|
- #include<reg52.h>
- #include<stdio.h> //標準輸入輸出
- #include<intrins.h> //
- sbit left1=P1^0; //左邊1電機轉
- sbit right1=P1^1; //右邊1電機轉
- sbit left2=P1^6; //左邊2電機轉
- sbit right2=P1^7; //右邊2電機轉
- sbit cleft0=P1^2; //左邊第一號紅外檢測
- sbit cleft1=P1^3; //左邊第二號紅外檢測
- sbit cright0=P1^4; //右邊第一號紅外檢測
- sbit cright1=P1^5; //右邊第二號紅外檢測
- sbit key=P3^2; //外部按鍵
- sbit rs=P0^5; //數據/命令控制位
- sbit rw=P0^6; //讀寫控制位
- sbit enable=P0^7; //使能控制位
- sbit xl=P3^0; //尋線左紅外
- sbit xr=P3^1; //尋線右紅外
- sbit TX =P3^6; //超聲波信號發送端
- sbit RX =P3^7; //超聲波信號接收端
- #define date P2 //用于LCD數據輸出
- char data test1[]=" "; //第一行顯示table
- char data test2[]=" "; //第二行顯示table
- unsigned char wflag; //工作位標志,包括避障,尋線,超聲波探測
- unsigned long S; //超聲波測試距離
- unsigned int time; //超聲波高電平時間
- unsigned char qian,bai,shi,ge; //千百十個位
- void delay(int i) //不精確延時
- {
- while(i--);
- }
- unsigned char test() //小車正向避障監測子程序
- {
- unsigned char k;
- if((cleft0&&cleft1&&cright0&&cright1)==1)
- {
- k=1; //小車前面完全沒有障礙物標志為1
- }
- if((cleft0&&cleft1)==0)
- {
- k=2; //左邊有障礙物時標志為2
- }
- if((cright0&&cright1)==1)
- {
- k=3; //右邊有障礙物時標志為3
- }
- return k;
- }
- unsigned char test3() //尋線紅外檢測子程序
- {
- unsigned char p;
- if((xl&&xr)==1)
- {
- p=1; //此標志顯示小車可向前移動
- }
- if((xl=1)&&(xr=0))
- {
- p=2; //小車右邊碰到黑線,小車需糾正位置
- }
- if((xl=0)&&(xr=1))
- {
- p=3; //小車左邊碰到黑線,小車需要糾正位置
- }
- if((xl=0)&&(xr=0))
- {
- p=4; //小車全部碰到黑線,倒車
- }
- return p;
- }
- void zhengxiang() //正向
- {
- delay(500);
- right1=1;
- right2=0;
- left1=1;
- left2=0;
- delay(500); //全部置零 停止小車,減速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void youxiang() //右向
- {
- delay(500);
- right1=0;
- right2=0;
- left1=1;
- left2=0;
- delay(500); //全部置零 停止小車,減速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void zuoxiang() //左向
- {
- delay(500);
- right1=1;
- right2=0;
- left1=0;
- left2=0;
- delay(500); //全部置零 停止小車,減速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void daoche() //倒車
- {
- delay(500);
- right1=0;
- right2=1;
- left1=0;
- left2=1;
- delay(500); //全部置零 停止小車,減速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
-
- void bizhang() //避障子程序
- {
- unsigned char flag; //障礙標志位
- test(); //運行監測
- flag=test();
- if(flag==1) //判斷處理
- {
- zhengxiang();
- }
- if(flag==2)
- {
- zuoxiang();
- }
- if(flag==3)
- {
- youxiang();
- }
- }
- void xunxian()
- {
- unsigned char flag;
- test3();
- flag=test3();
- if(flag==1)
- {
- zhengxiang();
- }
- if(flag==2)
- {
- zuoxiang();
- }
- if(flag==3)
- {
- youxiang();
- }
- if(flag==4)
- {
- daoche();
- }
- }
- void delayms(int x) //粗略的MS延時
- {
- while(x--)
- {
- delay(500); //調用US延時
- delay(500);
- delay(500);
- }
- }
-
- void write_com(unsigned char c) //LCD液晶寫命令
- {
- delayms(5); //這一部分請參考1602C型號的LCD使用手冊
- enable=0;
- rs=0;
- rw=0;
- _nop_();
- _nop_();
- enable=1;
- _nop_();
- date=c;
- _nop_();
- enable=0;
- }
- void write_date(unsigned char s) //LCD寫數據命令
- {
- delayms(5); //這一部分請參考1602C型號的LCD使用手冊
- enable=0;
- rs=1;
- rw=0;
- _nop_();
- enable=1;
- _nop_();
- date=s;
- _nop_();
- enable=0;
- }
- void init() //LCD初始指令
- {
- delayms(15);
- write_com(0x38); //0XXX為命令指令,請參考1602C型號LCD的使用手冊
- write_com(0x38);
- write_com(0x38);
- write_com(0x0f);
- write_com(0x06);
- write_com(0x01); //顯示清屏
- write_com(0x80); //數據起始書寫地址
- }
-
- void showjie(unsigned char pos,unsigned char c) //寫入一個字節的數據
- {
- unsigned char p;
- if(pos>=0x10)
- p=pos+0xb0;
- else
- p=pos+0x80;
- write_com(p);
- write_date(c);
- }
- void showchuan(unsigned char line,char *ptr) //寫入一個字符串的數據并包含行數
- {
- unsigned char l,o;
- l=line<<4;
- for (o=0;o<16;o++)
- showjie(l++,*(ptr+o));
- }
- void sent() //定義一個發送
- {
- TX=1; //發送端發送信號
- delay(25); //給一個大于10US的信號
- TX=0; //關閉發送端信號
- }
- void Count()
- {
- time=TH0*256+TL0; //計算時間
- TH0=0; //復位
- TL0=0; //復位
- S=(time*1.7)/10; //計算距離,單位MM
- if(S<5000)
- {
- qian=S/1000; //定義第四位
- bai=S/100%10; //定義第三位
- shi=S/10%10; //定義第二位
- ge=S%10; //定義第一位
- test2[5]=(qian+48);
- test2[6]=(bai+48);
- test2[7]=(shi+48);
- test2[8]=(ge+48);
- showchuan(1,test2);
- }
- }
- void receive() //定義一個接收
- {
- TR0=1; //定時器0開
- while(RX); //持續延時RX為高電平的時間
- TR0=0; //定時器0關
- Count(); //調用Count
- }
- void welcome() //起始LCD歡迎詞
- {
- delayms(20);
- init(); //初始化LCD
- delayms(20);
- sprintf(test1,"welcome to robot"); //調用sprintf
- showchuan(0,test1); //using showchuan
- sprintf(test2," by jack "); //using sprintf
- showchuan(1,test2); //using showchuan
- while(1);
- }
- void chaoshengbo() //超聲波子程序
- {
- int lv;
- delayms(20);
- init();
- delayms(20);
- sprintf(test1,"the distance is ");
- showchuan(0,test1);
- for(lv=1000;lv>0;lv--)
- {
- RX=1; //給RX一個高電平
- sent(); //給發送端一個>10us的信號
- if(RX==1)
- {
- receive(); //調用RECEIVE
- }
- }
- }
- void main()
- {
- EA=1; //中斷打開
- EX0=1; //外部中斷打開
- IT0=0; //外部中斷低電平有效
- ET0=1; //定時器中斷0開
- ET1=1; //定時器中斷1開
- TMOD=0X11; //定義TO,T1由TCON控制,工作方式為方式1
- TH0=0;
- TL0=0;
- TH1=0;
- TL1=0;
- while(wflag==0) //LCD歡迎界面
- {
- welcom();
- }
- while(wflag==1) //避障模式
- {
- bizhang();
- }
- while(wflag==2) //尋線模式
- {
- xunxian();
- }
- while(wflag==3)
- {
- chaoshengbo();
- }
-
- }
- void ISR_KEY(void) interrupt 1 using 1 //外部中斷函數 控制工作標志位的改變 切換工作狀態
- {
- delay(500);
- if(!key)
- {
- wflag++;
- if(wflag==4)
- wflag=0;
- }
- }
-
- //到這里就寫完啦···整體的硬件還沒做出來,但是分開的我都做過一次了,程序都沒問題···哈哈,整體作出來后再測試吧,哈哈···
復制代碼
|
|