单片机:实现HC-SR04超声波测距(附带源码)

使用单片机实现 HC-SR04 超声波测距模块 的功能,通常用于测量物体与超声波传感器之间的距离。HC-SR04 模块通过发射超声波信号并测量其返回时间来计算距离。单片机(如 STM32、51 系列、Arduino 等)可用来控制该模块的工作,并处理返回的脉冲信号。

下面我会提供一个基于单片机的 HC-SR04 超声波测距实现方案,并详细阐述每个步骤的设计思路和代码实现。

1. HC-SR04 超声波模块工作原理

HC-SR04 模块通过发送一系列声波脉冲来测量与目标物体的距离。模块由两部分组成:

  • 发射部分(Trigger):用来发送 10 微秒的脉冲,激发超声波信号的发送。
  • 接收部分(Echo):接收从目标物体反射回来的超声波脉冲,产生一个持续高电平的信号,持续时间等于声波往返的时间。
计算公式:

距离 = (回波时间 × 声速) / 2

  • 声速约为 340 m/s(即 0.034 cm/μs),所以计算的公式为:

    上式中,回波时间指的是从发送脉冲到接收到返回信号的时间。

2. 硬件连接

HC-SR04 模块有四个引脚:

  • VCC:电源(通常为 5V)
  • GND:地线
  • Trig:触发引脚(用于发射超声波脉冲)
  • Echo:回声引脚(接收返回的超声波脉冲)

单片机的引脚连接方式:

  • Trig:连接到单片机的一个 GPIO 引脚,用于触发超声波发射。
  • Echo:连接到单片机的另一个 GPIO 引脚,用于接收回声信号。

3. 设计思路

本设计采用单片机控制 HC-SR04 模块,通过控制 Trig 引脚生成超声波触发脉冲,并通过 Echo 引脚测量回波信号的持续时间。具体的步骤包括:

  1. 触发超声波信号 :通过向 Trig 引脚输出一个 10 微秒的高电平脉冲,激发 HC-SR04 发射超声波。
  2. 测量回波时间 :通过读取 Echo 引脚的高电平持续时间来计算回波时间。单片机根据此时间计算距离。
  3. 计算距离:根据回波时间和声速公式计算物体到传感器的距离。

4. 软件设计

以 STM32 微控制器为例,介绍如何实现该功能。可以使用 STM32 的 HAL 库来实现超声波测距。

4.1 初始化 GPIO

首先需要初始化 GPIO 引脚:

  • Trig 引脚配置为输出模式,用于发射触发脉冲。
  • Echo 引脚配置为输入模式,用于接收回波信号。
cpp 复制代码
#include "stm32f4xx_hal.h"
#include <stdio.h>

#define TRIG_PIN        GPIO_PIN_0   // Trig 引脚
#define ECHO_PIN        GPIO_PIN_1   // Echo 引脚
#define GPIO_PORT       GPIOA        // 假设使用 GPIOA 端口

void SystemClock_Config(void);
void GPIO_Init(void);
void trigger_ultrasonic_pulse(void);
uint32_t read_echo_pulse(void);
float calculate_distance(uint32_t pulse_width);

int main(void)
{
    HAL_Init();  // 初始化 HAL 库
    SystemClock_Config();  // 配置系统时钟
    GPIO_Init();  // 初始化 GPIO 引脚

    while (1)
    {
        trigger_ultrasonic_pulse();  // 触发超声波信号
        uint32_t pulse_time = read_echo_pulse();  // 获取回波时间
        float distance = calculate_distance(pulse_time);  // 计算距离

        // 可以通过串口输出距离值,或者在 LCD 上显示
        printf("Distance: %.2f cm\n", distance);

        HAL_Delay(500);  // 每 500 毫秒测量一次
    }
}

// 系统时钟配置函数(根据具体硬件配置)
void SystemClock_Config(void)
{
    // 这里可以根据需要配置时钟,一般不需要修改
}

// GPIO 初始化:配置 Trig 为输出,Echo 为输入
void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 启用 GPIO 时钟
    __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_LOW;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);

    // 初始化 Echo 引脚(输入)
    GPIO_InitStruct.Pin = ECHO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);
}

// 触发超声波信号:生成 10 微秒的脉冲
void trigger_ultrasonic_pulse(void)
{
    HAL_GPIO_WritePin(GPIO_PORT, TRIG_PIN, GPIO_PIN_SET);  // Trig 引脚置高
    HAL_Delay(0);  // 保持高电平至少 10 微秒
    HAL_GPIO_WritePin(GPIO_PORT, TRIG_PIN, GPIO_PIN_RESET);  // Trig 引脚置低
}

// 读取 Echo 引脚的高电平持续时间(脉冲宽度)
uint32_t read_echo_pulse(void)
{
    uint32_t pulse_width = 0;
    
    // 等待 Echo 引脚为高电平
    while (HAL_GPIO_ReadPin(GPIO_PORT, ECHO_PIN) == GPIO_PIN_RESET);

    // 计数 Echo 引脚高电平的持续时间
    while (HAL_GPIO_ReadPin(GPIO_PORT, ECHO_PIN) == GPIO_PIN_SET)
    {
        pulse_width++;  // 每次延时 1 毫秒
        HAL_Delay(1);   // 延时 1 毫秒,计数单位是毫秒
    }

    return pulse_width;  // 返回脉冲宽度(单位:毫秒)
}

// 根据回波时间计算距离(单位:cm)
float calculate_distance(uint32_t pulse_width)
{
    // 使用公式:距离 (cm) = (回波时间 (微秒) * 0.034) / 2
    // 由于我们在 read_echo_pulse 函数中每次延时 1 毫秒,pulse_width 其实已经是毫秒单位。
    float distance = pulse_width * 0.034 / 2.0;  // 公式:距离 = 时间 * 声速 / 2
    return distance;
}

代码解读

  1. 初始化 GPIO

    • GPIO_Init() 函数初始化了两个 GPIO 引脚:
      • Trig 引脚(GPIO_PIN_0):用于触发超声波发射,配置为推挽输出模式。
      • Echo 引脚(GPIO_PIN_1):用于接收超声波回波信号,配置为输入模式。
  2. 触发超声波发射信号

    • trigger_ultrasonic_pulse() 函数通过在 Trig 引脚输出一个 10 微秒的高电平脉冲来激发 HC-SR04 模块发射超声波信号。
  3. 测量回波时间

    • read_echo_pulse() 函数通过读取 Echo 引脚的高电平持续时间来获取回波信号的时长。通过 pulse_width 计数,记录回波信号持续的时间。
  4. 计算距离

    • calculate_distance() 函数根据回波信号的时长(pulse_width)和声速公式来计算物体与传感器的距离:
      *
      \text{距离 (cm)} = \frac{\text{回波时间 (毫秒)} \times 0.034}{2} ] 其中,0.034 为声速(单位:cm/μs)。
  5. 主循环

    • main() 函数中,程序会不断触发超声波信号,并读取回波时间,通过计算得到距离,最后打印出距离值。每次测量之间有 500 毫秒的延时。

5. 项目总结

5.1 硬件总结
  1. HC-SR04 超声波模块 :通过发射和接收超声波信号来测量距离,连接到单片机的 GPIO 引脚(TrigEcho)。
  2. 单片机 :负责控制 Trig 引脚生成脉冲,并读取 Echo 引脚的高电平持续时间,计算并输出距离。
5.2 软件总结
  1. GPIO 初始化 :配置 Trig 为输出,Echo 为输入。
  2. 触发超声波信号 :通过给 Trig 引脚发送 10 微秒的高电平脉冲来激发 HC-SR04 发射超声波。
  3. 回波时间测量 :通过读取 Echo 引脚的高电平持续时间,计算超声波往返所需的时间。
  4. 距离计算:根据回波时间和声速公式计算距离,并输出测量结果。
5.3 优化与扩展
  1. 更高精度:为了获得更高精度的距离,可以增加计时的精度(例如,使用定时器或更高分辨率的计时方法)。
  2. 多次测量平均值:可以通过多次测量距离并取平均值来提高测量的稳定性和精度。
  3. 串口输出:通过串口将测量的距离数据发送到 PC 或其他设备进行显示。
  4. 电源管理:对于电池供电的系统,可以在不需要测量时关闭超声波模块,以节省电量。

通过以上设计,我们成功实现了使用单片机控制 HC-SR04 超声波模块进行测距的功能,并能够在不同的应用场景下测量距离。

相关推荐
智商偏低1 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen2 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森4 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白4 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D5 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术8 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt8 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘8 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang8 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n11 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件