您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 交通运输 > 基于51单片机的红外遥控智能小车源程序(C语言)
/*预处理命令*/#includereg52.h//包含单片机寄存器的头文件#includeintrins.h//包含_nop_()函数定义的头文件#defineucharunsignedchar#defineuintunsignedint#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};sbitIRIN=P3^2;//红外接收器数据线sbitLCD_RS=P0^7;sbitLCD_RW=P0^6;sbitLCD_EN=P0^5;ucharbegin[]={Mycar!};ucharcdis1[]={jiansu!};ucharcdis2[]={qianjin!};ucharcdis3[]={jiasu!};ucharcdis4[]={zuozhuang!};ucharcdis5[]={STOP!};ucharcdis6[]={youzhuan!};ucharcdis8[]={daoche!};sbitM1=P1^0;sbitM2=P1^1;sbitM3=P1^2;sbitM4=P1^3;sbitEN12=P1^4;sbitEN34=P1^5;ucharIRCOM[7];ucharm,n;uchart=2;ucharg;ucharcodedigit[]={0123456789};uintv;ucharcount;bitflag;voiddelayxms(uchart);voiddelay(unsignedcharx);voiddelay1(intms);voidmotor();voidlcd_display();/*检查LCD忙状态lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据*/bitlcd_busy(){bitresult;LCD_RS=0;LCD_RW=1;LCD_EN=1;delayNOP();result=(bit)(P0&0x80);LCD_EN=0;return(result);}/*写指令数据到LCDRS=L,RW=L,E=高脉冲,D0-D7=指令码*/voidlcd_wcmd(ucharcmd){while(lcd_busy());LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();P2=cmd;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}/*写显示数据到LCDRS=H,RW=L,E=高脉冲,D0-D7=数据*/voidlcd_wdat(uchardat){while(lcd_busy());LCD_RS=1;LCD_RW=0;LCD_EN=0;P2=dat;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}/*LCD初始化设定*/voidlcd_init(){delay1(15);lcd_wcmd(0x38);//16*2显示,5*7点阵,8位数据delay1(5);lcd_wcmd(0x38);delay1(5);lcd_wcmd(0x38);delay1(5);lcd_wcmd(0x0c);//显示开,关光标delay1(5);lcd_wcmd(0x06);//移动光标delay1(5);lcd_wcmd(0x01);//清除LCD的显示内容delay1(5);}/*设定显示位置*/voidlcd_pos(ucharpos){lcd_wcmd(pos|0x80);//数据指针=80+地址变量}/*x显示速度提示符*/voiddisplay_sym(void){lcd_pos(0x00);lcd_wdat('v');lcd_wdat('=');}/*显示速度数值*/voiddisplay_vel(uintx){uchari,j,k,l;i=x/1000;//取千位j=(x%1000)/100;//取百位k=(x%100)/10;//取十位l=x%10;//取个位lcd_pos(0x02);lcd_wdat(digit[i]);lcd_wdat(digit[j]);lcd_wdat(digit[k]);lcd_wdat(digit[l]);}/*显示速度单位*/voiddisplay_unit(void){lcd_pos(0x06);lcd_wdat('r');lcd_wdat('/');lcd_wdat('m');lcd_wdat('i');lcd_wdat('n');}/*主函数*//*******************************************************************/voidmain(){uinta;IRIN=1;//I/O口初始化IE=0x83;//允许总中断中断,使能INT0外部中断TCON=TCON|0x01;//触发方式为脉冲负边沿触发lcd_init();TMOD=0x51;TH0=(65536-50000)/256;TL0=(65536-50000)/256;TR0=1;count=0;display_sym();display_vel(0);display_unit();lcd_pos(0x40);g=0;while(begin[g]!='\0'){lcd_wdat(begin[g]);g++;}while(1){TR1=1;TH1=0;TL1=0;flag=0;display_sym();display_unit();while(flag==0);v=(TH1*256+TL1)*60/20;display_vel(v);motor();}}/**********************************************************/voidIR_IN()interrupt0using0{unsignedcharj,k,N=0;unsignedcharq=0;EX0=0;delay(15);if(IRIN==1){EX0=1;return;}//确认IR信号出现while(!IRIN)//等IR变为高电平,跳过9ms的前导低电平信号。delay(1);for(j=0;j4;j++)//收集四组数据{for(k=0;k8;k++)//每组数据有8位{while(IRIN)//等IR变为低电平,跳过4.5ms的前导高电平信号。{delay(1);}while(!IRIN)//等IR变为高电平delay(1);while(IRIN)//计算IR高电平时长{delay(1);N++;if(N=30){EX0=1;return;}//0.14ms计数过长自动离开。}//高电平计数完毕IRCOM[j]=IRCOM[j]1;//数据最高位补“0”if(N=8){IRCOM[j]=IRCOM[j]|0x80;//数据最高位补“1”}N=0;}}if(IRCOM[2]!=~IRCOM[3]){EX0=1;return;}IRCOM[5]=IRCOM[2]&0x0F;//取键码的低四位IRCOM[6]=IRCOM[2]4;//右移4次,高四位变为低四位if(IRCOM[5]9){IRCOM[5]=IRCOM[5]+0x37;}elseIRCOM[5]=IRCOM[5]+0x30;if(IRCOM[6]9){IRCOM[6]=IRCOM[6]+0x37;}elseIRCOM[6]=IRCOM[6]+0x30;q=(((IRCOM[6]&0x0f)4)+(IRCOM[5]&0x0f));switch(q)//判断按键键码值{case0x16:m=0;break;//串口发送0case0x03:m=1;t++;if(t=5)t=4;break;//串口发送01case0x18:m=2;n=2;break;//串口发送02case0x55:m=3;t--;if(t=0)t=0;break;//串口发送03case0x08:m=4;n=4;break;//串口发送04case0x13:m=5;n=5;break;//串口发送05case0x51:m=6;n=6;break;//串口发送06case0x42:m=7;break;//串口发送07case0x52:m=8;n=8;break;//串口发送08case0x41:m=9;break;//串口发送09default:break;}lcd_display();EX0=1;}/***************延时函数*****************************/voiddelay(unsignedcharx)//x*0.14MS{unsignedchari;while(x--){for(i=0;i13;i++){}}}voidlcd_display(){g=0;switch(m){case1:lcd_init();lcd_pos(0x40);while(cdis1[g]!='\0')//减速{lcd_wdat(cdis1[g]);g++;}break;case2:lcd_init();lcd_pos(0x40);//前进while(cdis2[g]!='\0'){lcd_wdat(cdis2[g]);g++;}break;case3:lcd_init();lcd_pos(0x40);//加速while(cdis3[g]!='\0'){lcd_wdat(cdis3[g]);g++;}break;case4:lcd_init();lcd_pos(0x40);//左转while(cdis4[g]!='\0'){lcd_wdat(cdis4[g]);g++;}break;case5:lcd_init();lcd_pos(0x40);//停车while(cdis5[g]!='\0'){lcd_wdat(cdis5[g]);g++;}break;case6:lcd_init();lcd_pos(0x40);//右转while(cdis6[g]!='\0'){lcd_wdat(cdis6[g]);g++;}break;case8:lcd_init();lcd_pos(0x40);//倒车while(cdis8[g]!='\0'){lcd_wdat(cdis8[g]);g++;}break;default:break;}}voidmotor(){EN12=1;EN34=1;switch(n){case2://前进M1=1;M2=0;M3=1;M4=0;/*delayxms(5-t);M1=0;M3=0;elayxms(t);*/break;case4://左转M1=0;M2=0;M3=1;M4=0;/*delayxms(5-t);M1=0;M3=0;layxms(t+1);*/break;case6://右转M1=1;M2=0;M3=0;M4=0;/*delayxms(5-t);M1=0;M3=0;layxms(t+1);*/break;case8://后退M1=0;M2=1;M3=0;M4=1;/*delayxms(5-t);M2=0;M4=0;layxms(t);*/break;case5:EN12=0;EN34=0;break;default:break;}}/*******************************************************函数功能:定时器T0的中断服务函数********************************************************/voidTime0(void)interrupt1using1//定时器T0的中断编号为1,使用第1组工作寄存器{count++;//T0每中断1次,count加1if(count==20)//若累计满20次,即计满1秒钟{flag=1;//计满1秒钟标志位置1count=0;//清0,重新统计中断次数}TH0=(65536-46083)
本文标题:基于51单片机的红外遥控智能小车源程序(C语言)
链接地址:https://www.777doc.com/doc-5647212 .html