#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
}
}
|