单片机设计 超声波测距仿真(AT89C51)

2023-01-05  

一、电路设计

由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此得到了广泛的应用。如图5即为HC-SR04超声波测距模块

1、基本工作原理:

如图6为超声波测距传感器HC-SR04模块,VCC 接 5V 电源,GND 为地 线,TRIG 为触发控制信号输入,ECHO为回响信号输出。超声波在传播时碰到障碍物即返回,HC-SR04模块收到回波信号后Echo口输出一个高电平。

2.、HC-SR04电气参数:

HC-SR04超声波测距模块可提供2cm至400cm的非接触式距离感测功能,测距精度可达3mm;模块自身包括超声波发射器、接收器与控制电路

3、操作步骤为:

HC-SR04的Trig端口和Echo端口接入单片机的I/O口接,初始化时将trig和echo端口都置低,首先向给 trig 端发送至少10 us的高电平脉冲(模块自动向外发送8个40K的方波),如图6,然后等待,捕捉 echo 端输出一个高电平,当单片机检测到上升沿(或高电平)的同时,打开定时器开始计时,再次等待,直到单片机检测到echo变成下降沿(或低电平)时,结束计数,读出计时器的时间,计数器的计数值乘以单片机计数周期就是超声波从发射到接收的往返时间,即按照

*测试距离(S)=高电平时间(t)声速(v=340m/s)/2

就可以算出超声波到障碍物的距离。

二、运行结果

三、部分代码

#include "task.h"


//全局变量定义

//段码表,适用于共阴数码管

unsigned int code duan_ma[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0~9

0x77,0x7c,0x39,0x5e,0x79,0x71}; //A~F

unsigned int dis_buf[4]; //显示缓存


unsigned int S = 0; //距离缓存变量

unsigned long time = 0; //时间缓存变量 

unsigned int S_H = 400, S_L = 10; //S_H:报警上限值,默认400cm,S_L:报警下限值,默认10cm




/* 延时,单位:ms */

void delayms(unsigned int ms)

{

unsigned char a,b,c;


while(--ms)

{

    for(c=1;c>0;c--)

        for(b=142;b>0;b--)

            for(a=2;a>0;a--);

}

}




/* 计算测距 */

void count(void)

{

start_ranging(); //启动一次超声波

while(!Echo); //等待超声波模块输出IO拉高 

TR0 = 1; //开启定时器计时

while(Echo); //等待超声波模块输出IO拉低

TR0 = 0; //关闭定时器计时

/* 计算距离 */

time = TH0 * 256 + TL0; //得到的时间,专业写法应该是这样:time = TH0 << 8 | TL0

TH0 = 0; //定时计数器清零

TL0 = 0;

S = (time * 1.7) / 100; //算出来是M

}

/* 显示距离 */

void dis_distance(void)

{

dis_buf[3] = 0x00;

dis_buf[2] = duan_ma[S / 100 %10]; //取出百位数,并在数码管的第3位显示,从右往左数

dis_buf[1] = duan_ma[S / 10 %10]; //取出十位数,并在数码管的第2位显示,从右往左数

dis_buf[0] = duan_ma[S % 10]; //取出个位数,并在数码管的第1位显示,从右往左数

}

/* 设置报警功能 */

void key_fuction(void)

{

unsigned char mode_flag = 1; //模式切换标记位,1:设置上限值,2:设置下限值,3:退出


while(1)

{

if(key_scan() == 1)

{

BEEP = 0; //按键提示音

delayms(50);

BEEP = 1;

delayms(1000);

++mode_flag;

if(mode_flag >= 3) //如果满3了,则退出

break;

}

if(key_scan() == 2) //如果加键按下

{

BEEP = 0; //按键提示音

delayms(50);

BEEP = 1;

delayms(1000);

if(mode_flag == 1) //设置上限值

{

++S_H;

if(S_H > 400)

S_H = 2;

}

if(mode_flag == 2) //设置下限值

{

++S_L;

if(S_L > 400)

S_L = 2;

}

}

if(key_scan() == 3) //如果减键按下

{

BEEP = 0; //按键提示音

delayms(50);

BEEP = 1;

delayms(1000);

if(mode_flag == 1) //设置上限值

{

--S_H;

if(S_H < 2)

S_H = 400;

}

if(mode_flag == 2) //设置下限值

{

--S_L;

if(S_L < 2)

S_L = 400;

}

}


/* 报警设置显示 */

if(mode_flag == 1) //显示设置上限值内容

{

dis_buf[3] = 0x76; //第4位数码管显示字母 H

dis_buf[2] = duan_ma[S_H / 100 % 10]; //显示百位数

dis_buf[1] = duan_ma[S_H / 10 % 10]; //显示十位数

dis_buf[0] = duan_ma[S_H % 10]; //显示个位数

}

if(mode_flag == 2) //显示设置下限值内容

{

dis_buf[3] = 0x38; //第4位数码管显示字母 L

dis_buf[2] = duan_ma[S_L / 100 % 10]; //显示百位数

dis_buf[1] = duan_ma[S_L / 10 % 10]; //显示十位数

dis_buf[0] = duan_ma[S_L % 10]; //显示个位数

}

}

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。