前言
鉴于本人之前写过一篇关于STM32F103搭配HCSR04模块实现测距功能的文章,内容不清楚代码相对混乱以及源码未放出,可能对读者造成一定误导,现重新整理了一份,代码相对比较垃圾仅供参考,希望对有需求的提供一点帮助。旧文章链接https://blog.youkuaiyun.com/weixin_44234294/article/details/114147929?spm=1001.2014.3001.5501
HC-SR04超声波测距模块技术详解
HC-SR04是一款广泛应用的超声波测距模块,基于超声波回波时间测量原理实现非接触式距离检测。其低成本、高可靠性、易用性等特点,使其成为机器人避障、液位检测、智能家居等领域的常用传感器。以下是该模块的详细技术信息。
一、模块概述
1. 基本功能
- 测距原理:发射超声波(40kHz),接收回波,通过计算发射与回波的时间差(Time of Flight, ToF)计算距离。
- 测距范围:2cm ~ 400cm(理论值),实际有效范围约2cm ~ 300cm(受环境温度、障碍物材质影响)。
- 分辨率:约0.3cm(依赖定时器精度)。
- 工作电压:5V DC(兼容3.3V逻辑电平)。
- 工作电流:静态<2mA,触发时约15mA。
2. 模块外观与引脚定义
引脚名称 | 功能描述 | 连接方式 |
---|---|---|
VCC | 电源输入(5V) | 接5V电源 |
Trig | 触发信号输入(高电平脉冲) | 接MCU的GPIO(输出) |
Echo | 回响信号输出(高电平脉冲) | 接MCU的GPIO(输入) |
GND | 电源地 | 接GND |
二、工作原理
1. 工作流程
触发信号:
- MCU向Trig引脚发送至少10µs的高电平脉冲。
- HC-SR04收到触发信号后,自动发射8个周期的40kHz超声波。
回波检测:
- 模块内部接收器检测到回波后,Echo引脚输出高电平脉冲,脉冲宽度与超声波往返时间成正比。
- 计算公式
2. 时序图
Trig脉冲:最小10µs,建议10~20µs。
Echo脉冲:最大持续时间约38ms(对应6.5米),实际应用中建议设置超时检测(如30ms)
三、关键参数
1. 电气特性
参数 | 值 |
---|---|
工作电压 | 5V ±0.5V |
工作电流(静态) | <2mA |
工作电流(触发时) | ~15mA |
超声波频率 | 40kHz |
探测角度 | ≤15度(圆锥形) |
2.性能参数
参数 | 值 |
---|---|
最小检测距离 | 2cm |
最大检测距离 | 400cm(理论) |
实际有效距离 | 20cm ~ 300cm |
测量精度 | ±3mm(理想条件) |
响应时间 | <100ms |
代码思路
- 将Trig引脚介入单片机PB8引脚,Echo引脚接入PB9(可自由选择合适引脚),然后配置定时器(可自由选择,本人选择了定时器2);
- 定时器2的配置是关键。要求1MHz频率,即每个计数1微秒,这样计算时间比较方便。需要计算预分频值,系统时钟是72MHz,预分频值应为71,因为72MHz/(71+1)=1MHz。同时,定时器设置为自由运行模式,重装载值0xFFFF,即最大65535,对应65.535ms,足够覆盖HC-SR04的最大测量时间(约23.5ms),所以溢出不是问题。
- 将Trig拉高信号,发出高电平,输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;在此时我们获取当前计数值
T1;当超声波返回被模块接收到时,回波(echo)引
脚端的电平会由1变为0;我们再获取计数值T2,两个时间计数差值T3即为总时间,我们可以带入上面公式进行计算。 - 时间T3的单位是微秒,因为每个计数是1us。所以距离为 (T3 * 340 m/s) /2,但单位要转换。例如,340m/s等于34000cm/s,等于0.034cm/us。所以距离cm = (T3 * 0.034) / 2 = T3 * 0.017 cm。或者也可以写成T3* 17 / 1000 cm,或者T3/ 58.0 cm(因为 1/58 ≈ 0.01724,因为声速在空气中可能取343m/s,这时系数是34300 cm/s = 0.0343 cm/us,所以距离是 (T3 * 0.0343)/2 = T3 *0.01715 ≈ T3 /58.3)。
代码实现
bsp_hcsr04.c
#include "bsp_hcsr04.h"
#include "delay.h"
void HCSR04GpioConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(HCSR04_RCC,ENABLE);
GPIO_InitStructure.GPIO_Pin = HCSR04_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(HCSR04_GPIO_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_GPIO_PORT,HCSR04_TX_PIN);
GPIO_InitStructure.GPIO_Pin = HCSR04_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(HCSR04_GPIO_PORT, &GPIO_InitStructure);
}
void Timer2Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0xffff;
TIM_TimeBaseStructure.TIM_Prescaler = 72 -1 ;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
}
float Hcsr04GetLength(void)
{
uint16_t timeStart = 0;
uint16_t timeEnd = 0;
uint16_t timeLast = 0;
float length = 0;
float sum = 0;
uint16_t i = 0;
while(i != 5)
{
//trig拉高信号,发出高电平
GPIO_SetBits(HCSR04_GPIO_PORT,HCSR04_TX_PIN);
delay_us(20);
GPIO_ResetBits(HCSR04_GPIO_PORT,HCSR04_TX_PIN);
/*Echo发出信号 等待回响信号*/
/*输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;
(此时应该启动定时器计时);当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;
(此时应该停止定时器计数),定时器记下的这个时间即为
超声波由发射到返回的总时长;*/
//echo等待回响
while(GPIO_ReadInputDataBit(HCSR04_GPIO_PORT,HCSR04_RX_PIN) == 0);
//记录放送时间T1
timeStart = TIM2->CNT;
i = i+1; //每收到一次回响信号+1,收到5次就计算均值
while(GPIO_ReadInputDataBit(HCSR04_GPIO_PORT,HCSR04_RX_PIN) == 1);
//记录接收时间T2
timeEnd = TIM2->CNT;
/*获取Echo高电平时间时间T3*/
timeLast = (timeEnd > timeStart) ? (timeEnd - timeStart) : (0xffff - timeStart + timeEnd);
//单位时cm
length = (float)timeLast / 58;
sum += length;
}
length = sum / 5;
return length;
}
void HCSR04Init()
{
HCSR04GpioConfig();
Timer2Init();
}
mian.c
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "bsp_hcsr04.h"
int main(void)
{
delay_init();
HCSR04Init();
uart_init(115200);
while(1)
{
printf("cur dis = %fcm\r\n",Hcsr04GetLength());
delay_ms(1000);
}
}
实验结果
代码有所不足仅供参考,比如超时检测:若Echo信号长时间无下降沿,强制结束测量并标记为无效数据。
链接: https://pan.baidu.com/s/1m_PGSEfQ_RIFdEoxj_jBAQ 提取码: 65kn
有需要其他模块需要测试的可以留言,抽空会实现并写博文,如果对你有帮助的话,一键三连一下,谢谢!