STM32外设系列—HC-SR04(超声波)

这篇具有很好参考价值的文章主要介绍了STM32外设系列—HC-SR04(超声波)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


🎀 文章作者:二土电子

🌸 关注文末公众号获取其他资料和工程文件!

🐸 期待大家一起学习交流!


一、超声波测距基本原理

超声波测距的原理非常简单,超声波发生器在某一时刻发出一个超声波信号,当这个超声波信号遇到被测物体后会反射回来,被超声波接收器接收到。这样只要计算出从发出超声波信号到接收到返回信号所用的时间,就可以计算出超声波发生器与反射物体的距离。

距离的计算公::d=s/2=(c*t)/2

其中 d 为被测物与测距器的距离,s 为声波的来回路程,c 为声波,t 为声波来回所用的时间。

由于超声波也是一种声波,其声速 c 与温度有关,在不同温度下的超声波声速不同。在使用时,如果温度变化不大,则可认为声速是基本不变的。如果测距精度要求很高,则应通过温度补偿的方法加以校正。声速校正后,只要测得超声波往返的时间,即可求得距离。不同外温度下的超声波声速表如下

STM32外设系列—HC-SR04(超声波),STM32开发笔记—外设系列,stm32,嵌入式硬件,单片机

补充说明

最近在问答区发现有小伙伴疑惑为什么在计算距离时是根据Echo输出的高电平持续时间来计算距离。这里简单解释一下,仅供参考

  1. 实际超声波测距的原理就是上面介绍的,记录的时间是从超声波发出到回波被接收的时间,然后这个时间除以2,再乘超声波的传播速度得到距离。超声波测距模块实际也是这么做的。模块内部会记录超声波发出的时刻,在接收到回波后会立刻以高电平的形式从Echo引脚输出高电平,高电平的持续时间就是超声波从发出到被接收到的时间间隔。这么做是模块为了方便单片机处理,快速得到超声波从发出到被接收到的时间间隔。
  2. 实际大家可以自己测试一下,初始化一个定时器,从给Trig引脚10us高电平结束时刻开启定时器,到Echo引脚接收到高电平的时刻停止计时,用这个时间来计算距离,实际和用高电平持续时间来计算距离得到的结果基本是相同的。
  3. 给Trig引脚10us高电平并不是说只发送10us的超声波。10us的高电平是为了触发模块工作。10us高电平结束后,模块会发送一个8个40KHz的方波。

二、超声波传感器简介

总体上讲,超声波发生器可以分为两大类:一类是用电气方式产生超声波类是用机械方式产生超声波。电气方式包括压电型、磁致伸缩型和电动型等:机械方式有加尔统笛、液哨和气流旋笛等。他们所产生的超声波的频率、功率和声波特性各不相同,因而用途也各不相同。目前较为常用的是压电式超声波发生。

压电式超声波发生器实际上是利用压电晶体的谐振来工作的。它有两个压电晶片和一个共振板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片将会发生共振,并带动共振板振动,便产生超声波。反之,如果两极间未外加电压,当共振板接收到超声波时,将压迫压电晶片作振动,将机械能转换为电信号,这时它就成为超声波接收器了。这里介绍的是一个超声波测距模块——HC-SR04。

STM32外设系列—HC-SR04(超声波),STM32开发笔记—外设系列,stm32,嵌入式硬件,单片机

三、HC-SR04测距实现思路

这里就不再针对HC-SR04模块的原理和电路做详细介绍了,直接介绍利用该模块实现测距的思路。该模块有四个引脚。

  • VCC —— 通常是5V供电
  • GND —— 地
  • Trig —— 给该引脚大于10us的高电平,超声波发射头会发送一个超声波信号
  • Echo —— 该引脚在接收到返回的超声波信号后会变为高电平

Echo接收到的高电平持续时间即为超声波一个来回所用的时间,利用该时间除以2再乘上光速,即可得到测量距离。

四、超声波测距程序实现

4.1 HC-SR04初始化程序

HC-SR04初始化程序主要包括两部分,一部分是初始化HC-SR04的GPIO,Trig引脚设置为推挽式输出,Echo引脚设置为浮空输入。另一部分是初始化TIM2。初始化TIM2之后,没有立即使能,而是等到Echo接收到高电平的时刻,开启TIM2。

/*
 *==============================================================================
 *函数名称:Drv_Hcsr04_Init
 *函数功能:初始化HC-SR04
 *输入参数:无
 *返回值:无
 *备  注:初始化HC-SR04引脚的同时,初始化了TIM2,用来记录高电平持续时间
          初始化完TIM2后,没有使能,当Echo收到高电平后使能
 *==============================================================================
 */
void Drv_Hcsr04_Init (void)   // Hc-sr04初始化
{    
	// 结构体定义
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   // 生成用于定时器设置的结构体  
	GPIO_InitTypeDef GPIO_InitStructure;   // GPIO结构体
	NVIC_InitTypeDef NVIC_InitStructure;   // NVIC结构体
	RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);   // 使能GPIO时钟

	// GPIO初始化  
	GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;   // 发送电平引脚  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽式输出  
	GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
	GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);  
		 
	GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO;   // 返回电平引脚  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   // 浮空输入  
	GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);    
	GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);      
		 
	// 定时器初始化 使用基本定时器TIM2  
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   // 使能对应RCC时钟  
	// 配置定时器基础结构体  
	TIM_DeInit(TIM2);  
	TIM_TimeBaseStructure.TIM_Period = (1000-1);   // 设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到1000为1ms ) 
	TIM_TimeBaseStructure.TIM_Prescaler =(72-1);   // 设置用来作为TIMx时钟频率除数的预分频值  1M的计数频率 1US计数  
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;   // 不分频  
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // TIM向上计数模式  
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);   // 根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位         
				
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);   // 清除更新中断,免得一打开中断立即产生中断  
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);   // 打开定时器更新中断  

	// NVIC配置	     
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   // 设置中断优先级分组为组2:2位抢占优先级,2位响应优先级 
		
	NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn;   // 选择定时器2中断  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   // 抢占式中断优先级设置为0  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   // 响应式中断优先级设置为0  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   // 使能中断  
	NVIC_Init(&NVIC_InitStructure);  
	
	TIM_Cmd(TIM2,DISABLE);       
}

4.2 TIM开关程序

/*
 *==============================================================================
 *函数名称:Drv_Hcsr04_OpenTimerForHc
 *函数功能:打开定时器
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void Drv_Hcsr04_OpenTimerForHc (void)   // 打开定时器  
{  
	TIM_SetCounter(TIM2,0);   // 清除计数  
	gMsHcCount = 0;  
	TIM_Cmd(TIM2, ENABLE);   // 使能TIMx外设  
}
/*
 *==============================================================================
 *函数名称:Drv_Hcsr04_CloseTimerForHc
 *函数功能:关闭定时器
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void Drv_Hcsr04_CloseTimerForHc (void)   // 关闭定时器  
{  
	TIM_Cmd(TIM2, DISABLE);   // 使能TIMx外设  
}  

定时器中断服务函数如下

/*
 *==============================================================================
 *函数名称:TIM2_IRQHandler
 *函数功能:定时器2中断服务程序 
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void TIM2_IRQHandler (void)   // TIM2中断  
{  
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)   // 检查TIM2更新中断发生与否  
	{  
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除TIMx更新中断标志   
		gMsHcCount++;  
	}  
}   

4.3 获取定时时间

/*
 *==============================================================================
 *函数名称:Drv_Hcsr04_GetEchoTimer
 *函数功能:获取定时器定时时间 
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
u32 Drv_Hcsr04_GetEchoTimer (void)  
{  
	u32 t = 0;  
	t = gMsHcCount * 1000;   // 得到MS  
	t += TIM_GetCounter(TIM2);   // 得到US  
	TIM2 -> CNT = 0;   // 将TIM2计数寄存器的计数值清零  
	delay_ms(50);
	return t;  
}

4.4 计算测量距离

/*
 *==============================================================================
 *函数名称:Med_Hcsr04_GetLength
 *函数功能:获取测量距离
 *输入参数:无
 *返回值:无
 *备  注:一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
					为了消除余震的影响,取五次数据的平均值进行加权滤波
 *==============================================================================
 */
float Med_Hcsr04_GetLength (void )  
{  
	u32 t = 0;  
	int i = 0;  
	float lengthTemp = 0;  
	float sum = 0;  
	while(i!=5)  
	{  
		TRIG_Send = 1;   // 发送口高电平输出  
		delay_us(20);
		TRIG_Send = 0;  
		while(ECHO_Reci == 0);   // 等待接收口高电平输出  
		Drv_Hcsr04_OpenTimerForHc();   //打开定时器  
		i = i + 1;  
		while(ECHO_Reci == 1);  
		Drv_Hcsr04_CloseTimerForHc();   // 关闭定时器  
		t = Drv_Hcsr04_GetEchoTimer();   // 获取时间,分辨率为1us
		lengthTemp = ((float)t/58.0);   // cm  
		sum = lengthTemp + sum ;        
		}  
	lengthTemp = sum/5.0;  
	return lengthTemp;  
}

4.5 宏定义

#define HCSR04_PORT   GPIOB   // 定义IO口
#define HCSR04_CLK    RCC_APB2Periph_GPIOB   // 开启GPIO时钟  
#define HCSR04_TRIG   GPIO_Pin_8   // 定义Trig对应引脚
#define HCSR04_ECHO   GPIO_Pin_9   // 定义Echo对应引脚
  
#define TRIG_Send  PBout(8)   // 将TRIG_Send映射到PB8
#define ECHO_Reci  PBin(9)   // 将ECHO_Reci映射到PB9

void Drv_Hcsr04_Init(void);   // Hc-sr04初始化
void Drv_Hcsr04_OpenTimerForHc (void);   //打开定时器
void Drv_Hcsr04_CloseTimerForHc (void);   //关闭定时器
u32 Drv_Hcsr04_GetEchoTimer(void);   // 获取定时器时间

五、应用实例

利用串口打印距离信息,main函数如下

float gDistance = 0;   //定义获取返回距离变量

int main(void)
{
	Med_Mcu_Iint();   // 系统初始化
	
	while(1)
  {
		gDistance = Med_Hcsr04_GetLength();   //获取返回距离
	 	printf ("距离为:%.3f cm\n",gDistance);   //串口打印返回距离
		
		delay_ms(500);   //延时500ms = 0.5s
	}
}

六、拓展应用

超声波测距比较常用的,比如利用超声波测距模块实现智能车的自动避障,这个在后续实战项目系列中会有,在此就不再详细介绍了。主要思路就是根据HC-SR04测得的与障碍物的距离,来决定是否要停止或转弯,以及往那边转弯。文章来源地址https://www.toymoban.com/news/detail-699512.html

到了这里,关于STM32外设系列—HC-SR04(超声波)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HC-SR04超声波测距模块使用方法和例程(STM32)

    基于STM32和HC-SR04模块实现超声波测距功能 最近在学STM32做个简单的应用实践一下,顺便水一篇文章。 本文用的单片机是STM32F103C8T6,超声波测距模块是HC-SR04,显示测距结果用的是0.96寸OLED屏模块。 下图中小于10cm时的显示结果有点问题,代码已修复并更新 修复后的结果: 视频

    2024年02月03日
    浏览(19)
  • STM32传感器外设集--超声波模块(HC_SR04)

    目录 1.器件介绍 1.1.参数 1.2.测量范围 1.3.计算公式 1.4.优点 2.1.原理 3.代码编写 3.1.接线图 3.2.代码 3.2.1.HC_SR04.h 3.2.2.HC_SR04.c 3.2.3.timer.h 3.2.4.timer.c  3.2.5.main.c 5根引脚 工作电压5v 工作电流15mA 工作频率40Hz 最近距离 2cm 最远距离 4m 测量角度 15度 测试距离=(高电平时间*声速(340

    2024年02月14日
    浏览(17)
  • 基于STM32的超声波HC-SR04和红外测距模块测量距离的实验对比(HAL库)

            前言: 本文主要是为了 日常普通场合 下测距做的 对比实验 ,本实验主要包含 2种模块 : 超声波测距模块 (HC-SR04)和 红外测距模块 (SHARP GP2Y0A21YK0F)。两种模块不管是测距原理和编程实验方式都是不相同的,其测距效果也存在很大差异。感兴趣的读者朋友,

    2023年04月27日
    浏览(32)
  • 基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距

    一、基于STM32F103C8T6最小系统板和STM32CubeMX实现LED灯循环闪烁 二、基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发 三、实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方 四、基于STM32F103C8T6最小系统板HAL库CubeMX驱动HC-SR501红外人体传感模块 五、基于STM32F103C8

    2023年04月17日
    浏览(38)
  • 基于STM32F103ZET6的(单/三)路HC-SR04超声波测距+TFTLCD实时显示+距离报警

    一、成果图 说明:本程序的源码地址: https://github.com/Lfy-YF/Campus-Project            CSDN下载连接:https://download.csdn.net/download/weixin_58849239/87829470 源码包含四个版本,涉及单路测距、三路测距、增加外部中断(用来版本记录的~) 运行效果: 本程序实现脱机测距,共左中右

    2024年02月11日
    浏览(16)
  • HC-SR04超声波测距模块介绍

    超声波简介       超声波是由机械振动产生的, 可在不同介质中以不同的速度传播, 具有定向性好、能量集中、传输过程中衰减较小、反射能力较强等优点。超声波传感器可广泛应用于非接触式检测方法,它不受光线、被测物颜色等影响, 对恶劣的工作环境具有一定的适应能力

    2023年04月19日
    浏览(22)
  • 【mcuclub】超声波测距模块HC-SR04

      编号 名称 功能 1 VCC 电源正 2 TRIG 触发控制信号输入 3 ECHO 回响信号输出 4 GND 电源地 由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物体测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便

    2023年04月08日
    浏览(17)
  • 树莓派使用HC-SR04超声波测距

      超声波测距原理很简单:   1、通过记录发送超声波的时间、记录超声波返回的时间,返回时间与发送时间相减得到超声波的持续时间。   2、通过公式:( 超声波持续时间 * 声波速度 ) / 2 就可以得出距离;   HC-SR04参数:   工作电压: 5V   工作电流:15mA   

    2024年02月06日
    浏览(19)
  • Linux驱动基础(HC-SR04超声波模块)

    本篇文章将讲解HC-SR04超声波模块的驱动程序编写,有了上篇SR501模块驱动程序编写的基础后这篇文章大家将会学的非常轻松。 HC-SR04超声波模块是一种常用于距离测量和障碍物检测的模块。它通过发射超声波信号并接收回波来计算所测量物体与传感器之间的距离。 HC-SR04超声波

    2024年02月05日
    浏览(18)
  • 硬件速攻-HC-SR04超声波传感器

    ▬▬▬▬▬▶测试模块实验◀▬▬▬▬▬ HC-SR04超声波测距传感器 HC-SR04超声波模块是一种常用的测距传感器,可以通过发射超声波脉冲并接收其回波来测量物体与模块之间的距离。它广泛应用于许多领域,如机器人、无人机、智能车辆等。 XCOM串口实时打印距离 VCC 5V GND GND

    2024年02月12日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包