实用标准文案精彩文档可实现功能:1可控制左右旋转2可控制停止转动3有测速功能,即时显示在液晶上4有速度档位选择,分五个档次,但不能精确控速5档位显示在液晶上用到的知识:1用外部中断检测电机送来的下降沿,在一定时间里统计脉冲个数,进行算出转速。2通过改变占空比可改变电机速度,占空比的改变可以通过改变定时器的重装初值来实现。3要想精确控制速度,还需要用自动控制理论里的PID算法,但参数难以选定,故在此设计中没有涉及!#include#defineucharunsignedchar#defineuintunsignedintsbitPW1=P1^0;sbitPW2=P1^1;//控制电机的两个输入sbitaccelerate=P0^2;//调速按键sbitstop=P0^3;//停止按键sbitleft=P0^4;//左转按键sbitright=P0^5;//右转按键实用标准文案精彩文档sbitdetect=P3^2;//检测脉冲sbitlcdrs=P0^0;sbitlcden=P0^1;#defineDaP2uinttemp;//保存检测到的电平数据以便比较uintcount;//用于计数uintaa,bb;//用于计数uintspeed;//用来计算转速uinta=25000;uintt0=25000,t1=25000;//初始时占空比为50%ucharflag=1;//此标志用于选择不同的装载初值uchardflag;//左右转标志ucharsflag=1;//用来标志速度档位#defineright_turnPW1=0;PW2=1//顺时针转动#defineleft_turnPW1=1;PW2=0//逆向转动#defineend_turnPW1=1;PW2=1//停转voidkeyscan();//键盘扫描voiddelay(ucharz);voidtime_init();//定时器的初始化voidwrite_com(ucharcom);//液晶写指令voidwrite_data(uchardate);//液晶写数据voidlcd_init();//液晶初始化voiddisplay(uintrate);//显赫速度voidint0_init();//定时器0初始化voidkeyscan();//键盘扫描程序voidjudge_derection();voidmain(){time_init();//定时器的初始化lcd_init();//液晶初始化int0_init();//定时器0初始化while(1){}}voidtime_init()实用标准文案精彩文档{TMOD=0x11;//两个定时器都设定为工作方式1十六位定时计数器EA=1;//开启总中断TH0=(65536-50000)/256;TL0=(65536-50000)%256;ET0=1;TR0=1;TH1=(65536-a)/256;TL1=(65536-a)%256;ET1=1;TR1=0;}voidint0_init(){EX0=1;//外部中断源可以申请中断IT0=1;//外部中断源下降沿触发}voidtimer0()interrupt1using0{TH0=(65536-50000)/256;TL0=(65536-50000)%256;//装载初值keyscan();//键盘扫描程序aa++;if(aa==5){aa=0;temp=count*0.5*60*2*2*100/24;//计算转速,每分转多少圈count=0;//重新开始计数脉冲数display(temp);//把计算得的结果显示出来}}voidtimer1()interrupt3using0{if(flag)实用标准文案精彩文档{flag=0;end_turn;a=t0;//t0的大小决定着低电平延续时间TH1=(65536-a)/256;TL1=(65536-a)%256;//重装载初值}else{flag=1;//这个标志起到交替输出高低电平的作用if(dflag==0){right_turn;//右转}else{left_turn;//左转}a=t1;//t1的大小决定着高电平延续时间TH1=(65536-a)/256;TL1=(65536-a)%256;//重装载初值}}/*******外部中断*******************/voidservice_int0()interrupt0{count++;//来一个下降沿沿就计一个脉冲数}/*******显示函数***********/voiddisplay(uintrate){ucharwan,qian,bai,shi,ge;wan=rate/10000;qian=rate/1000%10;bai=rate/100%10;shi=rate/10%10;实用标准文案精彩文档ge=rate%10;write_com(0x80);write_data('0'+wan);write_data('0'+qian);write_data('0'+bai);write_data('.');write_data('0'+shi);write_data('0'+ge);}/******延时函数********/voiddelay(uintz){uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/************写指令************/voidwrite_com(ucharcom){lcdrs=0;Da=com;delay(1);lcden=1;delay(1);lcden=0;}/************写数据**********/voidwrite_data(uchardate){lcdrs=1;Da=date;delay(1);lcden=1;delay(1);lcden=0;}/************液晶初始化**********/实用标准文案精彩文档voidlcd_init(){lcden=0;write_com(0x38);//初始化write_com(0x0c);//打开光标0x0c不显示光标0x0e光标不闪,0x0f光标闪write_com(0x01);//清显示write_com(0x80+0x40);write_data('0');write_data('');write_data('G');write_data('e');write_data('a');write_data('r');}/***********键盘扫描程序**********/voidkeyscan(){if(stop==0){TR1=0;//关闭定时器0即可停止转动end_turn;//停止供电write_com(0x80+0x40);write_data('0');}if(left==0){TR1=1;dflag=1;//转向标志置位则左转write_com(0x80+0x40);write_data('0'+sflag);}if(right==0){TR1=1;dflag=0;//转向标志复位则右转write_com(0x80+0x40);write_data('0'+sflag);}if(accelerate==0)实用标准文案精彩文档{delay(10);//延时消抖if(accelerate==0){while(accelerate==0);//等待松手sflag++;if(sflag==2){t0=20000;t1=30000;//占空比为百分之60write_com(0x80+0x40);write_data('2');}if(sflag==3){t0=15000;t1=35000;//占空比为百分之70write_com(0x80+0x40);write_data('3');}if(sflag==4){t0=10000;t1=40000;//占空比为百分之80write_com(0x80+0x40);write_data('4');}if(sflag==5){t0=5000;t1=45000;//占空比为百分之90write_com(0x80+0x40);write_data('5');}if(sflag>=6){sflag=0;t0=25000;t1=25000;write_com(0x80+0x40);write_data('1');}}实用标准文案精彩文档}}