设计分享 | 基于HC-SR04超声波模块实现“倒车雷达”防撞系统

vx【嵌入式工程师成长日记】https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484138&idx=1&sn=5c6de4a1367f6b33b632be9a03b5a3aa&chksm=cf4307b2f8348ea4fe4b5f7c76debdd7da4487e2bfa23a1357c7155bef8d05a1cbb759ce51f0&token=2078690953&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484138&idx=1&sn=5c6de4a1367f6b33b632be9a03b5a3aa&chksm=cf4307b2f8348ea4fe4b5f7c76debdd7da4487e2bfa23a1357c7155bef8d05a1cbb759ce51f0&token=2078690953&lang=zh_CN#rd

具体功能实现

将遮挡物放置HC-SR04前,可以将超声波模块和遮挡物之间的距离展示在4位数码管上;如果两者之间的距离小于5cm,则LED灯(P2^7)亮起。

器件

HC-SR04超声波模块,4位数码管,LED灯,4根杜邦线

超声波测距展示图:

当距离小于5cm时:

此时超声波和遮挡物的距离为4.5cm< 5cm,所以LED(P2^7)点亮。

当距离大于5cm时:

此时超声波和遮挡物的距离为15.6cm,LED灯熄灭

知识介绍

超声波模块(HC-SR04)

以上是该模块测距的工作原理:由Trig引脚发送一个10us的高电平信号,此时模块内部会自动发送8个40khz的脉冲信号,最后声音返回的信号会传送至Echo引脚,利用距离、时间和速度的公式可以得出两者之间的距离

HC-SR04引脚定义图

该项目代码中,Trig口接至P2^1 , Echo接至P2^0,VCC接3.3v,GND接地

超声波测距公式及原理

测试距离 = (高电平时间 * 声速(340m / s)) /2

测试距离最终要除于2的原因是经历了一个来回,相当于走了原本距离的两倍

定时中断系统

外部中断:

STC89C52有4个外部中断;

STC89C52的外部中断有两种触发方式:

下降沿触发和低电平触发

下降沿触发:当按键按下不松手时只触发一次

低电平触发:当按键按下不松手时会持续触发

中断号:

主函数代码(C语言)KEIL5实现

#include <REGX52.H>

/*     自定义变量类型    */

typedef unsigned char uchar;   //0~255

typedef unsigned int uint;     //0~65535

sbit Echo = P2^0;

sbit Trig = P2^1;

uchar flag;

uchar date_distance[5];

uchar count;

/* 用于控制数码管的引脚 */

sbit LSA = P2^2;

sbit LSB = P2^3;

sbit LSC = P2^4;

uchar LSA_NODE1[] = {0,1,0,1,0,1,0,1,0};

uchar LSB_NODE1[] = {0,1,1,0,0,1,1,0,0};

uchar LSC_NODE1[] = {0,1,1,1,1,0,0,0,0};

//共阴数码管码表 0-F

uchar SMG[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00};

//延时10us

void delay_10us(uchar i)

{

   while(i--);

}

//延迟1ms

void delay_ms(uint c)   //误差 0us

{

   uint a,b;

   for(;c>0;c--)

       for(b=102;b>0;b--)

           for(a=3;a>0;a--);

}

/* 数码管选择函数 */

void init_smg(uchar i)

{

   LSA = LSA_NODE1[i];

   LSB = LSB_NODE1[i];

   LSC = LSC_NODE1[i];

}

//初始化定时器

void init_timer()

{

TMOD = 0x11; //打开定时器0 1

//初始化定时器 0

   TH0 = 0x00;

   TL0 = 0x00;

   EA = 1;

   ET0 = 1;

   //TR0 = 1;

//初始化定时器 1

TH1 = 0xF8; //定时2ms

   TL1 = 0xCD;

   ET1 = 1;

   TR1 = 1;

}

//计算距离

void count_distance()

{

//s = 340m/s * time us /2 = 170*time *10^-6 m = 0.17*time mm

uint distance = (TH0*256 + TL0*1)*0.17;  //单位mm

if(distance<50)

{

P2_7 = 0;

}

else {

P2_7 = 1;

}

TH0 = 0;

TL0 = 0;

date_distance[1] = distance%10000/1000;

date_distance[2] = distance%1000/100;

date_distance[3] = distance%100/10;

date_distance[4] = distance%10/1;

}

void display()

{

uchar i;

for(i = 1;i<=4;i++)

{

if(i==1)

P0 = SMG[date_distance[i]] |0x80;

else

P0 = SMG[date_distance[i]];

delay_ms(1);

P0 = 0x00;

}

}

void main()

{

init_timer();

while (1)

{

while(!Echo); //等待Trig发出

TR0 = 1;        //开始计时

while(Echo);      //当Trig发出时,Echo为高电平

TR0 = 0; //终止计时

count_distance();

}

}

//定时器 1 用来数码管显示数据和发射超声波信号

void timer1() interrupt 3

{

TR1 = 0; //终止定时

TH1 = 0xF8; //定时2ms

   TL1 = 0xCD;

count ++;

display();

if(count>100)   //每200ms启动一次超声波模块

{

count = 0;

//启动超声波模块

Trig = 1;

delay_10us(2);

Trig = 0;

}

TR1 = 1;

}

问题解答

Q:

为什么数码管不是显示完整的静态数?

A:

因为数码管显示扫描的速度过慢,只有当扫描的速度足够块,才能“欺骗”眼睛,也就是将延时的时间修改短一些。

如果想要数码管动态显示,只需要将delay_ms里面的时间修改为500即可。

Q:

为什么数码管不能实时更新显示数据,而是按一下RESET的键才能显示当前距离?

A:

解决的方法如下:将数码管要显示的数据赋值给数组,数组将数据进行短暂的存储,以至于数码管有数字可以显示,如果出现问题中的情况,很大原因是因为直接调用数码管的库函数进行显示

Q:

如何通过定时器得到测量距离?

A:

定时器0的初始值TH0和TL0同时设置为0x00,并且此时的TR0=0,也就是定时器还没开启。当Trig发送信号后,Echo开始接受高电平信号,此时开启TR0=1,当Echo恢复低电平时,TR0=0关闭定时器;此时可以得到TH0和TL0的值,将两者合并即可。

更多内容在vx:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484138&idx=1&sn=5c6de4a1367f6b33b632be9a03b5a3aa&chksm=cf4307b2f8348ea4fe4b5f7c76debdd7da4487e2bfa23a1357c7155bef8d05a1cbb759ce51f0&token=2078690953&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484138&idx=1&sn=5c6de4a1367f6b33b632be9a03b5a3aa&chksm=cf4307b2f8348ea4fe4b5f7c76debdd7da4487e2bfa23a1357c7155bef8d05a1cbb759ce51f0&token=2078690953&lang=zh_CN#rd

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值