找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5872|回復(fù): 0
收起左側(cè)

智能小車循跡的51單片機(jī)程序

[復(fù)制鏈接]
ID:76556 發(fā)表于 2015-4-10 01:50 | 顯示全部樓層 |閱讀模式
//晶振=11.0592M
//MCU=STC516RD+
//************************************
#include<reg51.h>      //包括一個(gè)52標(biāo)準(zhǔn)內(nèi)核的頭文件
#define uchar unsigned char    //定義一下方便使用
#define uint unsigned int    //定義一下方便使用
uchar Distance;       //定義Distance(距離)變量
sbit Tr1=P1^4;       //定義超聲波模塊的控制端(Tr)
sbit Ec1=P1^5;       //定義超聲波模塊的接收端(Ec)
sbit Tr2=P1^6;       //定義第二個(gè)超聲波模塊的控制端(Tr)
sbit Ec2=P1^7;       //定義第二個(gè)超聲波模塊的接收端(Ec)
sbit IN1=P2^1;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的IN1管腳由51MCU的P2^1管腳控制IN1對(duì)應(yīng)控制OUT1電機(jī)驅(qū)動(dòng)腳
sbit IN2=P2^0;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的IN2管腳由51MCU的P2^0管腳控制IN2對(duì)應(yīng)控制OUT2電機(jī)驅(qū)動(dòng)腳
sbit IN3=P2^2;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的IN3管腳由51MCU的P2^2管腳控制IN3對(duì)應(yīng)控制OUT3電機(jī)驅(qū)動(dòng)腳
sbit IN4=P2^3;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的IN4管腳由51MCU的P2^3管腳控制IN4對(duì)應(yīng)控制OUT4電機(jī)驅(qū)動(dòng)腳
sbit ENA=P2^5;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的ENA管腳由51MCU的P2^5管腳控制ENA腳是使能腳控制IN1,2腳輸入的高低電平是否有效
sbit ENB=P2^4;       //定義L298n步進(jìn)電機(jī)驅(qū)動(dòng)芯片的ENB管腳由51MCU的P2^4管腳控制ENA腳是使能腳控制IN3,4腳輸入的高低電平是否有效
void Delays(uint x)      //延時(shí)函數(shù)Delays..定義形參x為unsigned int 型
{
uint q,w;        //定義實(shí)際參數(shù)q,w為unsigned int 型
for(q=x;q>0;q--)      //q=x,q小于0,q減一。如果q小于零則退出此語句
for(w=110;w>0;w--);      //w=110,w小于0,w減一。如果w小于零則退出此語句
}
void init()          //初始化函數(shù)init
{            //初始化Ec1=0;
Ec1=0;           //初始化Tr1=0;
Tr1=0;
}
void Ranging()         //Ranging(測(cè)距)函數(shù)用于檢測(cè)出距離并控制電機(jī)做出相應(yīng)的動(dòng)作
{
while(1)
{
static uchar Num_Run=0;
static uchar Num3=0;       //定義unsigned char型局部變量Num3,并且只第一次執(zhí)行時(shí)Num3=0,以后執(zhí)行時(shí)不會(huì)再次初始,主要用于超聲波模塊的使能信號(hào)過后用來檢測(cè)接收端Ec1是否有高電平,或用于進(jìn)入和退出while循環(huán),,
static uchar Choice=0;
bit Bit_Num2;         //定義bit型變量(51特有變量)Bit_Num2。。主要用于關(guān)閉定時(shí)器并進(jìn)入下一個(gè)函數(shù)(檢測(cè)Ec1的脈寬長(zhǎng)度)
uchar Move1,Move2,Move3,Move4;             //定義unsigned char變量Move(用來進(jìn)入switch語句并選擇那種工作方式)
if(Choice==2){Choice=0;}
switch(Choice)
  {
  case 0:Tr1=1;Delays(10);Tr1=0;Num3=1;break;    //Tr1給高電平 //至少延時(shí)10微秒 //Tr1給低電平 //Num3給1
  case 1:Tr2=1;Delays(10);Tr2=0;Num3=2;break;
  default:break;
  }
Choice++;           
Bit_Num2=0;          //Bit_Num2給0用于進(jìn)入下一步while循環(huán)
while(Num3==1)         //當(dāng)Num3檢測(cè)到定于1時(shí)進(jìn)入本循環(huán)       //右邊的測(cè)距模塊檢測(cè)程序
  {
  while(Ec1==1)        //當(dāng)Ec1檢測(cè)等于1是進(jìn)入本循環(huán),當(dāng)Ec1(接收信號(hào)的高電平脈寬結(jié)束后退出此循環(huán))
   {          //Bit_Num2給以用來鍵入笑一個(gè)if語句
   Bit_Num2=1;        //打開定時(shí)器TR0進(jìn)入定時(shí)器0中斷
   TR0=1;
   }
  if(Ec1==0&Bit_Num2==1)      //如果Ec1等于0(超聲波測(cè)距模塊的接收端發(fā)送到高電平脈寬傳送完后)而且Bit_Num2等于1進(jìn)入此語句
   {         
   TR0=0;         //關(guān)閉定時(shí)器
   if(Distance<20)       //如果脈寬小于50微秒
    {
    Move1=0;       //Move等于1      
    }
   else if(Distance>60)     //如果上一語句不成立則檢測(cè)此語句,如果脈寬的時(shí)間長(zhǎng)度大于50微秒
    {
    uchar n;
    for(n=1;n>0;n--)
     {
     Move1++;        //Move等于2
     }
    }
   else{};
   if(Distance<60&Distance>20)
    {
    uchar n;
    for(n=2;n>0;n--)
     {
     Move1++;        //Move等于2
     }
    }
   Num3=0;
   }         
  }
while(Num3==2)
  {
  Distance=0;
  while(Ec2==1)        //當(dāng)Ec2檢測(cè)等于1是進(jìn)入本循環(huán),當(dāng)Ec1(接收信號(hào)的高電平脈寬結(jié)束后退出此循環(huán))
   {         
   Bit_Num2=1;        //Bit_Num2給以用來鍵入笑一個(gè)if語句
   TR0=1;        //打開定時(shí)器TR0進(jìn)入定時(shí)器0中斷
   }
   if(Ec2==0&Bit_Num2==1)      //如果Ec1等于0(超聲波測(cè)距模塊的接收端發(fā)送到高電平脈寬傳送完后)而且Bit_Num2等于1進(jìn)入此語句
    {         
    TR0=0;        //關(guān)閉定時(shí)器                 
    if(Distance<20)       //如果脈寬小于50微秒
     {
      Move2=0;   
     }
    else if(Distance>60)     //如果上一語句不成立則檢測(cè)此語句,如果脈寬的時(shí)間長(zhǎng)度大于50微秒
     {
     uchar n;
     for(n=1;n>0;n--)
      {
      Move2++;   
      }
     }
    else{};
    if(Distance<60&Distance>20)     //如果上一語句不成立則檢測(cè)此語句,如果脈寬的時(shí)間長(zhǎng)度大于50微秒
     {
     uchar n;
     for(n=2;n>0;n--)
      {
      Move2++;   
      }
     }
    Num_Run=1;
    Num3=0;
    }   
  }
if(Num_Run==1)
  {
  unsigned char Get[4][4]={{0x01,0x02,0x03,0x04},{0x05,0x06,0x07,0x08},{0x0a,0x0b,0x0c,0x0e},{0x0f,0x11,0x21,0x31}};
  switch(Get[Move1][Move2])       //檢測(cè)Move的值并進(jìn)入相應(yīng)的語句      //Move1=右邊。。//Move2=左邊
   {
   case 0x01:IN1=0;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;break;  //如果Move等于0,則電機(jī)反轉(zhuǎn),并給Distance清零,然后退出此語句   // 左前,右后
   case 0x02:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;    //左后,右前
   case 0x05:IN1=0;IN2=1;IN3=1;IN4=0;ENA=1;ENB=1;break;   //左前,右后
   case 0x06:IN1=0;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;break;  //如果Move等于1,則電機(jī)正轉(zhuǎn),并給Distance清零,然后退出此語句**//前進(jìn)   //左前,右前
   case 0x0a:IN1=0;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;break;  // 左前,右后
   case 0x0b:IN1=1;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;break;   //左停,右后  case 0x0c:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;改為case 0x0b:IN1=0;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;break; 。。。如果有錯(cuò)可以改回來
   case 0x0c:IN1=1;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;break;    // 左前,右后   //
   case 0x03:IN1=1;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;break;   //左后,右前
   case 0x07:IN1=0;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;break;  //左前,右停   
   default:break;              //如果以上都不符合,則退出此語句,準(zhǔn)備下一循環(huán)
   }
  Distance=0;
  Move1=0;             //Move清零;
  Move2=0;
  Move3=0;
  Move4=0;
  Num_Run=0;
  }            
}
}
void open_time()        //定時(shí)器初始函數(shù)
{
TMOD=0x01;          //確定工作方式位01,(內(nèi)容自己上網(wǎng)查啊,大概是16位手動(dòng)重裝計(jì)數(shù)器,,記不清了)
TH0=(65536-1)/256;        //確定一微秒記一次
TL0=(65536-1)%256;        //確定一微秒記一次
EA=1;           //打開總中斷
ET0=1;           //打開定時(shí)器0中斷
TR0=0;           //關(guān)閉定時(shí)器0
}
void main()          //main函數(shù)(主函數(shù)),,所有函數(shù)都從這個(gè)函數(shù)開始執(zhí)行
{            
init();           //執(zhí)行init函數(shù)
open_time();         //執(zhí)行open_time函數(shù)
while(1)          //進(jìn)入大循環(huán)(除非執(zhí)行中斷函數(shù)否則永不退出)
{
Ranging();         //執(zhí)行Ranging函數(shù)
}
}
void time() interrupt 1       //定時(shí)器0中斷語句
{
TH0=(65536-1)/256;        //重裝初值TH0=(65536-1)/256;
TL0=(65536-1)%256;        //重裝初值TL0=(65536-1)%256;
Distance++;          //每次走一步Distance加一
if(Distance==65535)        //如果Distance等于65535就進(jìn)入此語句
{
Distance=0;         //Distance的值清零
}
}  


相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表