自動避障紅外電動小車C51程序
單片機源程序如下:
- #include"reg51.h"
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define left_infrare 0
- #define right_infrare 1
- #define dj_state1 0X5F //前進
- #define dj_state2 0X4F //右轉
- #define dj_state3 0X1F //左轉
- #define dj_state4 0X0F //后退
- #define dj_state5 0XfF //停車
- #define light_off 0x0f //關轉向燈
- #define left_light 0X5F //左轉向燈 兩個是5f
- #define right_light 0XaF //右轉向燈0xaf,兩個是0xbf
- #define back_light 0XcF //剎車燈即后燈
- #define front_light 0x3f //前燈
- #define light_on 0xff //開所有燈
- #define true 1
- #define false 0
- #define LCD_Data P0
- #define Busy 0x80 //用于檢測LCD狀態字中的Busy標識
- sbit c=P1^2; //轉向燈使能端
- uchar code talk1[]={"backward"};
- uchar code talk2[]={"forward"};
- uchar code talk3[]={"Turnleft"};
- uchar code talk4[]={"Turn right"};
- uchar flage =0x00;
- sbit ledcs=P1^2; //74H573的片選信號
- //sbit left_led=P0^2; //左紅外發射管
- //sbit right_led=P0^3; //右紅外發射管
- sbit LCD_RS = P1^5; //LCD定義引腳
- sbit LCD_RW = P1^6; //
- sbit LCD_E = P1^7 ;
- void Delay5Ms(void)
- {
- uint TempCyc = 5552;
- while(TempCyc--);
- }
- //400ms延時
- void Delay400Ms(void)
- {uchar TempCycA = 5;
- uint TempCycB;
- while(TempCycA--)
- { TempCycB=7269;
- while(TempCycB--);
- }
- }
- //LCD讀狀態
- unsigned char ReadStatusLCD(void)
- {
- LCD_Data = 0xFF;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_E = 0;
- LCD_E = 0;
- LCD_E = 1;
- while (LCD_Data & Busy); //檢測忙信號
- return(LCD_Data);
- }
- //LCD寫數據
- void WriteDataLCD(unsigned char WDLCD )
- {
- ReadStatusLCD(); //檢測忙
- LCD_Data = WDLCD;
- LCD_RS=1;
- LCD_RW =0;
- LCD_E = 0; //若晶振速度太高可以在這后加小的延時
- LCD_E = 0; //延時 ,為了安全
- LCD_E = 0; //延時
- LCD_E = 1;
- }
- //LCD寫指令
- void WriteCommandLCD(unsigned char WCLCD,BuysC)
- {
- if (BuysC) ReadStatusLCD(); //根據需要檢測忙,BuysC為0時忽略忙檢測
- LCD_Data = WCLCD;
- LCD_RS= 0;
- LCD_RW= 0;
- LCD_E = 0; //延時 ,為了安全
- LCD_E = 0;
- LCD_E = 0; //延時
- LCD_E = 1;
- }
- void LCDInit(void) //LCD初始化
- {
- Delay400Ms();
- LCD_Data = 0;
- WriteCommandLCD(0x38,0); //三次顯示模式設置,不檢測忙信號
- Delay5Ms();
- WriteCommandLCD(0x38,0);
- Delay5Ms();
- WriteCommandLCD(0x38,0);
- Delay5Ms();
- WriteCommandLCD(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
- WriteCommandLCD(0x08,1); //關閉顯示
- WriteCommandLCD(0x01,1); //顯示清屏
- WriteCommandLCD(0x06,1); // 顯示光標移動設置
- WriteCommandLCD(0x0C,1); // 顯示開及光標設置
- }
- //按指定位置顯示一個字符
- void DisplayOneChar(uchar X, uchar Y, uchar DData)
- {
- Y &= 0x1;
- X &= 0xF; //限制X不能大于15,Y不能大于1
- if (Y)
- X |= 0x40; //當要顯示第二行時地址碼+0x40;
- X |= 0x80; // 算出LCD的指令碼
- WriteCommandLCD(X, 0); //這里不檢測忙信號,發送地址碼
- WriteDataLCD(DData);
- }
- //按指定位置顯示一串字符(只能寫一行);
- void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n)
- { uchar i;
- Y &= 0x01;
- X &= 0x0F; //限制X不能大于15,Y不能大于1
- for(i=0;i<ListLength;i++)
- { if (X <= 0x0F) //X坐標應小于0xF
- { DisplayOneChar(X, Y, DData[i]); //顯示單個字符
- if(n==true)Delay400Ms();
- X++;
- }
- }
- }
- /****************************
- 紅外線接收子程序,利用了中斷的下降沿觸發方式
- ****************************/
- void infrared_ray()interrupt 0 using 3
- { uchar i=90;
- flage=0x01; //接受標志位
- while(i--); //減小靈敏度
- EX0=0; //關掉中斷,等到發射方波后才開啟,處于別動
- }
- // 延時子程序
- void delay(uint n)
- {
- while(--n);
- }
- //中斷初始化
- void Init0(void)
- { EA=1;
- IT0=1;
- }
- /***************************************
- /*原理是把中斷打開并 發射方波,
- 當有中斷時就轉到中斷產生中斷位為下一步轉向做準備,
- 當沒有是關閉中斷
- ****************************************/
- void seng_wave(uchar timer,bit n)//timer通過載波發射信號的時間,n->左右發射管的選擇
- { uchar i;
- P1 |= 0X04; //ledcs=1為74ls573為11腳為高電平時數據直接輸出,為低時把數據鎖存住,即保持
- IE |= 0X01;
- P0 |=0x0c; //04
- for(i=timer;i>0;i--)
- { if(n)P0^=0x08; // 右發射管通過載波發射信號//00
- else P0^=0x04; // 左發射管通過載波發射信號//0c
- delay(100); //這里控制著靈敏度(控制38khz的方波的多少)和距離
- } //timer*delay(x)即為發射管得到的平均電流
- P1 &= 0Xfb;
- IE &= 0Xfe;
- }
- //led轉向燈指示子程序
- void light_control(uchar deng)
- { ledcs=1;
- P0 =deng;
- ledcs=0; //11111011
- }
- //電機和燈光的控制部分
- void control(uchar n,uchar dj_state,uchar light)
- { uchar i;
- // P1|=0x04;
- light_control(light); //led轉向指示燈
- delay(100);
- P2 =dj_state; //電機的方向控制
- WriteCommandLCD(0x01,1); //LCD顯示清屏
- switch(dj_state)
- { case dj_state2 :{ DisplayListChar(3,1,10,talk4,false);}break;
- case dj_state3: { DisplayListChar(3,1,8,talk3,false);}break;
- case dj_state4: { DisplayListChar(3,1,7,talk1,false); }break;
- default :break;
- }
- for(i=n;i>0;i--)
- {delay(2000);}
- P2=dj_state5; //停車
- light_control(light_off); //led關閉
- WriteCommandLCD(0x01,1); //LCD顯示清屏
- P2=dj_state1; //前進
- if(dj_state1)
- { P1|=0X04; //ledcs=1;
- P0=0x0f;
- P1&=0XFB;
- delay(100);
- DisplayListChar(0,0,7,talk2,false);
- }
- }
- /****************************************
- 避障主要控制部分
- *****************************************/
- void move_car(void)
- {
- uchar temp =0x00;
- //左邊紅外管發射
- seng_wave(1,left_infrare); //向下為中斷開啟有關閉后,要執行的語句
- if(flage==0x01){temp|=0x01;flage=0x00;}
- //右邊紅外管發射
- delay(30);
- seng_wave(1,right_infrare); //向下為中斷開啟有關閉后,要執行的語句
- if(flage==0x01){temp|=0x02;flage=0x00;}
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
自動避障紅外電動小車C51程序.rar
(2.81 KB, 下載次數: 22)
2017-6-25 14:41 上傳
點擊文件名下載附件
自動避障紅外電動小車C51程序 下載積分: 黑幣 -5
|