单片机:实现驱动HC-SR04超声波模块
1. 项目背景与目标
HC-SR04超声波模块是一种常见的距离传感器,通过发射超声波并测量回波信号的时间差来计算距离。它通常用于机器人避障、液位检测、物体计数等应用中。本项目的目标是基于STM32单片机控制HC-SR04模块,通过超声波发射和接收来测量距离。
2. 硬件设计
2.1 硬件组件
- 单片机:如STM32系列单片机,本项目假设使用STM32。
- HC-SR04超声波模块:包括触发(Trigger)引脚和回波(Echo)引脚,用于发送和接收超声波信号。
- 外部电源:为单片机和HC-SR04模块提供电源(通常为5V电源)。
- 电阻:可以使用电阻分压将5V电平转换为3.3V,以适应STM32的GPIO输入电平。
2.2 硬件连接
- HC-SR04模块引脚:
- VCC:连接5V电源。
- GND:连接地。
- Trig:连接STM32的GPIO引脚(例如PA0),用于触发超声波发射。
- Echo:连接STM32的GPIO引脚(例如PA1),用于接收回波信号。
注:由于STM32的GPIO引脚是3.3V,而HC-SR04模块的Echo引脚工作电平是5V,因此需要在Echo引脚和STM32之间添加一个电阻分压电路,降低电平至3.3V,防止损坏单片机。
3. 软件设计
3.1 超声波测距原理
HC-SR04模块通过发射超声波并接收回波信号来计算距离。计算公式如下:
距离=回波时间×声速2\text{距离} = \frac{\text{回波时间} \times \text{声速}}{2}距离=2回波时间×声速
- 回波时间:超声波从发射到接收所需的时间。
- 声速:在标准条件下(20℃,海平面)声速约为343米/秒,1秒钟内声波传播的距离约为343米,即34300厘米。
3.2 时序图
- 触发信号:通过设置Trig引脚高电平持续10us,触发超声波模块发射超声波。
- 回波信号:Echo引脚会输出一个高电平脉冲,其持续时间等于超声波传播的时间。通过测量Echo引脚的高电平持续时间,可以计算出超声波传播的时间,从而得到距离。
3.3 程序设计思路
- 初始化GPIO引脚:初始化Trig和Echo引脚,Trig作为输出,Echo作为输入。
- 触发超声波发射:通过设置Trig引脚为高电平10us,触发超声波模块发射超声波。
- 测量回波时间:通过测量Echo引脚从低电平到高电平的时间,得到超声波传播的时间,进而计算出距离。
- 数据转换与显示:根据回波时间计算距离,并通过串口输出显示或控制其他外设(如LED等)。
3.4 代码实现
以下是基于STM32单片机实现HC-SR04超声波模块的代码示例:
#include "stm32f4xx_hal.h"
// 定义Trig和Echo引脚
#define TRIG_PIN GPIO_PIN_0
#define TRIG_PORT GPIOA
#define ECHO_PIN GPIO_PIN_1
#define ECHO_PORT GPIOA
// 声速常量(单位:厘米/微秒)
#define SOUND_SPEED 0.0343
// 初始化GPIO
void GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 初始化Trig引脚(输出)
GPIO_InitStruct.Pin = TRIG_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
// 初始化Echo引脚(输入)
GPIO_InitStruct.Pin = ECHO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
}
// 触发超声波发射
void Trigger_Ultrasonic(void) {
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET); // 设置Trig引脚高电平
HAL_Delay(0.01); // 保持10us
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET); // 设置Trig引脚低电平
}
// 测量回波时间并计算距离
float Measure_Distance(void) {
uint32_t start_time = 0, end_time = 0;
float distance = 0.0f;
// 触发超声波发射
Trigger_Ultrasonic();
// 等待Echo引脚变为高电平
while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET);
// 记录Echo引脚高电平开始时间
start_time = HAL_GetTick();
// 等待Echo引脚变为低电平
while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_SET);
// 记录Echo引脚高电平结束时间
end_time = HAL_GetTick();
// 计算回波时间(单位:微秒)
uint32_t pulse_time = end_time - start_time;
// 计算距离(单位:厘米)
distance = pulse_time * SOUND_SPEED / 2.0f;
return distance;
}
int main(void) {
HAL_Init(); // 初始化HAL库
// 初始化GPIO
GPIO_Init();
while (1) {
// 测量距离
float distance = Measure_Distance();
// 输出距离到串口(假设已初始化串口)
printf("Distance: %.2f cm\n", distance);
HAL_Delay(500); // 每500ms测量一次距离
}
}
3.5 代码解释
-
GPIO初始化:
GPIO_Init()
函数用于初始化Trig和Echo引脚。Trig引脚为输出模式,用于触发超声波发射;Echo引脚为输入模式,用于接收回波信号。
-
超声波发射:
Trigger_Ultrasonic()
函数将Trig引脚设置为高电平,保持10微秒,然后将Trig引脚设置为低电平,从而触发超声波模块发射超声波。
-
距离测量:
Measure_Distance()
函数通过测量Echo引脚的高电平持续时间来计算回波时间。通过将回波时间转换为距离,得到测量的距离值。计算公式为:- 其中0.0343是声速(单位:厘米/微秒)。
-
输出结果:
- 在主循环中,调用
Measure_Distance()
函数获取测量的距离,并通过串口输出显示。HAL_Delay()
用于设置测量的间隔时间。
- 在主循环中,调用
4. 总结
本项目通过STM32单片机驱动HC-SR04超声波模块实现了简单的距离测量功能。通过触发超声波发射并测量回波信号的时间差,成功计算出超声波传播的距离。该项目适用于需要进行距离检测的应用,如障碍物检测、液位测量等。在实际应用中,可以根据需要增加滤波和校准功能,提高测量的精度与稳定性。