基于51单片机的红外遥控智能小车源程序(C语言)(共7页).doc
-
资源ID:13859063
资源大小:37KB
全文页数:7页
- 资源格式: DOC
下载积分:20金币
快捷下载
![游客一键下载](/images/hot.gif)
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
基于51单片机的红外遥控智能小车源程序(C语言)(共7页).doc
精选优质文档-倾情为你奉上/*预处理命令*/#include<reg52.h> /包含单片机寄存器的头文件#include<intrins.h> /包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned int#define delayNOP(); _nop_();_nop_();_nop_();_nop_();sbit IRIN=P32; /红外接收器数据线sbit LCD_RS = P07; sbit LCD_RW = P06;sbit LCD_EN = P05;uchar begin="My car!"uchar cdis1="jiansu!"uchar cdis2="qianjin!"uchar cdis3="jiasu!"uchar cdis4="zuozhuang!"uchar cdis5="STOP!"uchar cdis6="youzhuan!"uchar cdis8="daoche!" sbit M1 = P10;sbit M2 = P11;sbit M3 = P12;sbit M4 = P13;sbit EN12 = P14;sbit EN34 = P15;uchar IRCOM7;uchar m,n;uchar t=2;uchar g;uchar code digit=""uint v;uchar count;bit flag;void delayxms(uchar t);void delay(unsigned char x) ;void delay1(int ms);void motor();void lcd_display();/*检查LCD忙状态lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据*/bit lcd_busy() bit result;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=指令码*/void lcd_wcmd(uchar cmd) 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=数据*/void lcd_wdat(uchar dat) while(lcd_busy(); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P2 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; /*LCD初始化设定*/void lcd_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);/*设定显示位置*/void lcd_pos(uchar pos) lcd_wcmd(pos | 0x80); /数据指针=80+地址变量/*x显示速度提示符*/void display_sym(void)lcd_pos(0x00);lcd_wdat('v');lcd_wdat('=');/*显示速度数值*/void display_vel(uint x)uchar i,j,k,l;i=x/1000; /取千位j=(x%1000)/100; /取百位k=(x%100)/10; /取十位l=x%10; /取个位lcd_pos(0x02);lcd_wdat(digiti);lcd_wdat(digitj);lcd_wdat(digitk);lcd_wdat(digitl);/*显示速度单位*/void display_unit(void)lcd_pos(0x06);lcd_wdat('r');lcd_wdat('/');lcd_wdat('m');lcd_wdat('i');lcd_wdat('n');/*主函数*/*/void main()uint a; 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(beging!='0') lcd_wdat(beging); 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(); /*/void IR_IN() interrupt 0 using 0unsigned char j,k,N=0;unsigned char q=0;EX0 = 0; delay(15);if (IRIN=1) EX0 =1;return; /确认IR信号出现while (!IRIN) /等IR变为高电平,跳过9ms的前导低电平信号。delay(1);for (j=0;j<4;j+) /收集四组数据 for (k=0;k<8;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计数过长自动离开。 /高电平计数完毕 IRCOMj=IRCOMj >> 1; /数据最高位补“0”if(N>=8)IRCOMj = IRCOMj | 0x80; /数据最高位补“1” N=0;if(IRCOM2!=IRCOM3) EX0=1;return; IRCOM5=IRCOM2 & 0x0F; /取键码的低四位IRCOM6=IRCOM2 >> 4; /右移4次,高四位变为低四位if(IRCOM5>9) IRCOM5=IRCOM5+0x37;elseIRCOM5=IRCOM5+0x30;if(IRCOM6>9) IRCOM6=IRCOM6+0x37;elseIRCOM6=IRCOM6+0x30;q= (IRCOM6&0x0f)<<4) + (IRCOM5&0x0f); switch(q) /判断按键键码值case 0x16:m=0;break; /串口发送0case 0x03:m=1;t+;if(t>=5)t=4;break; /串口发送01case 0x18:m=2;n=2;break; /串口发送02case 0x55:m=3;t-;if(t<=0)t=0;break; /串口发送03case 0x08:m=4;n=4;break; /串口发送04case 0x13:m=5;n=5;break; /串口发送05case 0x51:m=6;n=6;break; /串口发送06case 0x42:m=7;break; /串口发送07case 0x52:m=8;n=8;break; /串口发送08case 0x41:m=9;break; /串口发送09default :break; lcd_display(); EX0 = 1; /*延时函数*/void delay(unsigned char x) /x*0.14MSunsigned char i;while(x-)for (i = 0; i<13; i+) void lcd_display() g=0;switch(m) case 1: lcd_init(); lcd_pos(0x40); while(cdis1g!='0')/减速 lcd_wdat(cdis1g); g+; break;case 2: lcd_init(); lcd_pos(0x40); /前进 while(cdis2g!='0') lcd_wdat(cdis2g); g+; break; case 3: lcd_init(); lcd_pos(0x40); /加速 while(cdis3g!='0') lcd_wdat(cdis3g); g+; break;case 4: lcd_init(); lcd_pos(0x40); /左转 while(cdis4g!='0') lcd_wdat(cdis4g); g+; break;case 5: lcd_init(); lcd_pos(0x40); /停车 while(cdis5g!='0') lcd_wdat(cdis5g); g+; break;case 6: lcd_init(); lcd_pos(0x40); /右转 while(cdis6g!='0') lcd_wdat(cdis6g); g+; break;case 8: lcd_init(); lcd_pos(0x40); /倒车while(cdis8g!='0') lcd_wdat(cdis8g); g+;break;default :break; void motor() EN12=1; EN34=1; switch(n) case 2: /前进 M1=1; M2=0; M3=1; M4=0; /* delayxms(5-t); M1=0;M3=0; elayxms(t); */ break; case 4: /左转 M1=0; M2=0; M3=1; M4=0; /*delayxms(5-t); M1=0; M3=0; layxms(t+1); */ break; case 6: /右转 M1=1; M2=0; M3=0; M4=0; /*delayxms(5-t); M1=0; M3=0; layxms(t+1); */ break; case 8:/后退 M1=0; M2=1; M3=0; M4=1; /*delayxms(5-t); M2=0; M4=0; layxms(t); */ break; case 5: EN12=0; EN34=0; break;default :break; /*函数功能:定时器T0的中断服务函数*/void Time0(void ) interrupt 1 using 1 /定时器T0的中断编号为1,使用第1组工作寄存器 count+; /T0每中断1次,count加1 if(count=20) /若累计满20次,即计满1秒钟 flag=1; /计满1秒钟标志位置1 count=0; /清0,重新统计中断次数 TH0=(65536-46083)/256; /定时器T0高8位重新赋初值 TL0=(65536-46083)%256; /定时器T0低8位重新赋初值 void delay1(int ms)unsigned char y;while(ms-)for(y = 0; y<250; y+)_nop_();_nop_();_nop_();_nop_();/*void delayxms(uchar t) uint i; uchar j; for(j=t;j>0;j-) for(i=80;i>0;i-); /延时124*8+10=1002us专心-专注-专业