/*預(yù)處理命令*/
#include<reg52.h> //包含單片機(jī)寄存器的頭文件 #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件 #define uchar unsigned char #define uint unsigned int #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; sbit IRIN=P3^2; //紅外接收器數(shù)據(jù)線 sbit LCD_RS = P0^7; sbit LCD_RW = P0^6; sbit LCD_EN = P0^5; 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 = P1^0; sbit M2 = P1^1; sbit M3 = P1^2; sbit M4 = P1^3; sbit EN12 = P1^4; sbit EN34 = P1^5; uchar IRCOM[7]; uchar m,n; uchar t=2; uchar g; uchar code digit[]={"0123456789"}; 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忙狀態(tài) lcd_busy為1時(shí),忙,等待。lcd-busy為0時(shí),閑,可寫指令與數(shù)據(jù) */ bit lcd_busy() { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN = 0; return(result); } /* 寫指令數(shù)據(jù)到LCD RS=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; } /* 寫顯示數(shù)據(jù)到LCD RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù) */ 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初始化設(shè)定 */ void lcd_init() { delay1(15); lcd_wcmd(0x38); //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù) delay1(5); lcd_wcmd(0x38); delay1(5); lcd_wcmd(0x38); delay1(5); lcd_wcmd(0x0c); //顯示開,關(guān)光標(biāo) delay1(5); lcd_wcmd(0x06); //移動(dòng)光標(biāo) delay1(5); lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容 delay1(5); } /* 設(shè)定顯示位置 */ void lcd_pos(uchar pos) { lcd_wcmd(pos | 0x80); //數(shù)據(jù)指針=80+地址變量 } /*x顯示速度提示符*/ void display_sym(void) { lcd_pos(0x00); lcd_wdat('v'); lcd_wdat('='); } /*顯示速度數(shù)值*/ void display_vel(uint x) { uchar i,j,k,l; i=x/1000; //取千位 j=(x%1000)/100; //取百位 k=(x%100)/10; //取十位 l=x%10; //取個(gè)位 lcd_pos(0x02); lcd_wdat(digit); lcd_wdat(digit[j]); lcd_wdat(digit[k]); lcd_wdat(digit[l]); } /*顯示速度單位*/ void display_unit(void) { lcd_pos(0x06); lcd_wdat('r'); lcd_wdat('/'); lcd_wdat('m'); lcd_wdat('i'); lcd_wdat('n'); } /* 主函數(shù) */ /*******************************************************************/ void main() { uint a; IRIN=1; //I/O口初始化 IE=0x83; //允許總中斷中斷,使能 INT0 外部中斷 TCON=TCON|0x01; //觸發(fā)方式為脈沖負(fù)邊沿觸發(fā) 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(); } } /**********************************************************/ void IR_IN() interrupt 0 using 0 { unsigned char j,k,N=0; unsigned char q=0; EX0 = 0; delay(15); if (IRIN==1) { EX0 =1; return; } //確認(rèn)IR信號(hào)出現(xiàn) while (!IRIN) //等IR變?yōu)楦唠娖,跳過9ms的前導(dǎo)低電平信號(hào)。 delay(1); for (j=0;j<4;j++) //收集四組數(shù)據(jù) { for (k=0;k<8;k++) //每組數(shù)據(jù)有8位 { while (IRIN) //等 IR 變?yōu)榈碗娖,跳過4.5ms的前導(dǎo)高電平信號(hào)。 {delay(1);} while (!IRIN) //等 IR 變?yōu)楦唠娖?/font> delay(1); while (IRIN) //計(jì)算IR高電平時(shí)長(zhǎng) { delay(1); N++; if (N>=30) { EX0=1; return; } //0.14ms計(jì)數(shù)過長(zhǎng)自動(dòng)離開。 } //高電平計(jì)數(shù)完畢 IRCOM[j]=IRCOM[j] >> 1; //數(shù)據(jù)最高位補(bǔ)“0” if(N>=8) { IRCOM[j] = IRCOM[j] | 0x80; //數(shù)據(jù)最高位補(bǔ)“1” } N=0; } } if(IRCOM[2]!=~IRCOM[3]) { EX0=1; return; } IRCOM[5]=IRCOM[2] & 0x0F; //取鍵碼的低四位 IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位變?yōu)榈退奈?/font> if(IRCOM[5]>9) { IRCOM[5]=IRCOM[5]+0x37; } else IRCOM[5]=IRCOM[5]+0x30; if(IRCOM[6]>9) { IRCOM[6]=IRCOM[6]+0x37; } else IRCOM[6]=IRCOM[6]+0x30; q= (((IRCOM[6]&0x0f)<<4) + (IRCOM[5]&0x0f)); switch(q) //判斷按鍵鍵碼值 { case 0x16:m=0;break; //串口發(fā)送0 case 0x03:m=1;t++;if(t>=5)t=4;break; //串口發(fā)送01 case 0x18:m=2;n=2;break; //串口發(fā)送02 case 0x55:m=3;t--;if(t<=0)t=0;break; //串口發(fā)送03 case 0x08:m=4;n=4;break; //串口發(fā)送04 case 0x13:m=5;n=5;break; //串口發(fā)送05 case 0x51:m=6;n=6;break; //串口發(fā)送06 case 0x42:m=7;break; //串口發(fā)送07 case 0x52:m=8;n=8;break; //串口發(fā)送08 case 0x41:m=9;break; //串口發(fā)送09 default :break; } lcd_display(); EX0 = 1; } /***************延時(shí)函數(shù)*****************************/ void delay(unsigned char x) //x*0.14MS { unsigned 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(cdis1[g]!='\0') //減速 { lcd_wdat(cdis1[g]); g++; }break; case 2: lcd_init(); lcd_pos(0x40); //前進(jìn) while(cdis2[g]!='\0') { lcd_wdat(cdis2[g]); g++; }break; case 3: lcd_init(); lcd_pos(0x40); //加速 while(cdis3[g]!='\0') { lcd_wdat(cdis3[g]); g++; }break; case 4: lcd_init(); lcd_pos(0x40); //左轉(zhuǎn) while(cdis4[g]!='\0') { lcd_wdat(cdis4[g]); g++; }break; case 5: lcd_init(); lcd_pos(0x40); //停車 while(cdis5[g]!='\0') { lcd_wdat(cdis5[g]); g++; }break; case 6: lcd_init(); lcd_pos(0x40); //右轉(zhuǎn) while(cdis6[g]!='\0') { lcd_wdat(cdis6[g]); g++; } break; case 8: lcd_init(); lcd_pos(0x40); //倒車 while(cdis8[g]!='\0') { lcd_wdat(cdis8[g]); g++; }break; default :break; }} void motor() { EN12=1; EN34=1; switch( n) { case 2: //前進(jìn) M1=1; M2=0; M3=1; M4=0; /* delayxms(5-t); M1=0; M3=0; elayxms(t); */ break; case 4: //左轉(zhuǎn) M1=0; M2=0; M3=1; M4=0; /*delayxms(5-t); M1=0; M3=0; layxms(t+1); */ break; case 6: //右轉(zhuǎn) 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; } } /******************************************************* 函數(shù)功能:定時(shí)器T0的中斷服務(wù)函數(shù) ********************************************************/ void Time0(void ) interrupt 1 using 1 //定時(shí)器T0的中斷編號(hào)為1,使用第1組工作寄存器 { count++; //T0每中斷1次,count加1 if(count==20) //若累計(jì)滿20次,即計(jì)滿1秒鐘 { flag=1; //計(jì)滿1秒鐘標(biāo)志位置1 count=0; //清0,重新統(tǒng)計(jì)中斷次數(shù) } TH0=(65536-46083)/256; //定時(shí)器T0高8位重新賦初值 TL0=(65536-46083)%256; //定時(shí)器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--); //延時(shí)124*8+10=1002us }
|