#include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit inl1=P2^0; //左電機輸出1 sbit inl2=P2^1; //左電機輸出2 sbit inr1=P2^2; //右電機輸出1 sbit inr2=P2^3; //右電機輸出2 sbit s_left=P2^4; //左傳感器 sbit s_right=P2^5; //右傳感器 sbit s_mid=P2^6; // 中間傳感器 sbit barrier=P2^7;//障礙物掃描傳感器 sbit beep=P1^0;//探到鐵報警接蜂鳴器 uint b_count=0;// 障礙物掃描位置基數 uchar alter_time=0;//報警計數值 uchar go_go=1;//小車前進中斷標志 sbit left_light=P1^2; sbit right_light=P1^1; uchar second=0; sbit P32=P3^2; uchar b_left,b_right; /****紅外遙控程勛數據****/ uchar irtime; uchar startflag; uchar irdata[33]; uchar irreceok; uchar irproseok; uchar dis[8]; uchar bitnum; uchar cd,flag,yaokong; uchar ircode[4]; uchar right=0,left=0,stop_stop=0,model=0; uchar kuai; void stop(void); void delay(uint a); void ir_key() //遙控鍵盤識別 { if(ircode[2]==0x51&&ircode[3]==0xAE&&flag==1) { yaokong=~yaokong; //打開遙控模式 flag=0; } if(ircode[2]==0x55&&ircode[3]==0xAA&&flag==1) //前進后退模式選擇 { model=~model; right=0; left=0; flag=0; } if(ircode[2]==0x56&&ircode[3]==0xA9&&flag==1) { //遙控前進標志位 stop_stop=~stop_stop; left=0; right=0; flag=0; } if(ircode[2]==0x17&&ircode[3]==0xE8&&flag==1) //遙控左拐標志位 { left=1; right=0; stop_stop=0; flag=0; } if(ircode[2]==0x16&&ircode[3]==0xE9&&flag==1) //遙控右轉標志位 { right=1; stop_stop=0; left=0; flag=0; } if(ircode[2]==0x11&&ircode[3]==0xEE&&flag==1) //遙控右轉標志位 { kuai=~kuai; flag=0; } } void timer1init() //定時器1初始化 { TMOD=0x21; TH1=0x00; TL1=0x00; ET1=1; TR1=1; } void int1init() //外部中斷1初始化 { IT1=1; EX1=1; EA=1; } void irpros(void) //紅外處理函數 { uchar k,j,i; uchar value; k=1; for(j=0;j<4;j++) { for(i=0;i<8;i++) { value=value>>1; if(irdata[k]>6) { value=value|0x80; } k++; } ircode[j]=value; } irproseok=1; } void irwork() //紅外解碼函數 { uchar i; dis[0]=ircode[0]/16; dis[1]=ircode[0]%16; dis[2]=ircode[1]/16; dis[3]=ircode[1]%16; dis[4]=ircode[2]/16; dis[5]=ircode[2]%16; dis[6]=ircode[3]/16; dis[7]=ircode[3]%16; for(i=0;i<8;i++) { if(dis[i]>9) { cd=dis[i]-9; dis[i]=0x10+cd; } } flag=1; } void inti() //初始化定時器0,中斷0 { P2=0xff; P0=0xff; P1=0xff; P3=0xff; EX0=1; IT0=1; TH0=(65536-50000)/256; TL0=(65536-50000)%256; ET0=1; TR0=0; } void delay(uint a) ////延時 1ms { int i; for (; a>0; a--) for(i=0; i<110; i++); } void go_along(void) //直走 { inl1=1; inl2=0; inr1=1; inr2=0; } void go_left(void) // 向左轉 { left_light=0; inl1=0; inl2=0; inr1=1; inr2=0; } void go_right(void) //向右轉 { right_light=0; inl1=1; inl2=0; inr1=0; inr2=0; } void go_back(void) //后退 { inl1=0; inl2=1; inr1=0; inr2=1; } void left_back(void) //左轉彎后退 { left_light=0; inl1=0; inl2=0; inr1=0; inr2=1; } void right_back(void) //右轉彎后退 { right_light=0; inl1=0; inl2=1; inr1=0; inr2=0; } void stop(void) //停止 { inl1=0; inl2=0; inr1=0; inr2=0; } void kill_stop(void) //殺停 { inl1=1; inl2=1; inr1=1; inr2=1; } /***************先掃描中間傳感器如不再黑線上剎停,掃描 左右兩個傳感器,如果左邊在黑線上,向右轉,如果右邊在黑 向上向左轉知道都在黑向上前進*******************/ void scan_sensor(void) //掃描前面傳感器 并前行 { if(s_mid==1) { kill_stop(); delay(3); stop(); delay(3); if (s_right==0) { go_right(); delay(7); } else if (s_left==0) { go_left(); delay(7); } else { stop(); delay(4); go_along(); delay(5); } } else{ kill_stop(); delay(3); stop(); delay(3); if(s_right==0) { go_right(); delay(6); } else if(s_left==0) { go_left(); delay(6); } else { go_along(); delay(6); } } } /**********如果遇見障礙物先向左轉到180度還有障礙物, 之后向右轉到沒有障礙物為止之后前進***************/ void bizhang() //避開障礙物函數 { if(barrier==0) { if(b_count<=100) { go_left(); delay(5); b_count++; } else{ left_back(); delay(10); } } else{ if(b_left==1) { go_left(); delay(50); b_left=0; } if(b_right==1) { left_back(); delay(50); b_right=0; } go_along(); delay(5); b_count=0; } } /****發現鐵片則停止三秒鐘****/ void fironalter() //發現鐵報警清楚函數 { if(second==3) { second=0; beep=1; go_along(); delay(300); EX0=1; go_go=1; } } main() { int1init(); timer1init(); inti(); while(1) { if(irreceok) { irpros(); irreceok=0; } if(irproseok) { irwork(); irproseok=0; } ir_key(); if(yaokong==0xff) //遙控模式 { if(kuai==0) { stop(); delay(5); } if(model==0) //前行模式 { if(go_go==1) { if(left==0xff) { stop(); delay(2); go_left(); delay(5); } else if(right==0xff) { stop(); delay(2); go_right(); delay(5); } else if(stop_stop==0xff) { stop(); delay(5); } else { go_along(); delay(5); } } else { stop(); delay(5); } } else //后退模式 { if(go_go==1) { if(left==0xff) { stop(); delay(2); left_back(); delay(5); } else if(right==0xff) { stop(); delay(2); right_back(); delay(5); } else if(stop_stop==0xff) { stop(); delay(5); } else { go_back(); delay(5); } } else { stop(); delay(5); } } left=0; right=0; } else //循跡模式 { if(go_go==1) { stop(); delay(5); if(s_right==0&&s_left==0&&s_mid==0) bizhang(); else scan_sensor(); } else { stop(); } } fironalter(); left_light=1; right_light=1; } } void int0() interrupt 0 { beep=0; kill_stop(); delay(10); alter_time=0; TR0=1; go_go=0; EX0=0; } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; alter_time++; if(alter_time==20) { alter_time=0; second++; } } void timer1() interrupt 3 { irtime++; } void int1() interrupt 2 { if(startflag) { if(irtime>32) { bitnum=0; } irdata[bitnum]=irtime; irtime=0; bitnum++; if(bitnum==33) { bitnum=0; irreceok=1; } } else { startflag=1; irtime=0; } }