超声波测距模块HC

您所在的位置:网站首页 老款锐志中控锁接线图视频 超声波测距模块HC

超声波测距模块HC

2024-07-11 14:38| 来源: 网络整理| 查看: 265

本篇文章是个人整理的包含超声波测距模块HC-SR04的基本介绍与基本工作原理以及分别通过LCD1602、数码管和串口显示距离的实例讲解与代码的笔记,部分内容来自《HC-SR04超声波测距模块说明书》,代码使用模块化编辑,部分模块来自江科大自化协的51单片机教学视频。 希望大家早日掌握单片机。

文章目录 一、基本介绍二、基本工作原理三、时序图四、实例(1)最终效果(2)思路Ⅰ、LCD1602显示Ⅱ、数码管显示Ⅲ、串行通信显示 (3)代码实现Ⅰ、LCD1602显示①HCSR04.c②Timer0.c③main.c Ⅱ、数码管显示①Nixie.c②Timer1.c③HCSR04.c④main.c Ⅲ、串行通信显示①HCSR04.c②UART.c③main.c

一、基本介绍

​ 超声波测距模块是根据超声波遇障碍反射的原理进行测距的,能够发送超声波、接收超声波并通过处理,输出一段和发送与接收间隔时间相同的高电平信号,是常用的测距模块之一。HC-SR04是最常用的超声波测距模块之一,HC-SR04超声波模块可提供2cm~400cm的非接触式距离感测功能,测距精度可达3mm,工作电压为5V;内部模块包括超声波发射器、接收器与控制电路。如下为实物与对应端口图:

Vcc:+5V电源供电;Trig:输入触发信号(可以触发测距);Echo:传出信号回响(可以传回时间差);GND:接地。 二、基本工作原理

(1)采用I/O口连接Trig触发测距,给最少10us的高电平后即可发送超声波;

(2)模块自动发送8个40kHz的方波,并自动检测是否有信号返回;

(3)若有信号返回,经内部电路处理后,通过Echo到I/O口输入一个高电平,高电平持续的时间就是超声波从发射到返回的时间;

(4)测试距离=(高电平时间*音速)/2;音速=340m/s=0.034cm/us。

三、时序图

​ 以上时序图表明你只需要向模块提供一个10us以上的脉冲触发信号,然后该模块内部将发出8个40kHz周期电平并检测回波,一旦检测到有回波信号,模块就向I/O口输出回响信号。回响信号的脉冲宽度与所测的距离成正比,由此通过回响信号的高电平时间计算得到距离。建议先将单位转换为cm/us,便于数据显示;测量周期为60ms以上,以防止发射信号对回响信号的影响。

此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作;测距时,被测物体的面积不少于0.5平方米且平面尽量要求平整,否则会影响测量的结果。 四、实例 (1)最终效果 实现超声波测距,并将数据分别显示在LCD1602、数码管和串行通信上。 (2)思路

​ 先将端口初始化(置0),再通过Trig输入一个12us的高电平作为触发信号,最后接收回响信号,回响信号高电平的时间通过定时器0测量——当Echo为1时开始计时,Echo为0时结束计时,不需要打开中断。得到时间后根据公式:测试距离=(高电平时间*音速)/2;音速=340m/s=0.034cm/us,计算出实际距离。

Ⅰ、LCD1602显示

​ 调用LCD1602函数进行显示:

注意:连接LCD1602的端口包括P0和P2,连接超声波模块时注意引脚不能冲突。 Ⅱ、数码管显示

​ 调用数码管函数进行显示,使用定时器扫描数码管。

Ⅲ、串行通信显示 打开定时器1,配置串行通信,波特率为9600;将距离数据通过串口发送到电脑,将发送中断请求标志位TI置1,使计算机不断接收数据;调用stdio.h中的printf函数可以通过串口在电脑上打印数据。 (3)代码实现 Ⅰ、LCD1602显示 ①HCSR04.c #include #include "Timer0.h" //定义引脚接口 sbit Trig = P1^0; sbit Echo = P1^1; /** * @brief HC-SR04初始化 * @param 无 * @retval 无 */ void HCSR04_Init() { Timer0_Init(); Trig = 0; Echo = 0; } /** * @brief HC-SR04接收一个12us的触发信号 * @param 无 * @retval 无 */ void HCSR04_Trig() { unsigned char i; Trig = 1; i = 5;while (--i); //延时12us Trig = 0; } /** * @brief HC-SR04接收触发信号并计算回波信号高电平时间 * @param 无 * @retval 无 */ void HCSR04_Set() { HCSR04_Trig(); while(!Echo); TR0 = 1; while(Echo); TR0 = 0; } /** * @brief HC-SR04计算模块与障碍间的距离 * @param Duration(持续时间) 发送到接收的间隔时间 * @param Distance 模块与障碍间的距离 * @retval Distance */ float HCSR04_Calc() { unsigned int Duration = 0; float Distance = 0; Duration = TH0*256+TL0; Distance = Duration*0.017;//时间*音速/2,音速=340m/s=0.034cm/us TH0 = 0; TL0 = 0; return Distance; } ②Timer0.c #include /** * @brief 定时器0初始化@11.0592MHz * @param 无 * @retval 无 */ void Timer0_Init() //@11.0592MHz { TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TH0 = 0; //设置定时初值 TL0 = 0; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 0; //定时器0不计时 } ③main.c #include #include "Delay.h" #include "HCSR04.h" #include "LCD1602.h" unsigned int Distance; void main() { LCD_Init(); //LCD1602初始化 HCSR04_Init(); //HC-SR04初始化 LCD_ShowString(1,1,"Distance:"); LCD_ShowString(2,4,"cm"); while(1) { HCSR04_Set(); //HC-SR04接收触发信号并计算回波信号高电平时间 Distance = HCSR04_Calc(); //计算距离 LCD_ShowNum(2,1,Distance,3);//调用显示 Delay(20); } } Ⅱ、数码管显示 ①Nixie.c #include #include "Delay.h" //数码管显示缓存区 unsigned char Nixie_Buf[9]={0,10,10,10,10,10,10,10,10}; //数码管段码表 unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40}; /** * @brief 设置显示缓存区 * @param Location 要设置的位置,范围:1~8 * @param Number 要设置的数字,范围:段码表索引范围 * @retval 无 */ void Nixie_SetBuf(unsigned char Location,Number) { Nixie_Buf[Location]=Number; } /** * @brief 数码管扫描显示 * @param Location 要显示的位置,范围:1~8 * @param Number 要显示的数字,范围:段码表索引范围 * @retval 无 */ void Nixie_Scan(unsigned char Location,Number) { P0=0x00; //段码清0,消影 switch(Location) //位码输出 { case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break; } P0=NixieTable[Number]; //段码输出 } /** * @brief 数码管驱动函数,在中断中调用 * @param 无 * @retval 无 */ void Nixie_Loop(void) { static unsigned char i=1; Nixie_Scan(i,Nixie_Buf[i]); i++; if(i>=9){i=1;} } 使用定时器扫描数码管的好处是,在函数循环中调用数码管显示时,不会受到延时函数的影响导致数码管动态显示延时时间延长。 ②Timer1.c #include /** * @brief 定时器1初始化,[email protected] * @param 无 * @retval 无 */ void Timer1_Init(void) { TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x10; //设置定时器模式 TL1 = 0x65; //设置定时初值 TH1 = 0xFC; //设置定时初值 TF1 = 0; //清除TF1标志 TR1 = 1; //定时器1开始计时 ET1=1; EA=1; PT1=0; } /*定时器中断函数模板 void Timer1_Routine() interrupt 3 { static unsigned int T1Count; TL1 = 0x65; //设置定时初值 TH1 = 0xFC; //设置定时初值 T1Count++; if(T1Count>=1000) { T1Count=0; } } */ ③HCSR04.c #include #include "Timer0.h" //定义引脚接口 sbit Trig = P1^0; sbit Echo = P1^1; /** * @brief HC-SR04初始化 * @param 无 * @retval 无 */ void HCSR04_Init() { Timer0_Init(); Trig = 0; Echo = 0; } /** * @brief HC-SR04接收一个12us的触发信号 * @param 无 * @retval 无 */ void HCSR04_Trig() { unsigned char i; Trig = 1; i = 5;while (--i); //延时12us Trig = 0; } /** * @brief HC-SR04接收触发信号并计算回波信号高电平时间 * @param 无 * @retval 无 */ void HCSR04_Set() { HCSR04_Trig(); while(!Echo); TR0 = 1; while(Echo); TR0 = 0; } /** * @brief HC-SR04计算模块与障碍间的距离 * @param Duration(持续时间) 发送到接收的间隔时间 * @param Distance 模块与障碍间的距离 * @retval Distance */ unsigned int HCSR04_Calc() { unsigned int Distance,Duration; Duration = TH0*256+TL0; Distance = Duration*0.017;//时间*音速/2,音速=340m/s=0.034cm/us TH0 = 0; TL0 = 0; return Distance; } ④main.c #include #include "Delay.h" #include "HCSR04.h" #include "Nixie.h" #include "Timer1.h" unsigned int Distance; void main() { HCSR04_Init(); //HC-SR04初始化 Timer1_Init(); //定时器1初始化 while(1) { HCSR04_Set(); //HC-SR04接收触发信号并计算回波信号高电平时间 Distance = HCSR04_Calc(); //计算距离 Nixie_SetBuf(1,Distance/100); Nixie_SetBuf(2,Distance%100/10); Nixie_SetBuf(3,Distance%100%10);//调用显示 Delay(50); } } void Timer1_Routine() interrupt 3 { static unsigned int T1Count1; TL1 = 0x65; //设置定时初值 TH1 = 0xFC; //设置定时初值 T1Count1++; if(T1Count1>=2) { T1Count1=0; Nixie_Loop();//2ms调用一次数码管驱动函数 } } Ⅲ、串行通信显示 ①HCSR04.c #include #include "Timer0.h" //定义引脚接口 sbit Trig = P1^0; sbit Echo = P1^1; /** * @brief HC-SR04初始化 * @param 无 * @retval 无 */ void HCSR04_Init() { Timer0_Init(); Trig = 0; Echo = 0; } /** * @brief HC-SR04接收一个12us的触发信号 * @param 无 * @retval 无 */ void HCSR04_Trig() { unsigned char i; Trig = 1; i = 5;while (--i); //延时12us Trig = 0; } /** * @brief HC-SR04接收触发信号并计算回波信号高电平时间 * @param 无 * @retval 无 */ void HCSR04_Set() { HCSR04_Trig(); while(!Echo); TR0 = 1; while(Echo); TR0 = 0; } /** * @brief HC-SR04计算模块与障碍间的距离 * @param Duration(持续时间) 发送到接收的间隔时间 * @param Distance 模块与障碍间的距离 * @retval Distance */ float HCSR04_Calc() { unsigned int Duration = 0; float Distance = 0; Duration = TH0*256+TL0; Distance = Duration*0.017;//时间*音速/2,音速=340m/s=0.034cm/us TH0 = 0; TL0 = 0; return Distance; } ②UART.c #include /** * @brief 串口初始化,[email protected] * @param 无 * @retval 无 */ void UART_Init() { //设定定时器0和定时器1的工作模式 TMOD = 0x21; //设置定时器0用于计时 TH0 = 0; TL0 = 0; //设定定时器0重装初值 TF0 = 0; //清除TF1标志 TR0 = 0; //停止定时器0 //设置定时器1用于串口波特率 SCON = 0x40; //设定串行口工作方式1 PCON = 0x00; //波特率不翻倍 TH1 = 0xFD; TL1 = 0xFD; //设定定时器1重装初值,波特率为9600 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 TI = 1; //将发送中断请求标志位置1,使计算机不断接收数据 } ③main.c #include #include #include "Delay.h" #include "HCSR04.h" #include "UART.h" float Distance; void main() { UART_Init(); //串行口初始化 while(1) { HCSR04_Set(); //HC-SR04接收触发信号并计算回波信号高电平时间 Distance = HCSR04_Calc(); //计算模块与障碍间的距离 printf("--.---cm\n"); //在串口上打印分割线 printf("Distance=%.3f cm\n",Distance); //在串行口上打印距离数据 Delay(200); //延时200ms } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3