HC-SR04超声波模块测距

1. HC-SR04超声波模块

在这里插入图片描述
说明:以下截图均来自HC-SR04用户手册。

1.1 概述

在这里插入图片描述

1.2 性能参数

截图来自HCSR04用户手册

1.3 接口定义

在这里插入图片描述

1.4 模式选择


从用户手册可以知道,HCSR04超声波模块支持多种工作方式,默认工作在GPIO模式。
在这里插入图片描述

2. 编程思路

  • 利用定时器输入捕获功能测量Echo引脚输出的高脉冲信号时间;
  • 接线: HCSR04的Trig引脚连接到STM32F103C8T6 PA0引脚(可以是其他引脚),Echo连接定时器TIM3的通道1(其他定时器均可),对应引脚为PA6;
  • PA0配置为推挽输出;
  • 定时器TIM3配置:IC1映射到TI1,上升沿检测,IC2映射到TI1,下降沿检测,从模式触发选择滤波后的定时器输入1(TI1FP1),复位模式。
    在这里插入图片描述

3. 具体步骤

  • 初始化定时器以及用到的IO口;
  • MCU 给模块 Trig 脚一个大于 10uS 的高电平脉冲;
  • 等待定时器通道2输入捕获事件;
  • 读取CCR2寄存器的值,即为要检测的高脉冲信号时间;
  • 计算距离:距离 = 高电平脉冲信号时间*声速 / 2。

4. 代码实现

4.1 头文件

//tim.h
#ifndef __TIM_H
#define __TIM_H

#include "stm32f1xx_hal.h"

extern TIM_HandleTypeDef htim3;

void TIM3_Init(uint16_t psc, uint16_t arr);
uint8_t TIM3_GetIcFlag(void);
void TIM3_ClearIcFlag(void);

#endif

//hcsr04.h
#ifndef __HCSR04_H
#define __HCSR04_H

#include "stm32f1xx_hal.h"

static void HCSR04_Start(void);

void HCSR04_Init(void);
int HCSR04_GetDistance(float * const dis);

#endif

4.2 源文件

//tim.c
#include "tim.h"

TIM_HandleTypeDef htim3;

/**
  * @brief  TIM3_Init初始化函数
  * @param  psc:预分频值,arr:自动重装载值
  * @retval 无
  */
void TIM3_Init(uint16_t psc, uint16_t arr)
{
   
    TIM_IC_InitTypeDef tim3_ic_chxConfig = {
   0};
    TIM_SlaveConfigTypeDef tim3_slaveConfig = {
   0};
    
    htim3.Instance = TIM3;                                                  //外设基地址
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;                            //向上计数模式
    htim3.Init.Period = arr;                                                //自动重装载值
    htim3.Init.Prescaler = psc;                                             //预分频值
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;                      //不分频
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;         
### 卡尔曼滤波算法用于HC-SR04超声波测距模块 为了提高HC-SR04超声波测距模块的距离测量准确性,可以采用卡尔曼滤波算法处理采集到的数据。该算法能够有效减少噪声干扰并提供更稳定可靠的测量结果。 #### 卡尔曼滤波简介 卡尔曼滤波是一种递推最优估计理论,在线性系统中通过一系列观测数据预测系统的状态向量。其核心在于利用先验信息和当前时刻的观测量更新对下一刻的状态预估值。对于HC-SR04来说,主要关注的是距离这一维度上的变化情况[^2]。 #### 参数设定 在具体实现过程中,需要设置过程噪声协方差矩阵Q以及测量噪声协方差矩阵R。其中R值的选择尤为重要,当R值大于0.5时会对传感器敏感度造成较大影响;因此建议根据实际应用场景调整合适的参数取值范围[^4]。 ```c // 定义变量 float Q_angle = 0.0003; // 过程噪声协方差 float R_measure = 0.39; // 测量噪声协方差 (可根据实际情况调节) double estimate[2]; // 预估位置与速度 double P[2][2]; // 误差协方差阵初始化 double K[2]; // Kalman增益计算结果存储空间 ``` #### 初始化阶段 初始化时需给定初始猜测的位置`estimate[0]`及其对应的不确定性程度即P矩阵中的元素,并设定了两个重要的参数——过程噪声协方差Q和测量噪声协方差R: ```c void kalman_init(void){ int i,j; /* 初始猜测 */ estimate[0]=0; // 假设起始位置为零点 estimate[1]=0; /* 设置初始不确定性的大小 */ for(i=0;i<2;i++) for(j=0;j<2;j++){ if(i==j) P[i][j]=1000; // 较大数值表示较高的不确定性 else P[i][j]=0; } } ``` #### 更新环节 每次接收到新的测量值后都要执行一次预测-校正循环操作,从而不断修正之前的估算值以接近真实值: ```c /* 时间更新(预测)*/ estimate[0]+=dt*estimate[1]; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { temp_P[i][j]=P[i][j]; } } P[0][0]+=(dt*dt)*temp_P[1][1]+Q_angle; /* 测量更新(校正)*/ K[0]=(P[0][0]*R_measure)/(P[0][0]+R_measure); estimate[0]+=K[0]*(measurement-distance); P[0][0]-=K[0]*P[0][0]; ``` 上述代码片段展示了如何在一个简单的单维卡尔曼滤波器框架内完成从初始化到最后一步迭代的过程。需要注意的是这里假设物体静止不动只考虑了位置的变化而忽略了速度因素的影响,如果要构建更加复杂的模型则还需要引入更多物理特性作为输入项参与运算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值