外设模块学习(8)——HC-SR04超声波模块(STM32)

引言

本次学习一款超声波测距模块HC-SR04,学习之前需要具备STM32基础知识以及C语言基础。


一、HC-SR04概述

1.1 是什么

HC-SR04是一款开放式超声波测距 模块,在尺寸上完全兼容老版本 HC-SR04 ,同时新增 UART 和 IIC 功能;默认条件下,软件与硬件均能完全兼容老版本 HC-SR04,还可通过电阻设置切换为 UART 或 IIC 模式,采用升级后的解调芯片 RCWL-9206,搭配带 UART 与 IIC 功能的 MCU,让外围结构更简洁。

1.2 有何作用

HC-SR04超声波测距模块顾名思义,主要用于实现距离测量 ,可在 2cm-450cm(测量平整墙面)的范围内,通过不同工作模式(GPIO、UART、IIC)获取目标物体与模块之间的距离数据,为各类需要距离感知的设备或系统提供精准的距离信息支持。

1.3 有何特点

(1)采用专业解调测距芯片RCWL-9206,性能更稳定可靠。

(2)支持 GPIO、UART 与 IIC 三种模式接口,适配不同的控制需求与硬件环境。

(3)具备3V-5.5V 宽电压供电能力,适用场景更广泛。

(4)工作电流低至 2.2mA,能耗低,续航更持久。

(5)最小盲区仅 2cm,能实现近距离测量,减少测量局限。

(6)测量范围超宽,在平整墙面测量场景下可达 2cm-450cm

(7)外围结构更简洁,便于集成到各类设备中。

(8)工作温度范围较广,塑壳探头(需定制)工作温度为 - 10℃-60℃,铝壳探头为 - 10℃-70℃,能适应不同环境温度。

(9)探测精度较高,在同一温度下精度为 ±2%,理论分辨率达 1mm。

(10)测量周期时间典型值为 200mS,可满足常规测距频率需求。

1.4 应用场景

(1)适用于智能机器人,为机器人提供周围环境的距离信息,辅助其实现避障功能,避免碰撞。

(2)可用于安防系统,如自动感应门,通过测量人体与门的距离,控制门的开启与关闭。

(3)能应用在智能液位监测设备中,测量液体表面与模块的距离,进而推算出液位高度。

(4)可集成到停车辅助系统,帮助驾驶员判断车辆与周围障碍物的距离,提升停车安全性。

(5)适用于各类需要距离检测的 DIY 电子项目,如基于 ARDUINO 、STM32、C51等创意电子制作,为项目提供距离数据支持。


二、相关参数

2.1 重要参数

HC-SR04模块相关参数如下图所示。

在使用这款模块前,务必了解其工作电压电流,避免还没驱动起来就弄坏了,其次关注其能够探测的距离范围等参数。

2.2 引脚定义及功能

HC-SR04超声波测距模块一般有4个管脚,分别对应的VCC、Trig、Echo以及GND,当然现在常见的是新版的,也就是含三种驱动模式的,可能也有的厂商卖的还是旧版的,也就是只有GPIO一种模式控制,也是最简单的一种。

旧版与新版的主要区别在于模块背面包含的芯片数量,旧版这样最普通的GPIO模式,**其只有一块芯片,新版一共三块芯片,**当然如果是GPIO模式的话,两者兼容。

本次我们会以GPIO模式为例,介绍其驱动方法,关于该模块的引脚定义与功能说明如下图所示。

默认情况下,超声波测距模块的驱动模式即GPIO模式。


三、工作原理

HC-SR04(2020 款)超声波测距模块通过不同工作模式实现距离测量,下面分别简单介绍不同模式的驱动原理。

3.1 GPIO 模式

该模式工作方式与老版本 HC-SR04 一致。该模式下的时序图如下图所示。

该时序比较简单,大致流程如下:

(1)触发信号(Trig):外部 MCU 向模块的 Trig 引脚发送一个大于 10μS 的高电平脉冲;

(2)内部驱动:模块接收到触发信号后,内部会循环发出 8 个 40KHz 的脉冲作为驱动信号;

(3)反馈信号(Echo):该模块会通过Echo引脚对外输出一个与测量距离成比例的高电平脉冲信号。

需要注意的是,每次触发信号发出的间隔时间不得少于200ms。

通过测量该 Echo 信号的脉宽时间 "T",结合声速即可计算出距离 ,计算公式为:距离 = T * C / 2 (其中 C 为声速)。声速会受温度影响,声速与温度的关系公式为:(331.45 为 0℃时的声速),实际应用中若需精确距离值,需考虑温度影响并进行温度补偿。

3.2 UART 模式

该模式下,具体操作 如下**:**

(1)**波特率设置:**UART 模式的波特率固定设置为 9600。

(2)**起始命令:**外部 MCU 或 PC 向模块发送 0XA0 命令,模块接收到命令后完成测距操作。

(3)**接收数据:**测距完成后,模块会发送 3 个距离数据,分别为 BYTE_H、BYTE_M 与 BYTE_L。

(4)**数据转换:**距离计算方式为(单位:mm):距离 = ((BYTE_H<<16)+(BYTE_M<<8)+ BYTE_L) / 1000。

3.3 IIC 模式

该模块在 IIC 模式下的从机地址为 0X57。

3.3.1 数据传输格式

(1)**写数据传输格式:**起始信号(S)→从设备地址 + 写(W)→应答(ACK)→数据→应答(ACK)→...(N 字节数据及对应应答)→停止信号(P)。


(2)**读数据传输格式:**起始信号(S)→从设备地址 + 读(R)→应答(ACK)→数据→应答(ACK)→...(N-1 字节数据及对应应答)→数据→非应答(NAK)→停止信号(P)。

3.3.2 地址及命令

(1)**启动测距:**向模块的写地址 0XAE 写入 0X01 命令,模块开始测距;

(2)**读取数据:**等待 200mS(模块最大测距时间)以上,再从读地址 0XAF 读取 3 个距离数据,即 BYTE_H、BYTE_M 与 BYTE_L。

距离计算方式为(单位:mm):


四、注意事项

(1)此模块不宜带电连接 ,如果要带电连接,则先让模块的Gnd端先连接

(2)如果测试面不是很规则或测试远距离物体时,可采用多次测量的方法来校正

(3)两次测试间隔要不小于200mS。


五、参考代码(STM32)

有上述原理介绍可知逻辑是很简单的,下面以默认GPIO模式为例 ,给出参考代码,该代码是基于STM32F103系列单片机,寄存器方式编写的。

5.1 ultrasound.h

cpp 复制代码
/*
 * @Descripttion: HC-SR04超声波模块驱动文件(.h)
 * @Author: JaRyon
 * @version: 
 * @Date: 2025-10-27 19:48:01
 */
#ifndef __ULTRASOUND_H
#define __ULTRASOUND_H

#include "stm32f10x.h"
#include "Delay.h"

/**
 * 超声波模块引脚连接
 * 
 * VCC   --->  3.3/5V
 * Trig  --->  PA0 --- 产生触发信号
 * Echo  --->  PA1 --- 接收反馈信号
 * GND   --->  GND
 * 
*/

// Trig拉高拉低
#define TRIG_HIGH   (GPIOA->ODR |= GPIO_ODR_ODR0)
#define TRIG_LOW   (GPIOA->ODR &= ~GPIO_ODR_ODR0)
// 反馈信号读取
#define ECHO_READ   (GPIOA->IDR & GPIO_IDR_IDR1)

void Ultrasound_Init(void);
double Ultrasound_GetDist(void);

#endif

5.2 ultrasound.c

cpp 复制代码
/*
 * @Descripttion: HC-SR04超声波模块驱动文件(.c)
 * @Author: JaRyon
 * @version:
 * @Date: 2025-10-27 19:47:38
 */
#include "ultrasound.h"

/**
 * @brief      超声波模块初始化
 * @param      void 无
 * @return     void
 * @example    Ultrasound_Init();
 * @attention  Echo引脚由模块产生信号,MCU接收;Trig引脚由MCU发出信号,模块接收
 */
void Ultrasound_Init(void)
{
    // 开启时钟 PA
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    // trig-PA0 推挽输出 echo-PA1 浮空输入
    GPIOA->CRL |= GPIO_CRL_MODE0;
    GPIOA->CRL &= ~GPIO_CRL_CNF0;

    GPIOA->CRL &= ~GPIO_CRL_MODE1;
    GPIOA->CRL |= GPIO_CRL_CNF1_0;
    GPIOA->CRL &= ~GPIO_CRL_CNF1_1;

    // 初始触发信号置低
    TRIG_LOW;
}

/**
 * @brief      超声波模块收发处理
 * @param      void 无
 * @return     uint16_t
 * @example    uint16_t distance = Ultrasound_Process();
 * @attention  内部调用,不向外展示
 */
static uint32_t Ultrasound_Process(void)
{
    uint32_t count = 0, startTime = 0;

    // ----- GPIO模式下 ------

    // 1. Trig拉高10us,触发模块
    TRIG_HIGH;
    Delay_us(10);
    TRIG_LOW;

    // 2. 等待ehco拉高
    startTime = Systick_GetTick();

    while (ECHO_READ == 0)
    {
        if (Systick_GetTick() - startTime >= 50000)
        {
            return 0;
        }
    }

    // 3. 计时
    count = Systick_GetTick();
    while (ECHO_READ != 0)
    {
        if (Systick_GetTick() - count >= 50000)
        {
            return 0;
        }
    }
    count = Systick_GetTick() - count;

    // 4. 延时维持足够触发间隔
    Delay_ms(200);

    return count;
}

/**
 * @brief      获取超声波测得距离换算
 * @param      void 无
 * @return     uint16_t
 * @example    Distance = Ultrasound_GetDist();
 * @attention  距离单位cm
 */
double Ultrasound_GetDist(void)
{
    uint32_t count = Ultrasound_Process();

    double distance = (count * 0.034) / 2;

    return distance;
}

5.3 main.c

cpp 复制代码
/*
 * @Descripttion: 超声波测距测试
 * @Author: JaRyon
 * @version: v1.0
 * @Date: 2025-10-25 23:09:53
 */
#include "stm32f10x.h"
#include "Systick.h"
#include "oled.h"
#include "ultrasound.h"

void LED_Init(void);

int main(void)
{
	uint32_t waitTime = 0;
	double distance = 0.0;
	// 初始化
	Systick_Init();
	OLED_Init();
	OLED_ClearAll();
	Ultrasound_Init();
	distance = Ultrasound_GetDist();

	waitTime = Systick_GetTick();
	while (1)
	{
		
		if (Systick_GetTick() - waitTime > 500000)
		{
			distance = Ultrasound_GetDist();
			waitTime = Systick_GetTick();
		}

		OLED_ShowFloat(5, 2, distance, 3, 1, 8);

		OLED_Update();
	}
}

**注:**这里给出的是控制HC-SR04模块的核心代码,主函数中涉及到的oled以及延时等不是重点,所以不再赘述。当然大家如果没有OLED 屏幕,完全可以使用串口等显示测得距离。


六、总结

本次,我们详细介绍了HC-SR04超声波测距模块的特性与应用。该模块支持GPIO、UART和IIC三种工作模式,测量范围2cm-450cm,具有低功耗、高精度等特点。工作原理方面,重点说明了GPIO模式下通过Trig触发信号和Echo接收信号实现测距的时序流程,并提供了距离计算公式。最后给出了基于STM32的参考代码实现,包括初始化配置和距离测量函数。


以上便是本次文章的所有内容,欢迎各位朋友在评论区讨论,本人也是一名初学小白,愿大家共同努力,一起进步吧!

鉴于笔者能力有限,难免出现一些纰漏和不足,望大家在评论区批评指正,谢谢!

相关推荐
LBuffer3 小时前
破解入门学习笔记题三十八
笔记·学习
微露清风3 小时前
系统性学习C++-第十讲-stack 和 quene
java·c++·学习
PyAIGCMaster3 小时前
钉钉的设计理念方面,我可以学习
人工智能·深度学习·学习·钉钉
Elias不吃糖4 小时前
第四天学习总结:C++ 文件系统 × Linux 自动化 × Makefile 工程化
linux·c++·学习
雍凉明月夜4 小时前
人工智能学习中深度学习之python基础之 类
python·学习
王同学要变强4 小时前
【深入学习Vue丨第二篇】构建动态Web应用的基础
前端·vue.js·学习
好奇龙猫4 小时前
日语学习-日语知识点小记-构建基础-JLPT-N3阶段-二阶段(14):文法和单词-第三课
学习
仰望—星空5 小时前
MiniEngine学习笔记 : DescriptorHeap
windows·笔记·学习
武昌库里写JAVA5 小时前
element-ui 2.x 及 vxe-table 2.x 使用 css 定制主题
java·vue.js·spring boot·sql·学习