标题:
关于单片机超声波避障的代码
[打印本页]
作者:
chen7529
时间:
2019-4-6 22:55
标题:
关于单片机超声波避障的代码
关于一些简单的超声波避障代码
单片机源程序如下:
#include<reg52.h>
//定义选择开关
sbit selet1 = P3^5;
sbit selet2 = P3^4;
//sbit selet3 = P3^3;
//定义L298N端口
sbit in1 = P0^0;
sbit in2 = P0^1;
sbit in3 = P0^2;
sbit in4 = P0^3;
sbit enA = P0^4;
sbit enB = P0^5;
//定义微动开关端口
sbit key1 = P1^0;
sbit key2 = P1^1;
//定义蜂鸣器
sbit beep = P3^6;
//定义超声波模块端口
sbit Trig = P1^2;
sbit Echo = P1^3;
unsigned int distance_cm = 0; //距离
unsigned int overflow_count = 0; //溢出计数
unsigned int status = 0; //超声波模块状态
unsigned int dis_count = 0; //计数
unsigned char tmp, dat, flat;
unsigned int num, model, c=0;
unsigned int speed = 100;
//static unsigned int car_statues = 5; //小车默认状态为停止
void delay(unsigned int z);
void delay_us(unsigned int aa);
void forward(unsigned char pwm);
void f(void);
void back(unsigned char pwm);
void b(void);
void left(unsigned char pwm);
void l(void);
void right(unsigned char pwm);
void r(void);
void stop(void);
void laba(unsigned int i);
void chaoshengbo_init(void);
void GetDistance(void);
void lanya_init(); //串口初始化
void send(unsigned char a); //单字节发送函数
void ctrl(); //接收处理函数
void get_model(unsigned char value);
void main(void)
{
unsigned int n = 0;
//chaoshengbo_init();
lanya_init(); //蓝牙模块初始化
speed = 40;
while(1)
{
get_model(SBUF);
if(model == 1)
forward(speed);
if(model == 2)
left(speed);
if(model == 3)
right(speed);
if(model == 4)
back(speed);
if(model == 5)
stop();
if(model == 6)
speed = 40;
if(model == 7)
speed = 75;
if(model == 8)
speed = 100;
if(RI==1) // 是否有数据到来
{
RI = 0;
ctrl();
}
if(selet1 == 0) //S1被按下时,前进,微动开关模式
{
delay(5); //消抖
if(selet1 == 0) //确认按键被按下
{
while(!selet1) //松开按键检测
;
n = 1; //n赋值为1,微动开关模式
}
}
if(selet2 == 0) //S2被按下时,后退,超声波避障模式
{
delay(5); //消抖
if(selet2 == 0) //确认按键被按下
{
while(!selet2) //按键松开检测
;
n = 2; //n赋值为2,超声波避障模式
}
}
/*
if(selet3 == 0) //S3被按下时,手机蓝牙控制模式
{
delay(5); //消抖
if(selet3 == 0) //确认按键被按下
{
while(!selet3) //按键松开检测
;
n = 3; //n赋值为3,蓝牙控制模式
lanya_init();
}
}
*/
if( n == 1) //若n为1,微动开关模式
{
f(); //默认前进
if(key1 == 0) //若左边微动开关被按下
{
delay(5); //消抖
if(key1 == 0) //确认左边微动开关被按下
{
//while(!key1); //按键松开检测
b(); //先后退
delay(1000);
r(); //再左转
delay(1000);
}
}
if(key2 == 0) //若右边微动开关被按下
{
delay(5); //消抖
if(key2 == 0) //确认右边微动开关被按下
{
//while(!key2); //按键松开检测
b(); //先后退
delay(1000);
r(); //在右转
delay(1000);
}
}
}
else if( n == 2) //若n为2,超声波避障模式
{
ES = 0;
TR1 = 0;
chaoshengbo_init(); //超声波模块初始化
//speed = 100;
b(); //默认后退
GetDistance(); //获取距离
if(distance_cm > 0 && distance_cm <= 15) //若获取的距离大于0且小于等于15cm时
{
f(); //先前进(与默认行驶方式相反)
delay(1000);
r(); //再右转
delay(1000);
}
}
/*
else if( n == 3) //若n为3, 蓝牙控制模式
{
//TR2 = 0; //关闭超声波模块开的定时器2
lanya_init(); //蓝牙模块初始化
stop(); //默认停止
get_model(SBUF); //获取信号
speed = 35;
if(model == 1) //若接收到的信号为1,前进
forward(speed); //前进
if(model == 2) //若接收到的信号为2,左转
left(speed); //左转
if(model == 3) //若接收到的信号为3,右转
right(speed); //右转
if(model == 4) //若接收到的信号为4,后退
back(speed); //后退
if(model == 5) //若接收到的信号为5,停止
stop(); //停止
if(model == 6) //若接收到的信号为6,一档
speed = 35; //speed为35
if(model == 7) //若接收到的信号为7,二挡
speed = 70; //speed为70
if(model == 8) //若接收到的信号为8,三挡
speed = 100; //speed为100
if(RI==1) //判断是否有数据到来
{
RI = 0;
ctrl();
}
}
*/
}
}
//小车右转
void right(unsigned char pwm)
{
enA = 1;
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 0;
delay_us( pwm );
enA = 1;
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
delay_us( 100 - pwm );
}
void r(void)
{
enA = 1;
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 0;
}
//小车左转
void left(unsigned char pwm)
{
enA = 1;
in1 = 0;
in2 = 0;
in3 = 1;
in4 = 0;
delay_us( pwm );
enA = 1;
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
delay_us( 100 - pwm );
}
void l(void)
{
enA = 1;
in1 = 0;
in2 = 0;
in3 = 1;
in4 = 0;
}
//小车后退
void back(unsigned char pwm)
{
enA = 1;
enB = 1;
in1 = 1;
in2 = 0;
in3 = 1;
in4 = 0;
delay_us( pwm );
enA = 1;
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
delay_us( 100 - pwm );
}
void b(void)
{
enA = 1;
enB = 1;
in1 = 1;
in2 = 0;
in3 = 1;
in4 = 0;
}
//小车前进
void forward(unsigned char pwm)
{
enA = 1;
enB = 1;
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 1;
delay_us( pwm );
enA = 1;
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
delay_us( 100 - pwm );
}
void f(void)
{
enA = 1;
enB = 1;
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 1;
}
//小车停止
void stop(void)
{
enB = 1;
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
}
/*
//喇叭
void laba(unsigned int i)
{
unsigned char j;
if( i == 1 )
forward();
else if( i == 2 )
left();
else if( i == 3 )
right();
else if( i == 4 )
back();
else if( i == 5 )
stop();
for(j=200; j>0; j--)
{
beep = ~beep;
delay_us(500);
}
delay(500);
for(j=200; j>0; j--)
{
beep = ~beep;
delay_us(500);
}
}
*/
//超声波模块初始化
void chaoshengbo_init(void)
{
Trig = 0;
//TH2 = RCAP2H = 0;
//TL2 = RCAP2L = 0;
TH0 = TL0 = 0;
TR0 = 0; //关闭定时器0
ET0 = 1; //允许T0中断
}
//超声波模块获取距离
void GetDistance(void)
{
Trig = 1; //发送触发信号
status = 1; //状态1为发射超声波
TH0 = 0;
TL0 = 0;
TR0 = 1; //打开定时器0
while(TL0 < 42) //产生超过10us的脉冲
;
status = 2; //状态2为发射完超声波后
Trig = 0;
TR0 = 0;
TH0 = 0;
TL0 = 0;
overflow_count = 0;
TR0 = 1; //打开定时器0
while(Echo == 0) //当无信号返回时
{
if(status == 5) //状态5表示超时
{
status = 0;
distance_cm = 0;
break ; //失败
}
}
TR0 = 0; //清空计数
TH0 = 0;
TL0 = 0;
overflow_count = 0;
TR0 = 1;
while(Echo == 1) //有信号返回时,开始计算长度
{
if(status == 5) //status为5时失败
{
status = 0;
distance_cm = 0;
TR0 = 0;
break ;
}
}
dis_count = overflow_count * 65536 + TH0 * 256 + TL0;
TR0 = 0;
distance_cm = (unsigned int)( (long)(dis_count) * 34 / 10000);
status = 0 ; //准备下次发送
}
//定时器2中断
void Timer0Int() interrupt 1
{
TF0 = 0;
overflow_count++;
TH0 = 0;
TL0 = 0;
if(overflow_count == 2)
{
status = 5; //超时
}
}
//蓝牙模块
void get_model(unsigned char value)
{
unsigned char shu1,value1;
value1=value-48;
//bai=value1/16;
shu1=value1%16;
switch(shu1)
{
case 1:model = 1;break; //model赋值为1,前进
case 2:model = 2;break; //model赋值为2,左转
case 3:model = 3;break; //model赋值为3,右转
case 4:model = 4;break; //model赋值为4,后退
case 5:model = 5;break; //model赋值为5,停止
case 6:model = 6;break; //model赋值为6,一档
case 7:model = 7;break; //model赋值为7,二挡
case 8:model = 8;break; //model赋值为8;三挡
//case 9:model = 6;break; //model赋值为6,喇叭
}
}
void lanya_init() //串口初始化
{
TR1 = 0;
ES=0; //关中断
SCON = 0x50; // 即10010000,REN为1,串口工作模式为2
//
TMOD = 0x20; // 定时器1工作于方式2,8位自动重载模式, 用于产生波特率
TH1=TL1=0xFD; // 初始值设为FD,产生9600波特率
PCON &= 0x7f; // 即SMOD1为0,波特率不倍增
TR1 = 1; //定时器1开始工作,产生波特率
//发送标志位置0
TI=0; //接收标志位置0
RI=0;
//EA=0;
ES=1;
}
void send(unsigned char a) //单字节数据发送
{
TI=0;
SBUF=a;
while(TI==0);
TI=0;
}
void ctrl() //接收处理函数
{
//static unsigned int car_statues = 5; //小车默认状态为停止
switch(tmp)
{
case '1':send(tmp);break; //前进
case '2':send(tmp);break; //左转
case '3':send(tmp);break; //右转
case '4':send(tmp);break; //后退
case '5':send(tmp);break; //停止
case '6':send(tmp);break; //一档
case '7':send(tmp);break; //二挡
case '8':send(tmp);break; //三挡
//case '9':send(tmp);break; //喇叭
default:send(tmp);
}
}
void delay(unsigned int z)
{
unsigned int x, y;
for(x = z; x > 0 ; x--)
for(y=110;y>0;y--)
;
}
void delay_us(unsigned int aa)
{
while(aa--);
}
复制代码
所有资料51hei提供下载:
源码.7z
(4.11 KB, 下载次数: 9)
2019-4-9 02:08 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2019-4-9 02:08
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1