#defineucharunsignedchar#defineuint unsigne……"/> #defineucharunsignedchar#defineuint unsigne……"/>
歡迎您光臨本站 登入註冊首頁

紅外避障電動小車C51程序

admin @ 2014-03-25 , reply:0

概述

#include"reg51.h"#include#defineucharunsignedchar#defineuint unsigne……

#include"reg51.h"
#include
#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;}

      //左邊有障礙物,右轉
     if(temp==0x01){control(2,dj_state2,left_light); temp =0x00;}
      //右邊有障礙物,左轉
      else if(temp==0x02) {control(2,dj_state3,right_light ); temp =0x00;}
       //兩個方向都有障礙物,後退,右轉
        else if(temp==0x03) {control(10,dj_state4,back_light );
              control(5,dj_state2,right_light ); temp =0x00;}       

    }
void main(void)
{  Init0();       //中斷初始化
   P1 |= 0X04;    //開鎖存器的控制位
   P0 = 0xFf;     //數據口的清零
   P1&=0XFB;      //關鎖存器的控制位
   LCDInit();     //LCD初始化
   WriteCommandLCD(0x01,1);   //顯示清屏
   delay(100);
   P2=dj_state1;
   DisplayListChar(0,0,8,talk2,false);
 while(1)
   {    move_car();  //主要控制部分
        delay(200000);//延時
    }
 }


[admin via 研發互助社區 ] 紅外避障電動小車C51程序已經有2204次圍觀

http://cocdig.com/docs/show-post-42090.html