#include<reg52.h>#include <intrins.h> //內部包含延時函數 _nop_();
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
unsigned char dj1=0; //左前
unsigned char dj2=0; //右前
unsigned char dj3=0; //左后
unsigned char dj4=0; //右后
uchar num1=0;
uchar t=0;
uchar n=0;
sbit HW1=P0^0; //紅外對管位定義
sbit HW2=P0^1;
sbit HW3=P0^2;
sbit HW4=P0^3;
sbit ENA1=P3^2; //前PWM輸入
sbit ENB1=P3^3;
sbit ENA2=P3^4; //后PWM輸入
sbit ENB2=P3^5;
sbit IN1=P2^0; //前電機
sbit IN2=P2^1;
sbit IN3=P2^2;
sbit IN4=P2^3;
sbit IN5=P2^4; //后電機
sbit IN6=P2^5;
sbit IN7=P2^6;
sbit IN8=P2^7;
sbit RX = P1^2;//ECHO超聲波模塊回響端 左
sbit TX = P1^1;//TRIG超聲波模塊發
sbit rx = P1^3;//ECHO超聲波模塊回響端
sbit tx = P1^4;//TRIG超聲波模塊發
unsigned int time = 0;//傳輸時間
unsigned long S = 0;//距離
bit flag = 0;//超出測量范圍標志位
unsigned int time1 = 0;//傳輸時間
unsigned long S1 = 0;//距離
bit flag1 = 0;//超出測量范圍標志位
void Delay10us(unsigned char i) //10us延時函數 啟動超聲波模塊時使用
{
unsigned char j;
do{
j = 10;
do{
_nop_();
}while(--j);
}while(--i);
}
void Delay10us1(unsigned char i) //10us延時函數 啟動超聲波模塊時使用
{
unsigned char j;
do{
j = 10;
do{
_nop_();
}while(--j);
}while(--i);
}
void StartModule() //啟動超聲波模塊
{
TX=1; //啟動一次模塊
Delay10us(2);
TX=0;
}
void StartModule1() //啟動超聲波模塊
{
tx=1; //啟動一次模塊
Delay10us(2);
tx=0;
}
/*計算超聲波所測距離并顯示*/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(float)(time*1.085)*0.17; //算出來是MM
if((S>=700)||flag==1) //超出測量范圍
{
flag=0;
}
}
void Conut1(void)
{
time1=TH0*256+TL0;
TH0=0;
TL0=0;
S=(float)(time1*1.085)*0.17; //算出來是MM
if((S1>=700)||flag==1) //超出測量范圍
{
flag1=0;
}
}
void delay(uint x) //延時1ms
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void qianjin() //小車前進
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=35; //左前
dj2=30; //
dj3=25; // 右后
dj4=25; //
}
void weileft() //小車前進向左微調
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=40;
dj2=50;
dj3=45;
dj4=45;
}
void weiright() //小車前進向右微調
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=55;
dj2=35;
dj3=35;
dj4=35;
}
void daright()
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=25;
dj2=15;
dj3=15;
dj4=25;
}
void daleft()
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=15;
dj2=25;
dj3=25;
dj4=15;
}
void stop() //小車停止
{
dj1=0;
dj2=0;
dj3=0;
dj4=0;
}
/*超聲波避障*/
void Avoid()
{
if(S<400||S1<400)
{
stop();//停車
delay(2500);
do
{
if(S<=S1)
{
// back();
// delay(100);//后退時間越長、距離越遠。后退是為了留出車輛轉向的空間
// stop();
delay(2500); //小車停止
daright();
delay(2500);
// qianjin();
// delay(1000);
// daleft();
// delay(500);
}
if(S>S1)
{
// back();
// delay(100);//后退時間越長、距離越遠。后退是為了留出車輛轉向的空間
// stop(); //小車停止
// delay(500);
daleft();
delay(2500);
// qianjin();
// delay(1000);
// daleft();
// delay(500);
}
StartModule(); //啟動模塊測距,再次判斷是否
while(!RX); //當RX(ECHO信號回響)為零時等待
TR0=1; //開啟計數
while(RX); //當RX為1計數并等待
TR0=0; //關閉計數
Conut(); //計算距離
StartModule1(); //啟動模塊測距,再次判斷是否
while(!rx); //當RX(ECHO信號回響)為零時等待
TR0=1; //開啟計數
while(rx); //當RX為1計數并等待
TR0=0; //關閉計數
Conut(); //計算距離
}while(S < 280||S1<280);//判斷前面障礙物距離
}
else
{
qianjin();
}
}
void init() //初始化
{
TMOD|=0x01;
TMOD |= 0x11;//定時器0工作模塊1,16位定時模式。T0用測ECH0脈沖長度
TH0 = 0;
TL0 = 0;//T0,16位定時計數用于記錄ECHO高電平時間
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
EA=1;
ET1=1;
ET0 = 1;//允許T0中斷
TR1=1;
TR0=1;
}
/*定時器0中斷*/
void timer0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
{
flag=1;
flag1=1; //中斷溢出標志
}
void timer1() interrupt 3 //定時器1中斷
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
t++;
if(t<dj1) ENA1=1;
else ENA1=0;
if(t<dj2) ENB1=1;
else ENB1=0;
if(t<dj3) ENA2=1;
else ENA2=0;
if(t<dj4) ENB2=1;
else ENB2=0;
if(t>=100)
{
t=0;
}
}
void main()
{
init();
while(1)
{
StartModule(); //啟動模塊測距
while(!RX); //當RX(ECHO信號回響)為零時等待
TR0=1; //開啟計數
while(RX); //當RX為1計數并等待
TR0=0; //關閉計數
Conut(); //計算距離
StartModule1(); //啟動模塊測距
while(!rx); //當RX(ECHO信號回響)為零時等待
TR0=1; //開啟計數
while(rx); //當RX為1計數并等待
TR0=0; //關閉計數
Conut1(); //計算距離
Avoid(); //避障
delay(65); //測試周期不低于60MS
}
}
|