C语言实现控制电机加减速正反转(飞思卡尔C代码)
C语言实现控制电机加减速正反转(飞思卡尔C代码)
C语言实现控制电机加减速正反转(飞思卡尔C代码)用单片机控制直流电动机的正反转、加减速的程序如何用C语言写参考一下这个例子吧。
#include#defineucharunignedchar#defineuintunignedintbitPW1=P2^0;bitPW2=P2^1;//控制电机的两个输入bitaccelerate=P2^2;//调速按键bittop=P2^3;//停止按键bitleft=P2^4;//左转按键bitright=P2^5;//右转按键#defineright_turnPW1=0;PW2=1//顺时针转动#defineleft_turnPW1=1;PW2=0//逆向转动#defineend_turnPW1=1;PW2=1//停转uintt0=25000,t1=25000;//初始时占空比为50%uinta=25000;//设置定时器装载初值25m设定频率为20Hzucharflag=1;//此标志用于选择不同的装载初值uchardflag;//左右转标志ucharcount;//用来标志速度档位voidkeycan();//键盘扫描voiddelay(ucharz);voidadjut_peed();//通过调整占空比来调整速度//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidmain(){keycan();//不断扫描键盘程序,以便及时作出相应的响应}}if(flag){flag=0;end_turn;a=t0;//t0的大小决定着低电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}ele{flag=1;//这个标志起到交替输出高低电平的作用if(dflag==0){right_turn;//右转}ele{left_turn;//左转}a=t1;//t1的大小决定着高电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}}TMOD=0某01;//工作方式寄存器软件起动定时器定时器功能方式1定时器0TH0=(65536-a)/256;TL0=(65536-a)%6;//装载初值ET0=1;//开启定时器中断使能EA=1;//开启总中断TR0=0;}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voiddelay(ucharz)//在12M下延时z毫秒{ uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidkeycan(){if(top==0){TR0=0;//关闭定时器0即可停止转动end_turn;} if(left==0){TR0=1;dflag=1;//转向标志置位则左转}if(right==0){TR0=1;dflag=0;//转向标志复位则右转}if(accelerate==0){delay(5);//延时消抖if(accelerate==0){ while(accelerate==0);//等待松手count++;if(count==1){t0=20000;t1=30000;//占空比为百分之60}if(count==2){t0=15000;t1=35000;//占空比为百分之70}if(count==3){t0=10000;t1=40000;//占空比为百分之80}if(count==4){t0=5000;t1=45000;//占空比为百分之90}if(count==5){count=0;}}}}功能特点:1)总线速度高达40MHz,CAN总线:3个1Mbp的CAN总线,兼容CAN2.0A/B;2)128KB程序Flah和8KBDataFlah,用于实现程序和数据存储,均带有错误校正码(ECC);3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μ的转换时间4)内嵌MSCAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;增强型捕捉定时器;6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能;7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。
c语言实现单片机控制步进电机加减速源程序
C 语言实现单片机控制步进电机加减速源程序1. 引言在现代工业控制系统中,步进电机作为一种常见的执行元件,广泛应用于各种自动化设备中。
而作为一种常见的嵌入式软件开发语言,C 语言在单片机控制步进电机的加减速过程中具有重要的作用。
本文将从单片机控制步进电机的加减速原理入手,结合 C 语言的编程技巧,介绍如何实现单片机控制步进电机的加减速源程序。
2. 单片机控制步进电机的加减速原理步进电机是一种能够精确控制角度的电机,它通过控制每个步骤的脉冲数来实现旋转。
在单片机控制步进电机的加减速过程中,需要考虑步进电机的加速阶段、匀速阶段和减速阶段。
在加速阶段,需要逐渐增加脉冲的频率,使步进电机的转速逐渐增加;在匀速阶段,需要保持恒定的脉冲频率,使步进电机以匀速旋转;在减速阶段,需要逐渐减小脉冲的频率,使步进电机的转速逐渐减小。
这一过程需要通过单片机的定时器和输出控制来实现。
3. C 语言实现步进电机加减速的源程序在 C 语言中,可以通过操作单片机的 GPIO 来控制步进电机的旋转。
在编写源程序时,需要使用单片机的定时器模块来生成脉冲信号,以控制步进电机的旋转角度和速度。
以下是一个简单的 C 语言源程序,用于实现步进电机的加减速控制:```c#include <reg52.h>void main() {// 初始化定时器// 设置脉冲频率,控制步进电机的加减速过程// 控制步进电机的方向// 控制步进电机的启停}```4. 总结与回顾通过本文的介绍,我们了解了单片机控制步进电机的加减速原理和 C 语言实现步进电机加减速源程序的基本思路。
掌握这些知识之后,我们可以更灵活地应用在实际的嵌入式系统开发中。
在实际项目中,我们还可以根据具体的步进电机型号和控制要求,进一步优化 C 语言源程序,实现更加精准和稳定的步进电机控制。
希望本文能为读者在单片机控制步进电机方面的学习和应用提供一定的帮助。
5. 个人观点与理解在我看来,掌握 C 语言实现单片机控制步进电机加减速源程序的技术是非常重要的。
无刷直流电机调速--C语言源程序
无刷直流电机调速--C语言源程序附录1. C语言源程序:#include"stdio.h"#include"myapp.h"#include"ICETEK-VC5502-EDU.h"#include"scancode.h"#include"lcd.h"#define CTRSTATUS (*(unsigned int * )0x608000) //port8000 #define CTRLED (*(unsigned int * )0x608004) //port8004#define MCTRKEY (*(unsigned int * )0x608005) //port8005 #define CTRCLKEY (*(unsigned int * )0x608006) //port8006 #define CTRMOTORBSPEED (*(unsigned int * )0x608003)void InitMcBSP();void INTR_init( void );void InitForMotorB( void );void showparameters();void LCDPutString(unsigned int * pData,int x,int y,unsigned int nCharNumber,unsigned color);void PIDControl(int rk,int yk);void PrintParameters();//定时器分频参数#define T100 99 // 100个时钟周期中断一次#define T2Hz 20000 // 20000个时钟周期读取速度一次//工作变量usigned int uWork,uN,nCount,nCount1,nCount2,nCount3,nCount4;int nSSS,nJSSpeed,pwm1;int md,wc;unsigned int nScreenBuffer[30*128];float a=0.6f,b=0.2f,c=0.1f,duk;int ek,ek1,ek2,tz;int nInput;unsigned int *www=(unsigned int *)0x608003;Int m_nSpeed,m_bPCSet;// 主函数main(){unsigned char ccc;int speed[100],sp,lj;float ljh;int i,w1,w2,w3;unsigned int uWork1;unsigned int bWork1,*pWork;int breakflage;// 初始化工作变量for ( sp=0;sp<100;sp++ )speed[sp]=0;for ( sp=0;sp<1024;sp++ ) nScreenBuffer[sp]=0;sp=nSSS=nCount=nCount1=nCount2=nCount3=nCount4= nJSSpeed=0;nInput=tz=wc =0;ek=ek1=ek2=0;uN=40;md=70;pwm1=60;m_nSpeed=70;m_bPCSet=0;inputspeed=0;uWork1=0;breakflage=0;initemif();CLK_init();*(int*)0x400001=1;CREG=1; //使能外部总线接口InitCTR();CTRGR=0x80;CTRGR=0;CTRGR=0x80;LCDTurnoff();// 设置显示参数和内容LCDSetDelay(1); //设置延时等待参数LCDSetScreenBuffer(nScreenBuffer); // 显示缓冲区for (bWork=0,pWork=nScreenBuffer;bWork<30*128;bWork++,pWork++) (*pWork=0)LCDTurnOn();//打开显示LCDCLS();//清除显示内存LCDPutCString(str1,0,127,8,0);LCDPutCString(str2,0,111,2,1);LCDPutCString(str3,68,111,2,1);LCDPutCString(str4,68,79,2,1);LCDPutCString(str5,68,95,2,1);LCDPutCString(str6,0,95,2,1);LCDPutCString(str7,0,79,3,1);ShowParamctors();//参数显示InitMcBSP();INTR-init();InitForMotorB();While(!breakflage){if(nCount==0) //读取键盘标志{uWork=MCTRKEY;CTRCLKEY=0;Switch(uWork1){Casc 128;if(inputspecd!=0){Md=inputspecd;Inputspecd=0;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1); LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();}break;case 64;breakflage=1;case 1;inputspeed=inputspeed+1break;case 2;inputspeed=inputspeed-1;break;case 4;inputspeed=inputspeed+10;break;case 8;inputspeed=inputspeed-10;break;}if(inputspeed>90){inputspeed=90;}if(inputspeed<0){inputspeed=0;}w1=inputspeed%1000/100;w2=inputspeed%100/10;w3=in putspeed%10; LCDPutString(numbers+w1*8,104,79,1,1);LCDPutString(numbers+w2*8,112,79,1,1);LCDPutString(numbers+w3*8,120,79,1,1);LCDRefreshScreen();}if(m-bPCSet){m-bPCSst=0;if (m-nSpeed>=0&&m-nSpeed<256){md=m-nSpeed;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1);LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();printparameters();}}if(nJSSpeed==0) //读取速度标志{LED=1;nJSSpeed=0;ccc=CTRMOTORBSPEED; //读取端口速度计数ccc=ccc&0xff;nSSS=ccc;if(nSSS>=0 && nSSS<400) //合法性检测{speed(sp)=Nssssp++;sp%=33;}if(sp==0) //读取实际速度{lj=0;ljh=0;for(i=0;i<33;i++){if(speed(i)>=0&&speed(i)<400){ljh+=speed(i);lj++;}}nCount3++;nCount3%=3;if(nCount3==2){PIDControl(md,wc); //调用PID算法控制程序uN=100-pwml; //利用占空比调整控制Showparameters(); //显示各参数到LCD }CloseCTR();exit(0);}//PID算法控制子程序void PIDControl(int rk,int yk){ek=rk-yk;duk=a*ek+b*ek1+c*ek2; //计算控制输出ek2=ek1; ek1=ek;tz=(int)duk;pwm1+=tz; //计算当前占空比if(pwml<0) pwml=0;else if(pwml>99) pwml=99;}void interrupt Timer(){uWork=PCR1; //pwml输出if(nCont1>u N){uWork=4; //根据占空比设置FSR状态}else{uWork&=0x0fffb;}PCR1=uWork;//设置中断控制寄存器void INTR-init(void){asm(“BSET INTM”);IVPD=0x01;IVPH=0x01;IERO=0x10;DBIERO=0x10;IFRO=0xffff;asm(“BCLR INTM”);}void InitForMotorB(void)ioport unsigned int *GPTCTL1-0;ioport unsigned int *GPTPRD1-0;ioport unsigned int *GPTGCTL1-0;*GPTCTL1-0=0;*GPTPRD1-0=0x1d8;*GPTGCTL1-0=0x3;}//显示参数到LCDvoid ShowParameters(){int w1,w2,w3;w1=md%1000/100;w2=md%100/10,w3=md%10; LCDPutString(numbers+w1*8,36,111,1,1); LCDPutString(numbers+w2*8,44,111,1,1); LCDPutString(numbers+w3*8,52,111,1,1);if (ek>=0){LCDPutString(numbers+88,36,95,1,1);w3=((int)ek)%100;}else{LCDPutString(numbers+96,36,95,1,1);w3=((int)(-ek))%100;}for (j=0;j<16;j++,k<<=1){if (color==2) mcolor=2;elsemcolor=(pData(1*8+i)&k)(1):(0);if(color==0) mcolor=1-mcolor;}LCDPutPixel(x+1*8+I,y-j,mcolor);}int wwss;void PrintParameters(){wwcc=wc-md;printf(“测速(%3d) 设置(%3d) 误差(%+4d) PID调整量(%+3d) 占空比(%3d%%)\n”,wc,md,wwcc,tz,pwm1);}。
控制电机的c语言程序
//水位5
if(shuiman==1&&sw5==0&&sw4==1&&sw3==1&&sw2==1&&sw1==1)//当唯一的闭合一个传感器单元:水位5时发生
{
P0=table[5];//显示水位深度:5
}
//水位4
if(shuiman==1&&sw5==1&&sw4==0&&sw3==1&&sw2==1&&sw1==1)//当唯一的闭合一个传感器单元:水位4时发生
#include<reg51.h>
//定义一个数组,使数码管显示的数字和数组元素的下标相等
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
sbit shuiman=P1^0;//水满
sbit sw5=P1^1;//水位5
{
P0=table[2];//显示水位深度:2
}
//水位低
if(shuiman==1&&sw5==1&&sw4==1&&sw3==1&&sw2==1&&sw1==0)//当唯一的闭合一个传感器单元:水位1时发生
{
dianji=0;//开电机
state=0;//电机工作指示灯打开
P0=table[1];//显示水位深度:1
}
//手工上水
if(shougong==0)//当按手工上水按钮时发生
{
dianji=0;//开电机
C语言程序-直流电机调速
C语言程序-直流电机调速(总5页)-CAL-FENGHAI.-(YICAI)-Company One1-CAL-本页仅作为文档封面,使用请直接删除#include<>#define uchar unsigned char#define uint unsigned int/* 端口定义*/sbit in1=P1^0;sbit in2=P1^1;sbit jian=P2^0;sbit jia=P2^1;sbit dir=P2^2;sbit run=P2^3;sbit inter_0=P3^2;sbit inter_1=P3^3;#define LCD_data P0 //数据口sbit LCD_RS = P2^7; //寄存器选择输入sbit LCD_RW = P2^6; //液晶读/写控制sbit LCD_EN = P2^5; //液晶使能控制sbit LCD_PSB = P2^4; //串/并方式控制uchar t10,t1,ce,cj,s1=0,pl=10;uchar zi[]={"电机转速:"};uchar num[3];uint nums=0,speed,k=1200;void delay_1ms(uchar x){uchar i,j;for(j=0;j<x;j++)for(i=0;i<110;i++);}/*******************************************************************/ /* *//*写指令数据到LCD *//*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/ /* *//*******************************************************************/ void write_cmd(uchar cmd){LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;P0 = cmd;delay_1ms(5);LCD_EN = 1;delay_1ms(5);LCD_EN = 0;}/*******************************************************************/ /* *//*写显示数据到LCD *//*RS=H,RW=L,E=高脉冲,D0-D7=数据。
基于C51单片机的直流电机PWM调速控制(包含原理图及C源代码)
基于C51单片机的直流电机PWM调速控制--SQ这是最近一阶段自己学习所获,现分享与大家。
这里采用A T89C52单片机做主控制芯片,实现两路直流电机的PWM调速控制,另外还可以实现转向、显示运行时间、显示档位等注:考虑小直流电机自身因素,调速范围仅设有四级电路原理图:C语言程序源代码:/******************** 硬件资源分配*********************/数码管:显示电机状态(启停、正反、速度)、运行时间、是否转弯按键:K4 启动/暂停K3 正反转/转弯允许K2 加速/左转/运行时间清零K1 减速/右转/停止定时器:T0 数码管动态显示,输出PWMT1 运行时间记录********************************************************//*******主程序文件PWM.c******/#include <reg52.h>#include "Afx.h"#include "Config.c"#define CIRCLE 5 //脉冲周期//按键定义uchar key,key_tmp=0, _key_tmp=0;//显示定义uchar LedState=0xF0; //LED显示标志,0xF0不显示,Ox00显示uchar code LED_code_d[4]={0xe0,0xd0,0xb0,0x70}; //分别选通1、2、3、4位uchar dispbuf[4]={0,0,0,0}; //待显示数组uchar dispbitcnt=0; //选通、显示的位uchar mstcnt=0;uchar Centi_s=0,Sec=0,Min=0; //分、秒、1%秒//程序运行状态标志bit MotState=0; //电机启停标志bit DirState=0; //方向标志0前,1后uchar State1=-1;uchar State2=-1;uchar State3=0;uchar State4=-1;uchar LSpeed=0;uchar RSpeed=0;//其他uint RunTime=0;uint RTime_cnt=0;uint LWidth;uint RWidth; //脉宽uint Widcnt=1;uint Dispcnt;//函数声明void key_scan(void);void DisBuf(void);void K4(void);void K3(void);void K2(void);void K1(void);void disp( uchar H, uchar n );void main(void){P1|=0xF0;EA=1;ET0=1;ET1=1;TMOD=0x11;TH0=0xFC;TL0=0x66; //T0,1ms定时初值TH1=0xDB;TL1=0xFF; //T1,10ms定时初值TR0=1;Widcnt=1;while(1){key_scan();switch(key){case 0x80: K1(); break;case 0x40: K2(); break;case 0x20: K3(); break;case 0x10: K4(); break;default:break;}key=0;DisBuf();LWidth=LSpeed;RWidth=RSpeed;}}//按键扫描**模拟触发器防抖void key_scan(void){key_tmp=(~P3)&0xf0;if(key_tmp&&!_key_tmp) //有键按下{key=(~P3)&0xf0;}_key_tmp=key_tmp ;}//按键功能处理/逻辑控制void K4(void){if(State4==-1){State4=1;TR1=1;dispbuf[3]=1;LedState=0x00; //打开LEDMotState=1; //打开电机LSpeed=1;RSpeed=1; //初速设为1}else if(State4==1){State4=0;TR1=0;MotState=0; //关闭电机}else if(State4==0){MotState=1;if(State3==0){State4=1;TR1=1;}else if(State3==1){LSpeed=2;RSpeed=2;}}}void K3(void){if(State4==1)DirState=!DirState;if(State4==0){if(State3==0){State3=1; //可以转向标志1可以,0不可以TR1=1;dispbuf[3]=9;MotState=1;LSpeed=2;RSpeed=2;}else if(State3==1){State3=0;TR1=0;dispbuf[3]=0;MotState=0;}}}void K2(void){if(State4==1&&LSpeed<4&&RSpeed<4){LSpeed++;RSpeed++;}else if(State4==0){if(State3==0){//State4=-1;//LedState=0xF0;MotState=0;Sec=0;Min=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=0;LSpeed=2;RSpeed++;}}}void K1(void){if(State4==1&&LSpeed>1&&RSpeed>1){LSpeed--;RSpeed--;}else if(State4==0){if(State3==0){State4=-1;LedState=0xF0;MotState=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=1;LSpeed++;RSpeed=2;}}}//显示预处理void DisBuf(void){if(RTime_cnt==100){Sec++;RTime_cnt=0;}if(Sec==60){Min++;Sec=0;}if(State4==1){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;if(!DirState) //正转dispbuf[3]=LSpeed;if(DirState) //反转dispbuf[3]=LSpeed+4;}if(State4==0){if(State3==0){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;dispbuf[3]=0;}if(State3==1){dispbuf[0]=RSpeed;dispbuf[1]=LSpeed;dispbuf[2]=Min;dispbuf[3]=9;}}}//LED驱动void disp( uchar H, uchar n ){P1=n;P1|=LedState ;P1|=LED_code_d[H];}//T0中断**显示/方波输出void Time_0() interrupt 1{TH0=0xFC;TL0=0x66;Widcnt++;Dispcnt++;//电机驱动/方波输出if(Widcnt>CIRCLE){Widcnt=1;}if(Widcnt<=LWidth)LMot_P=!DirState&&MotState;elseLMot_P=DirState&&MotState;LMot_M=DirState&&MotState;if(Widcnt<=RWidth)RMot_P=!DirState&&MotState;elseRMot_P=DirState&&MotState;RMot_M=DirState&&MotState;//显示if(Dispcnt==5){disp(dispbitcnt,dispbuf[dispbitcnt]);dispbitcnt++;if(dispbitcnt==4){dispbitcnt=0;}Dispcnt=0;}}//T1中断**运行时间void Time_1() interrupt 3{TH1=0xDB;TL1=0xFF;RTime_cnt++;}/******配置文件Afx.h******/#ifndef _AFX_#define _AFX_typedef unsigned char uchar;typedef unsigned int uint;typedef unsigned long ulong;#endif/******IO配置文件Config.c******/#ifndef _Config_#define _Config_#include "Afx.h"#include <reg52.h>//显示定义sbit led=P3^2;//电机引脚定义sbit LMot_P=P2^2; sbit LMot_M=P2^3; sbit RMot_P=P2^0; sbit RMot_M=P2^1;#endif。
AT80C52的PWM控制电机正转 反转 加速 减速
PWM调速电机正反转加速停止/********************************************************************* *本实验是基于普中科技的开发板设计直流电动机PWM调速实验。
*设计要求:k1控制电机正转,k2控制电机反转,k3控制电机加*速,k4控制电机减速,k5控制电机停止。
数码管显示电机转向,*速度和所转圈数。
并将速度发送到上位机。
实验所用电机为12V*自带增量式光电编码器。
外部中断0触发方式为高电平触发方式效果更好。
**********************************************************************/ #include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit BRA=P2^5; // 刹车sbit DIR=P2^6; // 转向sbit PWM=P2^7; // 调速sbit k1=P1^0; //正转sbit k2=P1^1; //反转sbit k3=P1^2; //加速sbit k4=P1^3; //减速sbit k5=P1^4; //停止sbit ls138a=P2^2;sbit ls138b=P2^3;sbit ls138c=P2^4;uchar flag; //方向标志位uchar speed=50; //初始转速uint quan_num; //圈数uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,// 0 1 2 3 40x6d,0x7d,0x07,0x7f,0x6f,0x40};// 5 6 7 8 9 -void delay(uint x){uchar i;while(x--){for(i=0;i<110;i++);}}/***************************************************************** 名称:init()* 功能:初始化函数,设置串口,定时器0,定时器1* 输入:无* 输出:无****************************************************************/void init(){SCON=0x50;//允许串接收发送TMOD=0x21;//定时器1工作在模式2,为串口提供波特率;定时器0工作在模式1,产生PWM波TH0=0xff; //定时100usTL0=0xa4;TH1=0xfd;//波特率为9600TL1=0xfd;IT0=1; //IT0=0低电平触发,IT0=1下降沿触发TR0=1; //开定时器0TR1=1; //开定时器1ET0=1; //开定时器0中断EA=1; //开总中断}/***************************************************************** 名称:display()* 功能:显示子函数,显示圈数,转速和转向* 输入:圈数,转速,转向* 输出:无****************************************************************/void display_sum(uint num) //圈数显示{P0=table[num%1000/100]; //显示圈数百位ls138a=1;ls138b=0;ls138c=1;delay(1);P0=table[num%100/10]; //显示圈数十位ls138a=0;ls138b=1;ls138c=1;delay(1);P0=table[num%10]; //显示圈数个位ls138a=1;ls138b=1;ls138c=1;delay(1);}void display_speed(uchar num) //转速显示{P0=table[num%100/10]; //显示转速十位ls138a=1;ls138b=1;ls138c=0;delay(1);P0=table[num%10]; //显示转速个位ls138a=0;ls138b=0;ls138c=1;delay(1);}void display_dir(uchar num) //方向显示{P0=table[num];ls138a=0;ls138b=1;ls138c=0;delay(1);}/**************************************************************** * 名称:dispose()* 功能:正反转加减速子函数* 输入:无* 输出:无****************************************************************/ void dispose() //按键处理{if(k5==0) //停止{EX0=0; //关外部中断0BRA=1; //刹车}if(k1==0) //正转{EX0=1; //开外部中断0BRA=0; //关刹车DIR=1; //电机正转PWM=1; //开电机flag=0; //电机正转标志}while(k1==0);if(k2==0) //反转{EX0=1; //开外部中断0BRA=0; //关刹车DIR=0; //电机反转PWM=1; //开电机flag=1; //电机反转标志}while(k2==0);if((k3==0)&&(speed<=90)) //加速{delay(100);if((k3==0)&&(speed<=90))EX0=1; //开外部中断0{speed=speed+10;}}while(k3==0);if((k4==0)&&(speed>=10)) //减速{delay(100); //延时去抖if((k4==0)&&(speed>=10))EX0=1; //开外部中断0{speed=speed-10;}if(speed==0)EX0=0; //如果速度为0,关外部中断0 }while(k4==0); //等待按键松开}void main(){init();PWM=0;P3=0xff;while(1){dispose(); //按键处理display_speed(speed); //显示速度display_sum(quan_num); //显示圈数display_dir(flag); //显示转向ES=0; //关串口SBUF=quan_num; //送圈数SBUF=speed; //送速度SBUF=flag; //送方向标志位ES=1; //开串口}}/**************************************************************** * 名称:timer0()* 功能:定时器0子函数,产生PWM波* 输入:无* 输出:无****************************************************************/ void timer0()interrupt 1 //PWM频率为1/(100us*100)=10k Hz{uchar count;TH0=0xff; //100usTL0=0xa4;if(count==speed){PWM=0; //关电}count++;if(count==100){count=0;if(speed!=0)//如果时间是0,保持原来状态PWM=1; //开电}}/**************************************************************** * 名称:int0()* 功能:外部中断0子函数* 输入:脉冲* 输出:电机旋转圈数****************************************************************/ void int0() interrupt 0{uint a;if(++a>=5120) //记每圈的脉冲数{a=0;quan_num++;if(quan_num>=999){quan_num=0;}}}/**************************************************************** * 名称:sever()* 功能:串口子函数* 输入:无* 输出:无****************************************************************/ void sever() interrupt 4 //串口中断{TI=0;}。
单片机控制双向可控硅调速电机c语言程序
单片机控制双向可控硅调速电机c语言程序下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!单片机控制双向可控硅调速电机C语言程序1. 引言随着现代工业的发展,电机控制技术在各个领域中起着至关重要的作用。
51单片机控制直流电机调速电路(含C语言源程序)
51单片机控制直流电机调速电路(含C语言源程序)在自动化控制中,许多场合需要单片机控制直流电机进行变速,这里我们介绍一种低成本的简单实现方法。
经实践证明,运行稳定可靠。
直流电机变速原理通过电机学知识,我们可知,直流电机的转速为:直流电机的变速主要有3种方式:1.控制电枢电压改变电机的转速。
2.控制电机的励磁电流改变电机的转速。
3.在电枢回路中,串联电阻改变电机的转速。
使用单片机控制直流电机的变速。
一般采用调节电枢电压的方式,如图1所示,单片机P36输出的为宽度可变的负脉冲,这样电机电枢上的电压也为宽度可变的脉冲电压,根据公式:U=aVCC其中:U-电机电枢电压。
a-脉冲的占空比,范围在0~1之间。
Vcc-直流电源电压,这里为12V。
电机的电枢电压即受单片机输出脉宽控制,实现了利用脉冲宽度调制技术(PWM)进行直流电机的变速。
直流电机变速的实例及编程图2为笔者设计的“电喷汽车喷油嘴清洗机”(一种保养汽车的设备)电路原理,根据需要,作业时可随时按下“压力+”、“压力-”键,控制直流电机M的转速,即改变了洗涤液输出的压力大小。
图3为PWM波的输出示意,为了叙述简单,我们把PWM波的周期定为1mS,占空比分10级可调(即每级级差为10%),这样定时器TO每01mS(即100μS)产生一次定时中断,每10次中断后进入下一个PWM波的周期。
图3中的脉冲占空比为60%,即输出脉冲的时间为600 μS,断开脉冲的时间为400 μS,这样电机的电枢电压为12*60%=72V。
该变速程序配合A189S51单片机,产生的PWM波载频为1KHz,电机运行时有一些声响,适用于一些对噪音不十分讲究的场合。
如将载频提升到10~15KHz以上时,则基本听不到噪音,由于A T89S51的运算速度有限,不可能实现这一目标。
这时我们可考虑使用高速8位单片机,如:C8051F020、A VR单片机等,它们不仅运行速度快,而且在片内集成了控制电机专用的PWM部件,用来对直流电机进行变速控制将会得心应手。
用C语言实现电机控制电路
用C语言实现电机控制电路作者:李依霖来源:《电子技术与软件工程》2016年第02期摘要在电机控制实验中,以前用开关和继电器来实现电机的正转、反转和停止动作。
现在我们采用计算机程序来控制对电机的各种动作,除了正转、反转和停止以外,还增加了定时器操纵和出入口锁定等动作。
从而增强了实验的效果。
我们将编辑好的程序置入电机驱动IC来实现电机控制电路。
【关键词】继电器电机驱动IC PIC各种电气、电子相关的实验中最常见的就是电机控制的实验。
过去我们使用的方法是利用开关和继电器来实现电机的正转、反转和停止动作。
现在我们可以利用计算机程序来实现各种电机电路的控制方法。
利用计算机程序进行电机控制电路情况下,首先考虑好电机控制电路时要实现的各种动作,然后按照指定动作,编译并调试程序,接着我们将调试成功的程序载入电机驱动IC芯片中,也就是现在广泛被使用的PIC微型机,最后我们将PIC微型机连接到电路中,确认电机的动作。
1 电机控制电路的构成在电路中不使用特殊的零件和材料,价格低且容易得到的材料进行设计和制作。
(1)模型用的小型电机。
(2)作为电路电源使用的电池。
(3)使用PIC16F84A作控制。
(4)使用TA7257P作为电动驱动IC。
(5)实验用的小型电路。
2 过去的电机控制电路方法过去控制电路最基本的方法用开关控制电路。
如图1(a)、(b)、(c)所示。
使用的开关是2级两投闸刀开关。
图1(a)中开关在中间位置,电机M没有电流流过处于停止状态。
图1(b)中电机M顺时针方向电流流动。
图1(c)中电机M逆时针方向电流流动。
开关的位置和电流的流向及电机的转动方向的变化相关。
3 新的设计方法控制电路我们采用新的设计是电机驱动IC方式。
这种方法不使用机械的继电器,电机驱动IC由PIC输入信号后控制电机旋转的电子方法。
如图2。
电机驱动IC的构造是将过去的继电器换成晶体管。
晶体管A、B、C、D由信号ON-OFF 控制工作。
电机驱动IC的输入端IN2,IN1从PIC中得到信号1或0,通过两输入端信号组合得到的运行状态如表1。
控制直流电机加减速
//加速处理
{
key_up_flag=0;
//清零加速标志位
high_time++; //高电平时间加1
if(high_time>=9) high_time=9; //控制 high_time,low_time 在1~9之间变化
low_time=10-high_time;
}Байду номын сангаас
if(key_down_flag==1)
while(!key_switch); //松手检测 key_switch_flag=1; //正反转标志位置"1" }
} }
/************************按键处理***************************/
void key_process()
{
if(key_up_flag==1)
//定义加速,减速,正反转标志位
/*********************ms 延时函数**********************/ void delay_ms(uint ms) {
uchar n; while(ms--) for(n=0;n<123;n++); }
/**********************按键扫描*************************/
//减速处理
{ key_down_flag=0;
//清零减速标志位
low_time++; //低电平时间加1
if(low_time>=9)
low_time=9;
high_time=10-low_time;
}
if(key_switch_flag==1) //正,反转处理
L298控制直流电机加减速的89c51单片机C程序
L298控制直流电机加减速的89c51单片机C程序#include<reg51.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit en1=P3^0; /* L298的Enable A */sbit s1=P3^2; /* L298的Input 1 */sbit s2=P3^3; /* L298的Input 2 */uchar t=0; /* 中断计数器*/uchar m1=0; /* 电机1速度值*/uchar tmp1; /* 电机当前速度值*//* 电机控制函数index-电机号(1,2); speed-电机速度(-100—100) */ void motor(uchar index, char speed){if(speed>=-100 && speed<=100){if(index==1) /* 电机1的处理*/{m1=abs(speed); /* 取速度的绝对值*/if(speed<0) /* 速度值为负则反转*/{s1=0;s2=1;}else /* 不为负数则正转*/{s1=1;s2=0;}}}}void delay(uint j) /* 简易延时函数*/{for(j;j>0;j--);}void main(){uchar i;TMOD=0x02; /* 设定T0的工作模式为2 */TH0=0x9B; /* 装入定时器的初值*/TL0=0x9B;EA=1; /* 开中断*/ET0=1; /* 定时器0允许中断*/TR0=1; /* 启动定时器0 */while(1) /* 电机实际控制演示*/{for(i=0;i<=100;i++) /* 正转加速*/{motor(1,i);delay(5000);}for(i=100;i>0;i--) /* 正转减速*/{motor(1,i);delay(5000);}for(i=0;i<=100;i++) /* 反转加速*/{motor(1,-i);delay(5000);}for(i=100;i>0;i--) /* 反转减速*/{motor(1,-i);delay(5000);}}}void timer0() interrupt 1 /* T0中断服务程序*/{if(t==0) /* 1个PWM周期完成后才会接受新数值*/{tmp1=m1;}if(t<tmp1) en1=1; else en1=0; /* 产生电机1的PWM信号*/ t++;if(t>=100) t=0; /* 1个PWM信号由100次中断产生*/}本程序实现串口对直流电机的控制******************************************************************/#include <REG2051.H>#include <stdio.h>#define uchar unsigned char#define uint unsigned int//****************************************************************//define a status world which sended back to computer#define COMMAND_STATUS 0#define STATUS_LEFT 1#define STATUS_RIGHT 2#define STATUS_SAFETYL 4#define STATUS_SAFETYR 8#define COMMAND_LEFT 1 //Turn left#define COMMAND_RIGHT 2 //Turn right#define COMMAND_STOP 3#define COMMAND_SPEED 4#define STOP 0#define LEFT 1#define RIGHT 2#define A_OUTPUT_ENABLE P3_4 //输出使能#define B_OUTPUT_ENABLE P3_5#define MotorA 1#define MotorB 2#define motorA_r P1_7#define motorA_l P1_6#define motorB_r P1_5#define motorB_l P1_4/****************************************************************************** *全局变量定义******************************************************************************* /uchar motor, command, cmddata; /* Used to receive commands with rs232 */uchar bytenr=0; /*Used to record how many byte we will receive*/ uchar Cycle=100;uchar directionA=0; /* current rotating direction */ uchar directionB=0;uchar PWidthA=50;uchar PWidthB=50;uint speedA=0; /* Default speed */uint speedB=0;uchar ticks=0; /* counter used for speed calculation */uchar serialtimeout=0; /* used when windows crashes ;-) *//****************************************************************************** *//funtion name:void Timer0_Int (void)////******************************************************************************* /void Timer0_Int (void) interrupt 1 using 1{serialtimeout++; // Ignore all received bytes after about 2 secondsif (!serialtimeout)bytenr=0;P3_7= ~P3_7; // invert P3.7, nice for debuggingticks++;if(ticks>=Cycle)ticks=0;if(ticks<=PWidthA)A_OUTPUT_ENABLE=0;elseA_OUTPUT_ENABLE=1;switch (directionA){case STOP:{motorA_r=0;motorA_l=0;A_OUTPUT_ENABLE=0; //NPN 三极管为省电}break;case LEFT:{motorA_r=0;motorA_l=1;}break;case RIGHT:{motorA_r=1;motorA_l=0;}break;}switch (directionB){case STOP:{motorB_r=0;motorB_l=0;B_OUTPUT_ENABLE=0;}break;case LEFT:{motorB_r=0;motorB_l=1;}break;case RIGHT:{motorB_r=1;motorB_r=0;}break;}TH0 = 0xFF; // Timing 10msTH0 = 0xF0; // reload basic count numberTR0 = 1; // Enable timer 0return;}//************************************************************************** ////////***************************************************************************/ void SendChar(uchar ch){SBUF=ch;while(TI==0); //等待发送完TI=0; //中断标志复位}//************************************************************************** //函数名:void Serial_INT_SVR//////***************************************************************************void Serial_INT_SVR (void) interrupt 4 using 3{if (RI) //Did we receive data?{serialtimeout=0; //reset Timeout Counter RI=0; //reset the interrupt flagswitch (bytenr){case 0: {motor=SBUF; //receive the first byteSendChar(motor);break;}case 1: {command=SBUF;SendChar(command);break;}case 2: {cmddata=SBUF;SendChar(cmddata);break;}}bytenr++;if (bytenr > 2){bytenr=0; //reset byte counter// motor should always be zero */if(motor==MotorA){switch (command) /* command handler */{case COMMAND_STOP:{directionA=0;break;}case COMMAND_LEFT:{ //turn leftdirectionA=1;break;}case COMMAND_RIGHT:{ //tu rn rightdirectionA=2;break;}case COMMAND_SPEED:{ //改变速度speedA=cmddata;if((speedA<=Cycle)&&(speedA>1)) //保证脉宽不会太窄{PWidthA=speedA;}break;}}}else if(motor==MotorB){switch (command) /* command handler */{case COMMAND_STOP:{directionB=0;break;}case COMMAND_LEFT:{ //turn leftdirectionB=1;break;}case COMMAND_RIGHT:{ //tu rn rightdirectionB=2;break;}case COMMAND_SPEED:{ //改变速度speedB=cmddata;if((speedB<=Cycle)&&(speedB>1)) //保证脉宽不会太窄{PWidthA=speedB;}break;}}}}}}/****************************************************************************** **serial initil******************************************************************************/ void Init_serialCOM(void){SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable RENTMOD |= 0x20 ; //TMOD: timer 1, mode 2, 8-bit reloadPCON |= 0x80 ; //SMOD=1; Baud*2TH1 = 0xF4 ; //Baud:4800 fosc=11.0592MHzTL1 =0xF4;EA=1 ; //Enable Serial InterruptES=1;TR1 = 1 ; // timer 1 run}/****************************************************************************** *seting timer0******************************************************************************* /void Set_Timer0(void){TMOD &= 0xf0; /* Set timer 0 */TMOD |= 0x01; /* set timer 0 as Gate=0 Timer, mode 1 */TH0 = 0xff; /* Timint 10ms */TL0 = 0x00;TR0 = 1; /* Enable timer 0 */ET0 = 1; /* Enable timer 0 interrupt */EA=1; /* Enable all enabled interrupts */}/****************************************************************************** *Main loop******************************************************************************* /void main (void){Init_serialCOM(); //serial initionSet_Timer0(); //int modeSendChar(PWidthA);SendChar(PWidthB); //A_OUTPUT_ENABLE=1;B_OUTPUT_ENABLE=1; //forbid outputwhile (1){; //here can add some user code }}大家来讨论下L298是怎么驱动直流电机的为什么我用单片机的I/O控制L298的IN1,IN2 ,ENA 直流减速电机不转动呢?而直接在上面加H/L电平却能控制呢?是不是L298又什么要求,我还不知道.......,不过我用仿真软件跑的很好~请高手帮忙诊断下,谢谢~程序如下:#include<reg51.h>sbit P1_1=P1^1;//ENA 左使能sbit P1_2=P1^2;//IN1sbit P1_3=P1^3;//IN2sbit P1_4=P1^4;//ENB 右使能sbit P1_5=P1^5; //IN3sbit P1_6=P1^6; //IN4sbit P2_0=P2^0; //前进sbit P2_1=P2^1; //后退sbit P2_2=P2^2; //左转sbit P2_3=P2^3; //右转#define ENA P1_1#define IN1 P1_2#define IN2 P1_3#define ENB P1_4#define IN3 P1_5#define IN4 P1_6unsigned int i,k=0;void int_tmer0 ();void forwoard();void backwoard();void left();void right();void stop();void init();void int_tmer0 () interrupt 1{ i++;TH0=0x3C;TL0=0xB0;if(i==100){i=0;switch(k++){ case 0: P2_0=1;forwoard();break;case 1:P2_0=0;P2_1=1;backwoard();break;case 2:P2_1=0;P2_2=1;left();break;case 3:P2_2=0;P2_3=1;right();break;case 4: P2_3=0;stop();P2=0x00;break; default:k=0;}}}void forwoard (){ init ();ENA=1;IN1=1;IN2=0;ENB=1;IN3=1;IN4=0;}void backwoard(){init();ENA=1;IN1=0;IN2=1;ENB=1;IN3=0;IN4=1;}void left(){init();ENA=1;IN1=1;IN2=0;ENB=1;IN3=0;IN4=1;}void right(){init();ENA=1;IN1=0;IN2=1;ENB=1;IN3=1;IN4=0;}void stop() {ENA=0;ENB=0;}void init (){P1=0x00;}main() {P2=0x00; TMOD=0x01;TH0=0x3C;TL0=0xB0;TR0=1;EA=1;ET0=1;for(;;);}。
直流电机调速程序c语言,以及电路
直流电机调速程序c语言,以及电路(实用版)目录1.直流电机调速程序概述2.C 语言编程基础3.直流电机调速电路设计4.直流电机调速程序的编写5.程序的实际应用与效果正文一、直流电机调速程序概述直流电机调速技术是一种广泛应用于工业自动化领域的技术,它能够实现直流电机的精确、平滑的速度控制。
其中,利用 C 语言编写直流电机调速程序,通过电路实现对直流电机速度的控制,具有操作简便、效果显著等优点。
二、C 语言编程基础C 语言是一种通用的、过程式的计算机程序设计语言,具有语法简洁、执行效率高、可移植性强等特点。
C 语言编程基础主要包括数据类型、运算符、控制结构、函数、数组等。
熟练掌握 C 语言编程基础,是编写直流电机调速程序的前提。
三、直流电机调速电路设计直流电机调速电路主要包括电源、电机、调速器等部分。
调速器是实现电机调速的核心部分,其主要功能是接收控制信号,将其转换为实际的电机驱动信号。
调速器的选型和电路设计对电机调速效果具有重要影响。
四、直流电机调速程序的编写在 C 语言编程环境下,编写直流电机调速程序主要包括以下几个步骤:1.定义变量和常量:定义与电机调速相关的变量和常量,如电机转速、电压等。
2.初始化:初始化相关硬件设备,如调速器、电机等。
3.获取控制信号:从操作面板或其他设备获取调速控制信号,如速度设定值等。
4.计算电机驱动信号:根据控制信号和电机参数,计算电机驱动信号,如电压、电流等。
5.输出电机驱动信号:将计算得到的电机驱动信号输出给调速器,实现对电机的速度控制。
6.程序循环:根据需要,实现程序的循环运行,以实时响应控制信号变化。
五、程序的实际应用与效果将编写好的直流电机调速程序下载到硬件设备中,可以实现对直流电机的精确、平滑的速度控制。
通过对程序的实际应用,可以验证其效果,如调速范围、调速精度等,从而进一步优化程序和电路设计,提高电机调速性能。
控制步进电机正反转的加减速程序程序
控制步进电机正反转的加减速程序程序#include#define KeyPort P1#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换sbit LATCH1=P2^4;//定义锁存使能端口段锁存sbit LATCH2=P0^0;// 位锁存unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量sbit A1=P2^0; //定义步进电机连接端口sbit B1=P2^1;sbit C1=P2^2;sbit D1=P2^3;#define Coil_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电#define Coil_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电#define Coil_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电#define Coil_DA1 {A1=1;B1=0;C1=0;D1=1;}//DA相通电,其他相断电#define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电#define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电#define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电#define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电#define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电unsigned char Speed=1;bit StopFlag;void Display(unsigned char FirstBit,unsigned char Num);void Init_Timer0(void);unsigned char KeyScan(void);/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下 T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/*------------------------------------------------主函数------------------------------------------------*/main(){unsigned int i=512;//旋转一周时间unsigned int n=0;unsigned char num,vo,v;Init_Timer0();Coil_OFF;while(1) //正向{num=KeyScan(); //循环调用按键扫描if(num==1)//第一个按键,速度等级增加{if(Speed<15)Speed=Speed+2;//+8}if(num==2)//第二个按键,速度等级减小{if(Speed>1)Speed=Speed-2;//-8}if(num==3)//第三个按键,电机停转{Coil_OFFStopFlag=1;}if(num==4)//第四个按键,电机启动{StopFlag=0;TR0=1;}if(num==5)//第五个按键,电机反转{TR0=0;TR1=1;}if(num==6)//第六个按键,电机正传{TR0=1;TR1=0;}vo=(0.25*(20-Speed)*64*32)/1000;v=60/vo;TempData[0]=dofly_DuanMa[v/10]; //分解显示信息,如要显示68,则68/10=6 68%10=8TempData[1]=dofly_DuanMa[v%10];}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用单片机控制直流电动机的正反转、加减速的程序如何用C语言写参考一下这个例子吧。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit PW1=P2^0 ;sbit PW2=P2^1 ; //控制电机的两个输入sbit accelerate=P2^2 ; //调速按键sbit stop=P2^3 ; //停止按键sbit left=P2^4 ; //左转按键sbit right=P2^5 ; //右转按键#define right_turn PW1=0;PW2=1 //顺时针转动#define left_turn PW1=1;PW2=0 //逆向转动#define end_turn PW1=1;PW2=1 //停转uint t0=25000,t1=25000; //初始时占空比为50%uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值uchar dflag; //左右转标志uchar count; //用来标志速度档位void keyscan(); //键盘扫描void delay(uchar z);void time_init(); //定时器的初始化void adjust_speed(); //通过调整占空比来调整速度//**********************************//void main(){time_init(); //定时器的初始化while(1){keyscan(); //不断扫描键盘程序,以便及时作出相应的响应}}//*************************************//void timer0() interrupt 1 using 0{if(flag){flag=0;end_turn;a=t0; //t0的大小决定着低电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%256; //重装载初值}else{flag=1; //这个标志起到交替输出高低电平的作用if(dflag==0){right_turn; //右转}else{left_turn; //左转}a=t1; //t1的大小决定着高电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%256; //重装载初值}}void time_init(){TMOD=0x01; //工作方式寄存器软件起动定时器定时器功能方式1 定时器0TH0=(65536-a)/256;TL0=(65536-a)%256; //装载初值ET0=1; //开启定时器中断使能EA=1; // 开启总中断TR0=0;}//****************************************//void delay(uchar z) //在12M下延时z毫秒{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//******************************//void keyscan(){if(stop==0){TR0=0; //关闭定时器0 即可停止转动 end_turn;}if(left==0){TR0=1;dflag=1; //转向标志置位则左转}if(right==0){TR0=1;dflag=0; //转向标志复位则右转}if(accelerate==0){delay(5) ; //延时消抖if(accelerate==0){while(accelerate==0) ; //等待松手count++;if(count==1){t0=20000;t1=30000; //占空比为百分之60}if(count==2){t0=15000;t1=35000; //占空比为百分之70}if(count==3){t0=10000;t1=40000; //占空比为百分之80}if(count==4){t0=5000;t1=45000; //占空比为百分之90}if(count==5){count=0;}}}}功能特点:1)总线速度高达40 M Hz,CAN总线:3个1Mbps的CAN总线,兼容CAN2.0 A/B;2)128 KB程序Flash和8 KB DataFlash,用于实现程序和数据存储,均带有错误校正码(E CC);3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μs的转换时间4)内嵌MS CAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;增强型捕捉定时器;6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能;7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。
8)存储器:128KB FLASH;2KB EEPROM;8KB RAM;9)串行口:2个异步串行通讯SCI和2个同步串行设备接口SPI;写在前面的话->:单片机要工作的话要具备一些基本条件,其中一条就是要有稳定的同步信号。
在飞思卡尔 S12 这款单片机中这个同步信号像其他单片机一样也是由外部晶振来提供的。
但与传统 51 单片机不同的是 S12 里面集成了 PLL (锁相环) 倍频电路,它可以把外部晶振的频率超到一定之后再提供给单片机,做为系统时钟。
并且这个 PLL 电路是可以软件编程的。
所以在对 S12 这款单片机进行软件编程时,首先就要配置系统的时钟。
假如没有配置好系统时钟的话就像人没有了心脏一样,接下来单片机具体在干什么事就只有它知道。
配置系统时钟的步骤如下:1、失能系统 PLL2、打开 PLL 电路3、计算频率要改变频率只要修改 SYNR、REFDV、POSTDIV 这三个寄存器的值即可。
具体怎么修改,改成多大可参考datasheet,MC9S12XS128RMV1.pdf 这个 PDF 文档(文档是英文的),里面有具体的公式。
以下给出常用的配置。
/*----------40M----------*/SYNR =0xc0 | 0x04; REFDV=0xc0 | 0x01; POSTDIV=0x00;/*----------48M----------*/SYNR =0xc0 | 0x05; REFDV=0xc0 | 0x01; POSTDIV=0x00;/*----------64M----------*/SYNR =0xc0 | 0x07; REFDV=0xc0 | 0x01; POSTDIV=0x00;4、等待 PLL 输出频率稳定5、使能系统 PLL实验的目的:学会 MC9S12XS128 这款单片机系统时钟的配置很 GPIO 的使用。
/********************************代码实现*************************************/#include <hidef.h> /* common defines and macros */#include <MC9S12XS128.h> /* derivative information */#pragma LINK_INFO DERIVATIVE "mc9s12xs128"/*--------函数原型声明-------------------------**/void SetBusCLK_48M(void);void DE_48M_ms(int ms);/*----------------------------------------------*//*--------主函数中 8路LED以200ms的间隔闪烁-------*/void main(void){byte i = 0;DisableInterrupts;SetBusCLK_48M();DDRB = 0XFF; //PB口设置为输出PORTB = 0XFF; //PB口初始化输出高电平for(;;){for(i=0;i<8;i++){PORTB &= ~(1<<i); //LED ONDE_48M_ms(200);PORTB |= (1<<i); //LED OFFDE_48M_ms(200);}}}/*-----------------配置系统时钟------------------*/void SetBusCLK_48M(void){CLKSEL = 0X00; //disengage PLL to systemPLLCTL_PLLON = 1; //turn on PLLSYNR = 0xc0 |0x05;REFDV = 0xc0 | 0x01;POSTDIV =0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;_asm(nop); //BUS CLOCK=48M_asm(nop);while(!(CRGFLG_LOCK == 1)); //when pll is steady ,then use it;CLKSEL_PLLSEL = 1; //engage PLL to system;}/*-----------------ms 级延时---------------------*/void DE_48M_ms(int ms){int ii,jj;if (ms<1) ms=1;for(ii=0;ii<ms;ii++)for(jj=0;jj<4006;jj++); //48MHz--1ms。