超声波测距HC-SR04模块的简单应用

news2024/12/23 1:24:33

文章目录

  • 一、HC-SR04
    • HC-SR04是什么?
    • HC-SR04测距的原理
  • 二、使用步骤
    • 1.硬件
      • 最远探测距离调节
      • 硬件连接
    • 2.软件
      • 1.初始化配置代码如下(示例):
        • 引脚初始化
        • 定时器初始化
      • 2.引脚输入输出配置代码如下(示例):
      • 3.定时器中断处理代码如下(示例):
      • 4.HCSR04测距函数代码如下(示例):
      • 5.显示函数代码如下(示例):
      • 6.变量定义如下(示例):
      • 7.显示结果如下(示例):
        • 图片
        • 串口打印
  • 三、总结


一、HC-SR04

HC-SR04是什么?

HC-SR04是一种常见的超声波测距模块,它可以用于测量物体与传感器之间的距离,在机器人导航、智能家居和安防系统等领域得到了广泛的应用。

HC-SR04超声波测距模块包含一个发射器和一个接收器,它们通过超声波信号实现测距。当发射器发出超声波信号后,它会被目标物体反射回来,并被接收器接收。根据超声波从发射到接收的时间差,就可以计算出物体与传感器之间的距离。

正面
在这里插入图片描述
背面:
在这里插入图片描述

HC-SR04测距的原理

工作原理:
HC-SR04超声波测距模块由发射器和接收器组成。它通过发射超声波信号并接收反射回来的信号,利用信号的往返时间差来计算距离。

(1)采用 IO 触发测距,给至少 10us 的高电平信号;
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2;

在这里插入图片描述
模块使用注意事项:
1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响
模块工作。
2:测距时,被测物体的面积不少于 0.5 平方米且要尽量平整。否则会影响测试结果。

二、使用步骤

1.硬件

最远探测距离调节

在这里插入图片描述
上图标志电阻即 R3,可以调节最大探测距离。R3 电阻为 392,探测距离最大 4.5M 左右,探测角度小于 15 度;R3 电阻为 472,探测距离最大 7M 左右,探测角度小于 30 度;出厂默认 392,即最大探测距离 4.5M 左右。R3 电阻大,接收部分增益高,检测距离大,但检测角度会相应变大,容易检测到前方旁边的物体。当然,在不要求很高的测试距离的条件下,
可以改小 R3 来减小探测角度,这时最大测距会减小。

硬件连接

VCC电源5V接5V
Trig控制端接PB12
Echo接收端接PB13
GND电源地接GND
/* Defines ------------------------------------------------------------------*/
#define HCSR04_GPIO_RCC    RCC_APB2Periph_GPIOB
#define HCSR04_GPIO_Port   GPIOB
#define Trig_Pin           GPIO_Pin_12
#define Echo_Pin           GPIO_Pin_13//根据实际的引脚修改

2.软件

1.初始化配置代码如下(示例):

/*******************************************************************************
 * 函数名:User_HCSR04_Init
 * 描述  :HCSR04初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void User_HCSR04_Init(void)
{
	User_TIM1_Init();
    HCSR04_GPIO_Init();
}
引脚初始化
/*******************************************************************************
 * 函数名:HCSR04_GPIO_Init
 * 描述  :HCSR04引脚初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void HCSR04_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出   

	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

	GPIO_InitStructure.GPIO_Pin = Trig_Pin;//控制脚 Trig	

	GPIO_Init(HCSR04_GPIO_Port, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入 

	GPIO_InitStructure.GPIO_Pin = Echo_Pin;//接收脚 Echo	

	GPIO_Init(HCSR04_GPIO_Port, &GPIO_InitStructure);	
}
定时器初始化

/*******************************************************************************
 * 函数名:User_TIM1_Init
 * 描述  :定时器1初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void User_TIM1_Init(void)
{
    RCC_APB2PeriphClockCmd(HCSR04_TIM_CLK_ENABLE, ENABLE); // 启用TIM1时钟

    TIM_InternalClockConfig(HCSR04_TIM);// 设置TIM1使用内部时钟

    TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStructure;// 定义结构体,配置定时器
    TIM1_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 设置1分频(不分频)
    TIM1_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 设置计数模式为向上计数
    TIM1_TimeBaseInitStructure.TIM_Period = PERIOD_COUNT - 1;    // 设置最大计数值,达到最大值触发更新事件
    TIM1_TimeBaseInitStructure.TIM_Prescaler = PRESCALER_COUNT - 1;    // 设置时钟预分频
    TIM1_TimeBaseInitStructure.TIM_RepetitionCounter = 0;    // 重复计数器
    TIM_TimeBaseInit(HCSR04_TIM, &TIM1_TimeBaseInitStructure);    // 初始化TIM1定时器

    TIM_ClearFlag(HCSR04_TIM, TIM_FLAG_Update);    // 清除更新中断标志位
    TIM_ITConfig(HCSR04_TIM, TIM_IT_Update, ENABLE);    // 开启更新中断

	TIM1_NVIC_Init();
	 
    TIM_Cmd(HCSR04_TIM, ENABLE);    // 开启定时器
}

/*******************************************************************************
 * 函数名:TIM1_NVIC_Init
 * 描述  :定时器1中断配置初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void TIM1_NVIC_Init(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    // 设置中断优先级分组

    NVIC_InitTypeDef NVIC_InitStructure;    // 定义结构体,配置中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = HCSR04_TIM_IRQn; // 指定中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    // 中断使能
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    // 设置抢占优先级为最高
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    // 设置响应优先级为最高
    NVIC_Init(&NVIC_InitStructure);
}

2.引脚输入输出配置代码如下(示例):

/*******************************************************************************
 * 函数名:Trig_out_High
 * 描述  :Trig输出高电平
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Trig_Out_High(void)
{
  GPIO_SetBits(HCSR04_GPIO_Port,Trig_Pin);//Trig= 1
}

/*******************************************************************************
 * 函数名:Trig_Out_Low
 * 描述  :Trig输出低电平
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Trig_Out_Low(void)
{
  GPIO_ResetBits(HCSR04_GPIO_Port,Trig_Pin);//Trig= 0		
}

/*******************************************************************************
 * 函数名:Read_Echo_Level
 * 描述  :读取Echo引脚电平
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
uint8_t Read_Echo_Level(void)
{
  return GPIO_ReadInputDataBit(HCSR04_GPIO_Port,Echo_Pin);
}

3.定时器中断处理代码如下(示例):


/*******************************************************************************
 * 函数名:HCSR04_TIM_IRQHandler
 * 描述  :定时器1中断服务程序
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void HCSR04_TIM_IRQHandler(void)
{
    if(TIM_GetITStatus(HCSR04_TIM, TIM_IT_Update) != RESET)
    {
	    if(ditance_flag)
		{
			ditance_count++;
		}
        TIM_ClearITPendingBit(HCSR04_TIM, TIM_IT_Update); //清除中断挂起位
    }
}

4.HCSR04测距函数代码如下(示例):

/*******************************************************************************
 * 函数名:Measurement_function
 * 描述  :HCSR04测距函数
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Measurement_function(void)
{
    Trig_Out_High();
	Delay_20us();
    Trig_Out_Low();	
	while(Read_Echo_Level()==0);//等待低电平结束
	ditance_count = 0;	
	while(Read_Echo_Level()==1);//等待高电平结束	
    ditance_flag = 1;	
	if(ditance_count < Overtime)//小于超时时间 38ms
	{
	   MM_ditance = ((ditance_count * 340)/2)/100;//单位毫米MM
	}
}

5.显示函数代码如下(示例):

对OLED有疑问的可以参考我的另外一篇博客0.96寸OLED(IIC接口)显示屏的图像显示应用

/*******************************************************************************
 * 函数名:OLED_Rfresh
 * 描述  :OLED实时显示数据刷新
 * 输入  :void
 * 输出  :void
 * 调用  :1s
 * 备注  :
 *******************************************************************************/
void OLED_Rfresh(void)
{
	OLED_ShowString(1, 1, "Distance:");	//1行1列显示字符串Distance:
	OLED_Part_Clear(2,1,16);
	if(MM_ditance < 10)
	{
	    OLED_ShowNum(2,10,MM_ditance,1);	
		OLED_ShowString(2, 12, "MM");	//2行12列显示单位MM
	}
	else if(MM_ditance < 100)
	{
	    OLED_ShowNum(2,10,MM_ditance,2);	
		OLED_ShowString(2, 13, "MM");	//2行13列显示单位MM		
	}
	else if(MM_ditance < 1000)
	{
	    OLED_ShowNum(2,10,MM_ditance,3);	
		OLED_ShowString(2, 14, "MM");	//2行14列显示单位MM		
	}	
}

6.变量定义如下(示例):

/* Defines ------------------------------------------------------------------*/
#define HCSR04_GPIO_RCC    RCC_APB2Periph_GPIOB
#define HCSR04_GPIO_Port   GPIOB
#define Trig_Pin           GPIO_Pin_12
#define Echo_Pin           GPIO_Pin_13//根据实际的引脚修改

#define HCSR04_TIM                TIM1
#define HCSR04_TIM_CLK_ENABLE  	  RCC_APB2Periph_TIM1
#define PERIOD_COUNT              10
#define PRESCALER_COUNT           72
#define HCSR04_TIM_IRQn			  TIM1_UP_IRQn
#define HCSR04_TIM_IRQHandler     TIM1_UP_IRQHandler

#define Overtime                  3800//38ms

uint8_t ditance_flag = 0;//开始测量标志
uint32_t ditance_count = 0;//测量计数 10us/次
uint16_t MM_ditance = 0;//输出测量距离 单位毫米

7.显示结果如下(示例):

图片

本来想录像的,但是一直录不好,有兴趣的自己测试下把。
在这里插入图片描述

串口打印

截取部分,测试内容:我是拿一个黑色本子立起来从近距离到远距离。

在这里插入图片描述


三、总结

超声波测距模块使用起来比较简单,但是发现环境条件对测量结果也存在一定影响,温度湿度我也没考虑进去,多次测量取平均值我也没用,还是存在诸多问题的,后面有时间在改进下,感谢你的观看,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1308095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

verilog基础,连续赋值之组合逻辑

连续赋值语句可以完成任意组合逻辑&#xff0c;本节对基本的逻辑电路进行测试分析&#xff0c;主要包含一下内容&#xff1a; 1. 反相器 2. 与门 3.与非门 4.或门 5.或非门 6.异或门 7.同或门 verilog实现逻辑操作的算符如下 // ~ .... Invert a single-bit signal…

【网络通信原理之套接字】

目录 概念 分类 数据报套接字&#xff1a;使用传输层UDP协议 流套接字&#xff1a;使用传输层TCP协议 原始套接字 Socket编程注意事项 前言&#xff1a;本文主要介绍了在什么是套接字及在Java中套接字是什么&#xff0c;和在套接字编程的注意事项。 概念 Socket套接…

Postman接口测试工具使用

一、前言 在前后端分离开发时&#xff0c;后端工作人员完成系统接口开发后&#xff0c;需要与前端人员对接&#xff0c;测试调试接口&#xff0c;验证接口的正确性可用性。而这要求前端开发进度和后端进度保持基本一致&#xff0c;任何一方的进度跟不上&#xff0c;都无法及…

K8S(四)—pod详解

目录 pod介绍Pod的概念&#xff1a;Pod的特性&#xff1a;Pod的配置&#xff1a;Pod的控制&#xff1a;示例 YAML 文件&#xff1a; pod启动流程问题 两种方式启动镜像的升级和回滚更新 Deployment&#xff1a;回滚检查 Deployment 历史版本回滚到之前的修订版本缩放 Deploymen…

进程概念【linux】

进程基础 在学习进程之前&#xff0c;首先要有一定的计算机硬件和软件基础。 硬件基础&#xff1a;冯诺依曼体系结构 如图&#xff0c;是计算机在硬件上的体系结构。 下面举出一些常见的输入输出设备&#xff08;有些设备只作输出设备&#xff0c;或者只作输入设备&#xff…

基于Leaflet的Webgis经纬网格生成实践

目录 前言 一、Leaflet.Graticule 1、参数说明 二、集成使用 1、新建网页模板 2、初始化地图对象 3、运行效果 三、源码调用分析 1、参数注入 2、经纬网构建 总结 前言 众所周知&#xff0c;在地球仪上或地图上&#xff0c;经线和纬线相互交织&#xff0c;就构成经纬…

复旦微固化流程

生成boot.bin 如图所示&#xff0c;psoc下的create boot image&#xff0c;选择文件配置路径output bif&#xff0c;任意命名 点击右侧add&#xff0c;分别添加三部分 1.编译FSBL工程后SDK\system_platform\FSBL\Debug\Exe路径下的FSBL.out 2.PL侧的bit文件 3.编译工程后SDK\sy…

关于对RF射频方面性能要求各有不同

1.1 射频天线性能 对于一个射频设备每个公司对其合格指标要求都不一&#xff0c;有些公司注重于阻抗及电压驻波&#xff0c;有些公司注重与回波损耗及阻抗、有些只关注电压驻波。 1.2 射频的目的 其实射频天线的目的就是在不把无用的杂散放大超标准的前提下&#xff0c;把有用…

穿梭时光的Java魔法:轻松掌握Date类,揭示当前时间的神秘面纱!

一、实现目标 获取当前时间&#xff01; 二、上代码 import java.text.SimpleDateFormat; import java.util.Date; public class Date_ { // 输出当前的时间 public static void main(String[] arg…

项目总结-自主HTTP实现

终于是写完了&#xff0c;花费了2周时间&#xff0c;一点一点看&#xff0c;还没有扩展&#xff0c;但是基本功能是已经实现了。利用的是Tcp为网络链接&#xff0c;在其上面又写了http的壳。没有使用epoll&#xff0c;多路转接难度比较高&#xff0c;以后有机会再写&#xff0c…

大数据技术8:StarRocks极速全场景MPP数据库

前言&#xff1a;StarRocks原名DorisDB&#xff0c;是新一代极速全场景MPP数据库。StarRocks 是 Apache Doris 的 Fork 版本。StarRocks 连接的多种源。一是通过这个 CDC 或者说通过这个 ETL 的方式去灌到这个 StarRocks 里面&#xff1b;二是还可以去直接的和这些老的 kafka 或…

图的导航-最短路径算法-深度优先遍历

介绍 最短路径&#xff1a;从起点开始访问所有的路径&#xff0c;到达终点的路径有多条&#xff0c;其中路径的权值最短的一条则为最短路径。 最短路径算法有深度优先遍历、广度优先遍历、Bellman-Ford算法、弗洛伊德算法、SPFA算法、迪杰斯特拉算法等。 而本篇讲的是利用深…

TypeScript中的基本类型

提示&#xff1a;TypeScript中的基本类型 文章目录 前言基本类型1.类型声明2.自动类型判断3.类型断言 前言 TypeScript &#xff08;计算机编程语言&#xff09;简称&#xff1a;TS&#xff0c;是 JavaScript 的超集。简单来说就是&#xff1a;JS 有的 TS 都有。JS写的代码在TS…

基于ssm民宿管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本民宿管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

H5 - - - - 移动端禁止长按保存图片

H5 - - - - 移动端禁止长按保存图片 1. 问题描述2. 解决办法2.1 img标签添加css属性2.2 设置为背景图片2.3 图片元素的同级加一个透明盒子 1. 问题描述 H5移动端 img标签长按&#xff0c;会出现如图效果⬇️ 那么该如何修改&#xff0c;能避免长按保存图片操作呢&#xff1f; …

代码随想Day36 | 435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 这道题和前一天的射箭题目思想类似&#xff0c;用总区间个数-不重叠的区间个数等于需要去除的区间个数。首先对左边界排序&#xff0c;如果当前的左边界大于等于上一区间的右边界&#xff0c;则说明是一个不重叠的区间&#xff0c;否则&#xff0c;更新上一重…

Microsoft 发布了 12 月份产品安全问题修复报告。

&#x1f525; Microsoft 发布了 12 月份产品安全问题修复报告。 请注意趋势漏洞 CVE-2023-36011 和 CVE-2023-35632。这些漏洞与 Win32k 内核和负责网络通信的辅助功能驱动程序 (AFD) 驱动程序中的缺陷有关。成功利用这两个漏洞可让进入 Windows 系统的攻击者将其权限提升至系…

NXP应用随记(二):S32K3xx内存随记

目录 1、TCM 1.1、代码放置在ITCM的方式 __attribute__ 的函数属性 __attribute__ 的变量属性 __attribute__ 的类型属性 __attribute__ 的优化控制属性 1.2、DTCM 1.3、TCM的使用注意事项 1、TCM CMTightly Coupled Memory&#xff0c;是一种高速缓存&#xff0c;据说是…

【EI会议征稿】第三届电力系统与电力工程国际学术会议(PSPE 2024)

第三届电力系统与电力工程国际学术会议&#xff08;PSPE 2024&#xff09; 2024 3rd International Conference on Power System and Power Engineering(PSPE 2024) 第三届电力系统与电力工程国际学术会议&#xff08;PSPE 2024&#xff09;于2024年3月29-31日在中国三亚隆重召…

开发案例:使用canvas实现图表系列之折线图

一、功能结构 实现一个公共组件的时候&#xff0c;首先分析一下大概的实现结构以及开发思路&#xff0c;方便我们少走弯路&#xff0c;也可以使组件更加容易拓展&#xff0c;维护性更强。然后我会把功能逐个拆开来讲&#xff0c;这样大家才能学习到更详细的内容。下面简单阐述…