3.超声波模块

发布日期:2020-12-26 09:10:01 来源:网络转载

1.超声波模块型号

超声波模块是一种常用的测距工具,一般用在避障小车,水位监控系统中,本教程使用的模块型号为HC-SR04,外观形状大体如下

9.3.png

模块除了两个电源引脚外,还有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();
}
关键词 :
网站违法和不良信息举报邮箱:23139485@qq.com
CopyRight@2020-2030 www.haoapp8.cn All Rights Reserved.C语言学习网版权所有 粤ICP备15061369号
免责声明:本站内容来源于用户自行提供或网络收集,其真实性、准确性和合法性,www.haoapp8.cn不提供任何保证,亦不承担任何法律责任.而产生的法律关系及法律纠纷,由您自行协商解决。