標(biāo)題: 51單片機(jī)小車走黑線程序 [打印本頁]

作者: 1804181935    時(shí)間: 2019-7-26 20:26
標(biāo)題: 51單片機(jī)小車走黑線程序


/*請(qǐng)將此程序下載到U2
啟動(dòng)鍵為U2P32
停止鍵為U2P33
有可能會(huì)出現(xiàn)黑線傳感器感應(yīng)不到黑線的情況,是因?yàn)楹诰傳感器的靈敏度調(diào)得太高了
應(yīng)該調(diào)低靈敏度,這樣才能檢測(cè)到黑線.因?yàn)殪`敏度太高,黑色反射的紅外光都能被傳感
器識(shí)別,導(dǎo)致檢測(cè)失敗.應(yīng)該把黑線傳感器上的可調(diào)電阻逆時(shí)針調(diào)節(jié),這樣就能把靈敏
度調(diào)低(順時(shí)針調(diào)節(jié)的時(shí)候是調(diào)高)*/

#include <at89x52.h>
#define uchar unsigned char
#define uint unsigned int
void motor_r_z(void);//右邊電動(dòng)機(jī)正轉(zhuǎn)
void motor_l_z(void);//左邊電動(dòng)機(jī)正轉(zhuǎn)
void motor_r_f(void);//右邊電動(dòng)機(jī)反轉(zhuǎn)
void motor_l_f(void);//左邊電動(dòng)機(jī)反轉(zhuǎn)
void go(uchar,uchar);//小車前進(jìn)
void stop(void);//小車停止

sbit IN1=P3^6;//L298N的IN1接到P2.5
sbit IN2=P3^7;//L298N的IN2接到P2.4
sbit IN3=P2^7;//L298N的IN3接到P2.1
sbit IN4=P2^6;//L298N的IN4接到P2.2
sbit ENA=P3^4;//L298N的ENA接到P2.0
sbit ENB=P3^5;//L298N的ENB接到P2.2



sbit left_k=P1^2;//小車左轉(zhuǎn)信號(hào)輸入端為P0.5,P0.5為1時(shí)說明已經(jīng)檢測(cè)到黑線
sbit right_k=P1^3;//小車左轉(zhuǎn)信號(hào)輸入端為P0.4,P0.4為1時(shí)說明已經(jīng)檢測(cè)到黑線
sbit start_k=P3^2;//啟動(dòng)按鍵為U2P32
sbit stop_k=P3^3;//停止按鍵為U2P33

sbit sound=P2^4;//蜂鳴器接到了P2.4上,P2.4為低電平的時(shí)候,蜂鳴器響。

uchar data t_0;//每產(chǎn)生一次T0定時(shí)器中斷的時(shí)候t_0加1
uchar data motor_r;//motor_r用于存放右邊電機(jī)轉(zhuǎn)速和轉(zhuǎn)向的數(shù)據(jù)
uchar data motor_l;//motor_l用于存放左邊電機(jī)轉(zhuǎn)速和轉(zhuǎn)向的數(shù)據(jù)
uchar data Speed_Parameters;

//**延時(shí)子程序**///
void delay_1ms(uint n)
{
        uint i,j;
        for(j=n;j>0;j--)
        for(i=20;i>0;i--);
}


/*******初始化函數(shù)***********/
void ini(void)
{
////T0初始化///
TMOD=0x01; //T0工作在方式1
TH0=0xff; //裝入T0初值
TL0=0xf6;
TR0=1;//開T0中斷
ET0=1;//T0允許中斷
EA=1;
P0=0Xff;
//////////////////////
t_0=0;
/////////////////////
P2=0xff;
P3=0XFF;
P1=0XFF;
sound=0;
delay_1ms(100);//蜂鳴器響100ms
sound=1;
}


///蜂鳴器響///
void Sound(void)
{
sound=0;
delay_1ms(60);
sound=1;
}


/****啟動(dòng)處理函數(shù)****/
void start(void)
{
   uchar a;
aa:while(start_k);//防抖程序
   for(a=0;a<50;a++)
   {
   delay_1ms(1);
   while(start_k)
   goto aa;
   }
   Sound();//調(diào)用蜂鳴器發(fā)音程序
   go(0x64,0x64);//全速直行
}


void go(uchar left_motor,uchar right_motor)//直行
{
Speed_Parameters=right_motor;//給速度參數(shù)賦值
motor_r_z();//調(diào)用右邊電機(jī)正轉(zhuǎn)函數(shù)
Speed_Parameters=left_motor;
motor_l_z();//調(diào)用左邊電機(jī)正轉(zhuǎn)函數(shù)
}


void motor_r_z(void)//右邊電動(dòng)機(jī)正轉(zhuǎn)
{
  motor_r=0x64+Speed_Parameters;
  ENA=1;
}

void motor_l_z(void)//左邊電動(dòng)機(jī)正轉(zhuǎn)
{
  motor_l=0x64-Speed_Parameters;
  ENB=1;
}

void stop(void)
{
ENB=0;
ENA=0;
}


/*********T0中斷服務(wù)程序*****************/
/*********PWM產(chǎn)生***********************/
void time0(void) interrupt 1 using 2
{
TR0=0;//停止T0計(jì)數(shù)
TH0=0xff;//當(dāng)晶振頻率是12M時(shí),每隔0.01ms中斷一次,200次中斷為PWM信號(hào)輸出的周期,
TL0=0xf6;//PWM信號(hào)的頻率=1000/(200*0.01ms)=500HZ
++t_0;//產(chǎn)生一次中斷t_0加1
ACC=t_0;//將t_0的值賦值給ACC
CY=0;//清零CY
ACC-=motor_r;//用ACC減去右邊電動(dòng)機(jī)的參數(shù)(此參數(shù)決定了右邊電機(jī)的轉(zhuǎn)向和速度)
   if(CY==1)//判斷CY是否置1,如果為1,說明ACC-motor_r已經(jīng)為負(fù)數(shù),置位了CY
  {
   IN1=1;//IN1由原來的0變成了1
   IN2=0;//IN2由原來的1變成了0
   goto PWM_2;
  }
IN1=0;//如果CY不等于1,IN1=0,IN2=1
IN2=1;
PWM_2:
ACC=t_0;//重新將t_0的值賦值給ACC
CY=0;//清零CY
ACC-=motor_l;//用ACC減去左邊電動(dòng)機(jī)的參數(shù)(此參數(shù)決定了左邊電機(jī)的轉(zhuǎn)向和速度)
  if(CY==1)//判斷CY是否置1,如果為1,說明ACC-motor_l已經(jīng)為負(fù)數(shù),置位了CY
  {
   IN3=1;//IN3由原來的0變成了1
   IN4=0;//IN4由原來的1變成了0
   goto HIGHT;
  }
  IN3=0;//如果CY不等于1,IN3=0,IN4=1
  IN4=1;

HIGHT:
//ACC=t_0; //重新將t_0的值賦值給ACC
if(t_0!=0xc8)//判斷t_0的值是否不等于200
goto EXIT;//如果不等于200,程序指針指向EXIT執(zhí)行程序  
ACC=0;//如果t_0的值等于200,清零ACC和t_0
t_0=ACC;
EXIT:
TR0=1;//打開TO計(jì)數(shù)
}  


void main(void)
{
uchar a;
ini();//調(diào)用初始化函數(shù)
start();//調(diào)用啟動(dòng)處理函數(shù)
////判斷左傳感器狀態(tài)////
while(1)
{
aa:
         while(!left_k)//判斷左邊傳感器的值是否為0
         goto bb;//如果是0,程序指針指向標(biāo)號(hào)bb,執(zhí)行程序
                 P0_0=0;//如果是1,點(diǎn)亮P1.0上連接的發(fā)光二極管
                // Sound();
                 while(left_k)//如果left_k的值一直為1,不斷的循環(huán)執(zhí)行 go(0x00,0x64);小車左轉(zhuǎn) 直到left_k的值為0為止。
         go(0x00,0x64);//0x00,0x64分別代表左右電動(dòng)機(jī)的轉(zhuǎn)速,兩個(gè)值的取值為0x00到0x64之間,0x00最慢。0x64最快
                              //0x00,0x64這兩個(gè)值不一樣代表兩個(gè)電機(jī)向前轉(zhuǎn)的速度不同,小車將拐彎
         go(0x40,0x40);//執(zhí)行到這句說明left_k已經(jīng)為1,說明左傳感器已經(jīng)離開了黑線。小車直線前進(jìn)
                               //0x40,0x40這連個(gè)值同表示小車執(zhí)行這個(gè)函數(shù)時(shí)將向前走,用戶可以自任意修改這些數(shù)值,達(dá)到小車走黑線
                               //最穩(wěn)定的效果,建議不要取得太大(十六進(jìn)制0x64是最大,其實(shí)也就是十進(jìn)制數(shù)的100),也就是速度等級(jí)
                                           //為0到100個(gè)等級(jí)。
                 P0_0=1;//關(guān)閉LED指示燈
////判斷右傳感器狀態(tài)////
bb:
        while(!right_k)//判斷右傳感器的值是否為0
        goto cc;//如果是0,程序指針指向標(biāo)號(hào)cc,執(zhí)行程序
                 P0_1=0;//如果是1,點(diǎn)亮P1.1上連接的發(fā)光二極管
        // Sound();
                 while(right_k)//如果right_k的值一直為1,不斷的循環(huán)執(zhí)行g(shù)o(0x64,0x0);;小車右轉(zhuǎn) 直到right_k的值為0為止
         go(0x64,0x0);
         go(0x40,0x40);//執(zhí)行到這句說明right_k已經(jīng)為1,說明左傳感器已經(jīng)離開了黑線。小車直線前進(jìn)
                 P0_1=1;//關(guān)閉LED指示燈
///判斷是否按下停止按鈕//////
cc:   

       while(stop_k)//判斷停止鍵是否按下,按下的時(shí)候stop_k為1
       goto aa;////如果是1,程序指針指向標(biāo)號(hào)aa,執(zhí)行程序
        for(a=0;a<20;a++)//如果是0,進(jìn)入防抖程序
        {
          delay_1ms(1);
          while(stop_k)//判斷20次stop_k是否為1
          goto cc;//如果是1,程序指針指向標(biāo)號(hào)cc,執(zhí)行程序
        }
          stop();//20次判斷之后stop_k都是0,立馬停止兩個(gè)電動(dòng)機(jī)
          start();//跳到啟動(dòng)處理函數(shù),執(zhí)行程序。
}
}


00 走黑線源程序.zip

21.51 KB, 下載次數(shù): 6, 下載積分: 黑幣 -5






歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1