关于超声波测距简单示例

       最近由于事情比较杂,加上自己懒得动手码字,一直没有更简书。刚好最近帮学弟做了一个超声波测距(含温度补偿)的小项目,觉得再看以前的示例程序不够通俗明了,站在过来人的视点,写一段简单的示例程序,给大家看看。

       首先想说的是,单片机程序应该从时序图入手。了解外围器件的工作时序,并按照时序,对控制时序的引脚上拉下拉各种跳变,就可以对外围器件进行读写。是不是觉得有点抽象。没有关系,接下来不多说,实际例子来教新手使用HC-SR04这个超声波模块。四个引脚分别是电源正负和收发,探头带有T的是传送(Transmission),带有R的是接收(Receiva)实物如下图1所示。

图1

                                                      

硬件连接图如图2。VCC&GND常规的电源正负,ECHO&TRIG两个脚分别为读写引脚。

图2

介绍了硬件,接下来就是关键的软件部分了,在讲软件之前,一定要说下最核心的时序部分(理解时序是十分重要的工程师素养)。下图3就是这个模块的时序图。

图3

触发信号就是Trig引脚的信号,TTL的10us就是出发信号,由图知道,10us的高电平(TTL规格,不懂TTL得话自己百度哟,主要区别于CMOS电平。)。即可启动模块内部的工作时序,模块内部的发出信号我们不用管,只需要了解接口程序怎么按照时序编写就好了,模块内部的工作,只需要配置好工作时序。直接看第三根线(输出回响信号),其实在模块收到trig=1以后,模块就很快(可以忽略的时间)开始发出声波,同时Echo引脚产生高电平,直到声波接触物体并且返回的时候,Echo才变为低电平。所以第三根时序线的高电平时长除以2就是距离所耗时间。错误的理解探头发出的声波被物体挡住以后,声波返回,R探头接收到声波,Echo引脚产生高电平,直到物体消失,Echo引脚电平变低。声波从T探头发出,物体挡住声波,沈波返回到R探头接收。这段时间就是声波走的总路程。看图4了解测距原理吧。

图4 测距的原理

有没有发现,输出回响信号(时序图第三根线)的高电平保持时间就是声波从发出然后碰到到障碍物返回,所消耗的总时间。把这段时间所走的距离除以2.就是模块与障碍物的距离拉~~~

    那么来看程序吧骚年们,主程序如下。

```

void main()

{

uint L; //定义距离变量为无符号integer

TMOD = 0x01; // 初始化单片机的计时器0,方式1

L=GetDistance();    //调用距离计算的子函数

while(1);            //死循环

}

```

主函数写的应该不难看懂,就是定义要得到的距离是L,然后开启定时器(89C51定时器有T0&T1两个,工作模式有4种,后面我会写文章详细讲定时器/计数器,尽情期待哟),然后调用GetDistance()这个函数获得距离的值,需要注意的是子函数的类型一定要和主函数定义的一致,都是无符号int,避免数据不准确。

```

uint GetDistance(void)

{

uint ss;               // 用于记录测得的距离

TH0=0;              //初始化定时器的高位为0 

TL0=0;              //初始化定时器的低位为0

Trig_P=1;          // 给超声波模块一个开始脉冲

DelayMs(1);       //延时的意义就在于时序要求启动信号要有10um的高电平

Trig_P=0;          //恢复低电平

//前面的程序都是配置时序,使模块工作起来

//模块一旦开始工作,发出声波的同时,会使得ECHO引脚变高

while(!Echo_P);      // 等待超声波模块的Echo变高  直到Echo引脚不再是0

TR0=1;                   // 启动定时器,开始计时

while(Echo_P);      // 等待超声波模块接收到返回声波

TR0=0;                  // 停止定时器,停止计时

ss=((TH0*256+TL0)*0.034)/2;    // 距离cm=(时间us * 速度cm/us)/2

return ss;

}

```

上面这段程序就是严格按照时序写的。如果说有难懂的语句就是定时器的使用,定时器最开始初始化为0。从Echo脚变为1开始计时,收到声波返回停止计时。低位最大只能是256,满了256就要向前进位。举例说明吧,26(十进制数)低位最大是10,挡计数到10的时候,就要向前进位,高位(十位)就会变为3,低位清零继续从0开始计数到10,又进一位。之后十进制数的结果就是 十位X10+个位。同理,计数器也是这样。所以有(TH0*256+TL0)。注意换算单位以后进行运算,并且注意是来回的距离,除以2后就是实际距离哟。讲到这里,简单的超声波测距就完全讲完了,有人跟我吐槽,说我写的例子没有完整的程序,不方便查阅,现附上完整的程序。谢谢大家。

```

/**************Copyrigfht:DENGWEI

TIME:2016.12.12

FUNCTION:超声波测距 

VISION: v1.0**********************/

#include<reg52.h>

#include<intrins.h>  //自带的库 

#define  uchar unsigned char // 以后unsigned char就可以用uchar代替

#define  uint  unsigned int  // 宏定义



sbit Trig_P  = P2^2;        // 超声波模块的Trig管脚

sbit Echo_P  = P2^3;      // 超声波模块的Echo管脚

/*********************************************************/

// 毫秒级的延时函数,time是要延时的毫秒数

/*********************************************************/

void DelayMs(uint time)

{

uint i,j;

for(i=time;i>0;i--)

for(j=110;j>0;j--);

}

/*********************************************************/

// 计算测到的距离

/*********************************************************/

uint GetDistance(void)

{

uint ss; // 用于记录测得的距离

TH0=0;

TL0=0;

Trig_P=1; // 给超声波模块一个开始脉冲

DelayMs(1);        //延时的意义就在于时序要求启动信号要有10um的高电平

Trig_P=0;          //恢复低电平

//前面的程序都是配置时序,使模块工作起来

//模块一旦开始工作,发出声波的同时,会使得ECHO引脚变高

while(!Echo_P); // 等待超声波模块的Echo变高  直到Echo引脚不再是0

TR0=1;     // 启动定时器,开始计时

while(Echo_P); // 等待超声波模块接收到返回声波

TR0=0; // 停止定时器,停止计时

ss=((TH0*256+TL0)*0.034)/2; // 距离cm=(时间us * 速度cm/us)/2

return ss;

}

/*********************************************************/

//主函数

/*********************************************************/

void main()

{

uint L; //定义距离变量为无符号integer

TMOD = 0x01; // 初始化单片机的计时器0,方式1

L=GetDistance();    //调用距离计算的子函数

while(1);            //死循环

}


//end
```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容