1.超声波模块型号
超声波模块是一种常用的测距工具,一般用在避障小车,水位监控系统中,本教程使用的模块型号为HC-SR04,外观形状大体如下
模块除了两个电源引脚外,还有TRIG,ECHO引脚,这两个引脚分别接我们开发板的P2.0和P2.1。
工作原理就是起初先给这两个引脚都拉低,然后让TRIG引脚拉高10微秒以上再拉低产生一个脉冲起始信号(程序中我们是拉高20微秒)。起始信号一开启,ECHO引脚就会被拉高的同时,超声波开始发射,ECHO引脚检测到反射回来的信号时就会被拉低,因为声速为340m/s。那么测出的距离就是
(ECHO引脚高电平持续的时间*340m/s)/2。
中学学过用声波测海底深度,时间*声速=来回的距离,所以需要除以2才是真正的深度,超声波模块也一样。
2.软件分析
计算ECHO引脚高电平的持续时间就用定时器的计数功能完成,如果定时器计数溢出,证明测的距离太远,超出模块的测距范围(最多4米),我们就在数码管上显示999表示距离太远。在测量范围内我们的数码管就显示测出的厘米数。
比如说定时器的计数为9216,那么高电平的持续时间就是9216*(12/11059200)=0.01s
测出的距离就是0.01*340/2=1.7m
数码管就显示170。
不过为了简化单片机的计算过程,我们可以这样算
“( (X*12)/11059200 )*340*100/2”就是厘米数,化简约为“X/54”,X就是定时器的计数值。
本讲代码需要用到“#include<intrins.h >”的“_nop_();”,这个表示延时1微秒左右,请参考《手把手教你学51单片机》文档14.2节后半段文字。
3.代码
#include <reg52.h> #include <function.h> //详见第六章第8讲 #include <timer.h> //详见第八章第11讲 #include <intrins.h> sbit TRIG = P2^0; sbit ECHO = P2^1; u8 FLAG = 0; void delay_20us() { _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); } void main() { u16 time_data,CM_data; TRIG = 0; ECHO = 0; LED_Init(); //初始化LED硬件模块 EA = 1; //闭合总中断开关 TIM1_Init(1000,0); //定时1ms,用来刷新数码管显示,定时精度要求不高可不微调 TMOD &= 0xF0; TMOD |= 0x01; ET0 = 1; while(1) { TH0 = 0; TL0 = 0; FLAG = 0; //上次如果是超出测量范围,FLAG被置1,这次再测就要清0 //启动发射声波 TRIG = 1; delay_20us(); TRIG = 0; while(!ECHO); //声波开始发射,等待ECHO引脚拉高退出这个循环 TR0 = 1; //ECHO引脚一拉高,就打开定时器进行计数 while(ECHO==1 && FLAG==0); //收到声波返回来的信号ECHO引脚就拉低,退出这个循环;如果定时器溢出,就会进入中断函数执行“FLAG=1;” //也就是测量的距离太远,一直没有收到反射回来的信号,不满足“FLAG==0”的条件只能结束这个循环语句 TR0 = 0; //关闭定时器结束计数 time_data =TH0; time_data=(time_data<<8)|TL0; //把两个八位的寄存器里的值组成一个16位变量的值,也就是定时器计数值 CM_data = time_data/54; //得到厘米的表达式 if(FLAG==1){ShowNumber(999); delay_ms(100);} //超出测量范围显示999,延时的目的:比如测得5cm到6cm之间,数码管会频繁在5跟6之间显示,加入延时就会让它们显示的没有那么频繁 else {ShowNumber(CM_data); delay_ms(100);} } } void TIM0_IRQHandler() interrupt 1 { FLAG=1; } void TIM1_IRQHandler() interrupt 3 { TH1 = T1RH; //重新加载重载值 TL1 = T1RL; SEG_Scan(); }
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程