51单片机案例实操 -- 倒车雷达
Posted GenCoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51单片机案例实操 -- 倒车雷达相关的知识,希望对你有一定的参考价值。
结合前面学习的流水灯、蜂鸣器、外部中断、超声波和OLED显示,实现51单片机平台的倒车雷达案例
51单片机倒车雷达案例实操
1. 倒车雷达
倒车雷达(PDC,Parking Distance Control)全称叫“倒车防撞雷达”,也叫“泊车辅助装置”,是汽车泊车或者倒车时的安全辅助装置,由超声波传感器(俗称探头)、控制器和显示器(或蜂鸣器)等部分组成。在倒车时,帮助司机“看见”后视镜里看不见的东西,以声音或者更为直观的显示告知驾驶员周围障碍物的情况,解除了驾驶员泊车、倒车和起动车辆时前后左右探视所引起的困扰,并帮助驾驶员扫除了视野死角和视线模糊的缺陷,提高驾驶的安全性。
案例采用STC89C52单片机做为主控,通过高精度超声波测量距离,STC89C52单片机接收超声波的测量距离信号并处理得到数据,可实时显示在OLED上;
当测量距离小于安全距离时,借助蜂鸣器发出声音报警,也可使用流水灯作为距离检测辅助。
2. 功能模块回顾
2.1 流水灯
有3种方式可以控制板上流水灯
位输出方式:
void main()
while(1)
LED0=ON;
delay(200);
LED0=OFF;
LED1=ON;
delay(200);
LED1=OFF;
LED2=ON;
delay(200);
LED2=OFF;
LED3=ON;
delay(200);
LED3=OFF;
LED4=ON;
delay(200);
LED4=OFF;
LED5=ON;
delay(200);
LED5=OFF;
LED6=ON;
delay(200);
LED6=OFF;
LED7=ON;
delay(200);
LED7=OFF;
移位方式:
void main()
unsigned char i;//0-255
while(1)
P1=0xfe;//1111 1110
for(i=0;i<8;i++)
delay(200);
P1<<=1;//P1=P1<<1
P1=P1|0X01;//0000 0001
循环移位方式:
#include<intrins.h>
void main()
P1=0Xfe;//1111 1110
while(1)
delay(200);
P1=_crol_(P1,1); //循环移位函数 把P1寄存器内的数向左移1位
2.2 蜂鸣器多频率
改变for函数中蜂鸣器高低电平的时间间隔,可以实现蜂鸣器以多段频率鸣叫
unsigned char i;
for(i=20;i>0;i--)
BUZZER = ON;
delay_ms(20);
BUZZER = OFF;
delay_ms(20);
for(i=10;i>0;i--)
BUZZER = ON;
delay_ms(50);
BUZZER = OFF;
delay_ms(50);
2.3 按键检测
通过检测物理按键输入状态执行不同操作(需要加延时消抖)
if(KEY1 == 0)
delay_ms(10);
if(KEY1 == 0)
P1 = 0x00;
if(KEY2 == 0)
delay_ms(20);
if(KEY2 == 0)
P1 = 0xff;
2.4 外部中断
通过外部中断的方式来执行实时性操作
void EXIT_Init()
IT1 = 0; //设置外部中断1触发方式 0:低电平触发 1:下降沿触发
EX1 = 1; //使能外部中断1
EA = 1; //开启全局中断
void main()
P1 = 0xff;
EXIT_Init();
while(1);
//外部中断1服务函数
void EXint1() interrupt 2
delay_ms(10);
if(KEY1 == 0) P1 = ~P1; // 0xff 0x00
while(KEY1 == 0);
2.5 超声波测距
按超声波时序图编写超声波驱动代码(用定时器0做10us延时)
// 延时10us
void Delay10us()
TMOD |= 0x01; //16位定时器/计数器,TH0、TH1全用
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1; //TR0为1时允许T0开始计数
while(!TF0); //当T0溢出时退出while
TF0 = 0; //TF0置0
float GetDistance(unsigned int time)
float distance;
distance = (float)time * 0.017; //cm
return distance;
unsigned int RunOnce()
unsigned int time;
//10us高电平发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
//等待高电平信号接收
while(!Echo);
//T0清0重新计数(高电平持续时间)
TH0 = 0;
TL0 = 0;
TR0 = 1;
//等待高电平信号接收结束
while(Echo);
//关闭T0计数
TR0 = 0;
//高电平时间赋值,单位us
time = TH0*256 + TL0; // TH0<<8 | TL0
TH0 = 0;
TL0 = 0;
return time;
main函数中调用函数计算超声波检测距离
void main()
unsigned int time = 0;
float distance;
while(1)
time = RunOnce(); //计算超声波测距时 传感器接收到高电平的时间
distance = GetDistance(time);
用流水灯“展示”超声波距离
void RunLED(unsigned int LEDnum)
unsigned int RunNum = LEDnum;
switch(RunNum)
case 0:
P1 = 0x00;
delay_ms(20);
P1 = 0xff;
delay_ms(20);
break;
case 1: P1 = 0xfe;
break;
case 2: P1 = 0xfc;
break;
case 3: P1 = 0xf8;
break;
case 4: P1 = 0xf0;
break;
case 5: P1 = 0xe0;
break;
case 6: P1 = 0xc0;
break;
case 7: P1 = 0x80;
break;
case 8: P1 = 0x00;
break;
default:
P1 = 0x00;
break;
void main()
unsigned int time = 0;
float distance;
while(1)
time = RunOnce();
distance = GetDistance(time);
RunLED((int)(distance/10));
根据不同的超声波检测距离使蜂鸣器以不同频率发出声音
void main()
unsigned int time = 0;
float distance;
while(1)
time = RunOnce();
distance = GetDistance(time);
if(distance <= 10.0)
BUZZER = ON;
delay_ms(50);
BUZZER = OFF;
delay_ms(50);
else if((10.0 < distance) && (distance <= 20.0))
BUZZER = ON;
delay_ms(100);
BUZZER = OFF;
delay_ms(100);
else if((20.0 < distance) && (distance <= 50.0))
BUZZER = ON;
delay_ms(160);
BUZZER = OFF;
delay_ms(160);
2.6 OLED显示
需要调用到的显示函数如下:
数字显示函数
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
if(temp==0)
OLED_ShowChar(x+(size2/2)*t,y,' ');
continue;
else enshow=1;
OLED_ShowChar(x+(size2/2)*t,y,temp+'0');
调用示例:
//参数: x坐标,y坐标,数值,位数,大小
OLED_ShowNum(0,0,2,1,8);
汉字显示函数(需取模)
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
调用示例:
//参数 x坐标,y坐标,数组下标
OLED_ShowCHinese(8,0,0);
字符串显示函数
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr)
unsigned char j=0;
while (chr[j]!='\\0')
OLED_ShowChar(x,y,chr[j]);
x+=8;
if(x>120)x=0;y+=2;
j++;
调用示例:
OLED_ShowString(20,0,"Hello World");
3.案例编程
3.1 案例构思
各功能模块在倒车雷达的案例应用构思如下表
功能 | 应用 |
---|---|
流水灯 | 测距辅助 |
蜂鸣器 | 测距辅助 |
板载按键(KEY1除外) | 按键控流水灯/蜂鸣器 |
外部中断(KEY1) | 模式切换(按键模式/测距模式) |
超声波 | 障碍物距离检测 |
OLED显示 | 模式显示/超声波距离显示 |
3.2 汉字取模
将案例中所需要显示的汉字一起取模,然后把取模代码拷贝至工程汉字显示数组中需要显示的文字内容分别是“倒车雷达”,“测距模式”,“按键模式”
unsigned char code Hzk[][32]=
0x84,0x84,0xFC,0x84,0x84,0x00,0xF8,0x00,0xFF,0x00,0x84,0x84,0xFC,0x84,0x84,0x00,
0x10,0x30,0x1F,0x08,0x88,0x42,0x21,0x18,0x07,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,/*"",0*/
0x80,0x60,0xF8,0x07,0x04,0x64,0x5C,0xC4,0x64,0x44,0x00,0xF8,0x00,0xFF,0x00,0x00,
0x00,0x00,0xFF,0x00,0x20,0x62,0x22,0x1F,0x12,0x12,0x00,0x4F,0x80,0x7F,0x00,0x00,/*"倒",1*/
0x00,0x08,0x88,0x48,0x28,0x18,0x0F,0xE8,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,
0x08,0x08,0x09,0x09,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x00,/*"车",2*/
0x20,0x18,0x0A,0xAA,0xAA,0xAA,0x0A,0xFE,0x0A,0xAA,0xAA,0xAA,0x0A,0x28,0x18,0x00,
0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,/*"雷",3*/
0x40,0x40,0x42,0xCC,0x00,0x10,0x10,0x10,0x90,0x7F,0x90,0x10,0x10,0x10,0x10,0x00,
0x00,0x40,0x20,0x1F,0x20,0x48,0x44,0x42,0x41,0x40,0x40,0x41,0x42,0x4C,0x40,0x00,/*"达",4*/
0x10,0x60,0x02,0x8C,0x00,0xFE,0x02,0xF2,0x02,0xFE,0x00,0xF8,0x00,0xFF,0x00,0x00,
0x04,0x04,0x7E,0x01,0x80,0x47,0x30,0x0F,0x10,0x27,0x00,0x47,0x80,0x7F,0x00,0x00,/*"测",5*/
0x00,0x3E,0x22,0xE2,0x22,0x3E,0x00,0xFE,0x22,0x22,0x22,0x22,0x22以上是关于51单片机案例实操 -- 倒车雷达的主要内容,如果未能解决你的问题,请参考以下文章
radar毫米波雷达静态障碍物识别及其相关资料(仿真生成标定运动估计静态障碍物识别)
radar毫米波雷达静态障碍物识别及其相关资料(仿真生成标定运动估计静态障碍物识别)
radar毫米波雷达动态障碍物检测相关论文汇总(聚类分类稀疏2D点4D点雷达成像原始数据处理)