历史上的今天
返回首页

历史上的今天

今天是:2026年01月31日(星期六)

2023年01月31日 | 基于HC-SR04超声波模块实现“倒车雷达”防撞系统

2023-01-31 来源:zhihu

具体功能实现

将遮挡物放置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


/*     自定义变量类型    */


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的值,将两者合并即可。


推荐阅读

史海拾趣

问答坊 | AI 解惑

 2006年上半年十大病毒防治办法

 一、灰鸽子   Backdoor/Huigezi.**“灰鸽子”是一个未经授权远程访问用户计算机的后门。以“灰鸽子”变种cm为例,该变种运行后,会自我复制到系统目录下。修改注册表,实现开机自启。侦听黑客指令,记录键击,盗取用户机密信息,例如用户拨号上 ...…

查看全部问答>

今天阴差阳错地被面试了

原本打算等到明年中旬再找工作的,因此这次经历来得比较意外。         今天早上,8点多,在床上。隔壁学弟学妹准备去学校里参加“自考毕业生招聘会”(这个名字还是前天经过学校从海报上看来的)。于是我赶紧起床 ...…

查看全部问答>

wince的奇怪问题

具体表现为:USB连接PC导致PC蓝屏,同时WINCE系统变得很慢。也就是说,只要不连接USB,就没问题。 本人对USB这块不懂,特来请教大家,先谢过了哈 板子是三星的2416。…

查看全部问答>

有人做过用红外二极管传输数据没?

发射端加38KHZ载波驱动,那接收端是不是也要加38HZ载波驱动? 接收端用的是VS838 另如果用现成的红外收发模块有什么推荐的没?距离不用超过10M,速率不要求很高,几百BPS就够了,但要便宜…

查看全部问答>

《EVC高级编程及其应用开发》这本书上基础数据库的例子

《EVC高级编程及其应用开发》这本书上基础数据库的例子…

查看全部问答>

应急灯应用心得

本次响应坛坛的号召加入应急灯的制作团队,从最初研究到最终完成,中间经历很多事情,来回反复. 刚开始的第一阶段,我了解应急灯,计划做一个单片机进行管理的可控应应急灯.构思挺复杂的.  要求也挺高的.  比如LED 灯驱动芯片的选择, 开始我选 ...…

查看全部问答>

关于STM32的几个问题

1.我使用的EEPROM芯片是AT24C64,请问STM32的硬件I2C可以使用不?2.在市面上买的普通晶振是不是最好不串390欧的电阻,并且能可靠的起振?3.使用8M的晶振可以实现ISP不?能不能产生精确的115200的波特率?4.RTC的时钟可以来自外部的8M不?我的 ...…

查看全部问答>

MSP 430单片机教程

MSP 430单片机教程  欢迎使用…

查看全部问答>

g2XXX芯片烧录问题

现在有个项目开发,选用了G2 系列,代理商那里借用了一块launchPad开发板,程序调试的差不多了,不知道以后如何把生成的HEX文件烧录芯片中…

查看全部问答>

晒晒我的EP3C10E144C8N最小系统板

闲来无事做了一块FPGA板子 折腾了几天终于调试通了 晒晒 板子正面视图 板子背面视图 最后还有原理图是必须的 …

查看全部问答>