超声波模块c语言编程,超声波模块

1.超声波模块型号

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

4ec71b6f22ee5453c1760a34e3d9821d.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”的“_nop_();”,这个表示延时1微秒左右,请参考《手把手教你学51单片机》文档14.2节后半段文字。

3.代码#include 

#include  //详见第六章第8讲

#include     //详见第八章第11讲

#include 

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();

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值