每周模块(HC-SR04)

tb6612 发布于 2025-02-04


今天介绍常用的超声波测距模块

1.基本参数

工作电压:DC5V.

工作电流:15mA.

工作频率:40KHz.

射程范围:2cm-4m(最大值).

测量角度:15°.

输入触发信号:10us的ttl脉冲(就是指这个脉冲信号的高电平或低电平状态持续时间为 10 微秒).

输出回响信号:输出ttl电平信号,与射程成比例.

2.工作原理

  1. 触发信号:向模块的 Trig 引脚发送一个至少 10us 的高电平脉冲,触发模块开始工作。
  2. 超声波发射:模块接收到触发信号后,自动发射 8 个 40kHz 的超声波方波。
  3. 等待接收:发射超声波后,模块开始等待反射回来的超声波信号。
  4. 回响信号:当接收到反射波时,模块的 Echo 引脚会输出一个高电平信号,高电平持续的时间就是超声波从发射到接收的时间。
  5. 距离计算:根据公式 距离 = 高电平时间×声速(340m/s)/2 计算出模块与障碍物之间的距离。

3.在stm32f103c8t6中的应用

硬件连接

Vcc--3.3v

Gnd--gnd

trig--PA0

Echo--PA1

相关代码

#include "stm32f10x.h"

void GPIO_Configuration(void)//初始化gpio口
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置Trig引脚(PA0)为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置Echo引脚(PA1)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Trig_Signal(void)//产生触发信号
{
    GPIO_SetBits(GPIOA, GPIO_Pin_0);
    delay_us(20); // 产生20us的高电平触发信号
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}
u32 Get_Echo_Time(void)//测量高电平时间
{
    u32 time = 0;

    // 等待Echo引脚变为高电平
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0);

    // 开始计时
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 1)
    {
        time++;
        delay_us(1);
    }

    return time;
}
float Get_Distance(void)//计算距离
{
    u32 time;
    float distance;

    Trig_Signal();
    time = Get_Echo_Time();

    // 根据公式计算距离
    distance = (float)time * 0.034 / 2; // 声速340m/s,转换为cm/us

    return distance;
}
int main(void)//主函数
{
    float distance;

    GPIO_Configuration();

    while (1)
    {
        distance = Get_Distance();

        // 可以将距离值通过串口等方式输出显示
        // 这里简单通过延时模拟循环测量
        delay_ms(500); 
    }
}

4.代码解释

  1. GPIO 初始化:将 Trig 引脚配置为推挽输出,用于发送触发信号;将 Echo 引脚配置为浮空输入,用于接收回响信号。
  2. 触发信号产生:通过Trig_Signal函数向 Trig 引脚发送一个 20us 的高电平脉冲。
  3. 高电平时间测量Get_Echo_Time函数等待 Echo 引脚变为高电平,然后开始计时,直到 Echo 引脚变为低电平,返回高电平持续的时间。
  4. 距离计算Get_Distance函数调用Trig_SignalGet_Echo_Time函数,根据公式计算出距离。
  5. 主函数:在主函数中循环调用Get_Distance函数,不断测量距离,并通过延时函数控制测量间隔。

5.其他应用

在机器人开发中,可以使用 HC - SR04 超声波模块实现避障功能。通过不断测量机器人与前方障碍物的距离,当距离小于设定的阈值时,机器人自动改变运动方向。

在工业控制和智能家居中,可以将 HC - SR04 超声波模块安装在容器上方,通过测量超声波从发射到液面反射回来的时间,计算出液位高度。

6.结言

通过以上代码和步骤,我们可以在 STM32F103C8T6 上实现 HC - SR04 超声波模块的距离测量功能。在实际应用中,可以根据需要将测量的距离值通过串口、LCD 等方式进行显示,也可以结合其他功能模块实现更复杂的应用。希望本文对你理解和使用 HC - SR04 超声波模块有所帮助。

注意:以上代码中的延时函数是简单 例,实际应用中可能需要根据具体情况进行调整。同时,代码中未包含串口通信等代码,如果需要将距离值输出显示,还需要添加相应的代码。

7.补充

代码中采用软件延时函数,可能会导致误差,可以采用stm32f103c8t6的定时器作延时,

代码如下

#include "stm32f10x.h"

// 定时器初始化
void TIM_Configuration(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 使能TIM2时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // 定时器基本配置
    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
    TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 1us计数周期
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    // 使能定时器更新中断
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    // 配置NVIC
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 使能定时器
    TIM_Cmd(TIM2, ENABLE);
}

// 定时器中断处理函数
void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {
        // 处理定时器溢出情况
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

// 测量高电平时间(使用定时器)
u32 Get_Echo_Time(void)
{
    u32 time;

    // 等待Echo引脚变为高电平
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0);

    // 清零定时器计数器
    TIM_SetCounter(TIM2, 0);

    // 等待Echo引脚变为低电平
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 1);

    // 获取定时器计数值
    time = TIM_GetCounter(TIM2);

    return time;
}

误差修正还可以创建一个多次测量取平均值的函数减小误差,或采用前面提到的ds18b20采集温度

应用公式声速 = 331.4 + 0.6 × 温度 来修正误差

拜拜~

2025.2.4

不告诉你
最后更新于 2025-02-04