STM32驱动HC-SR04 超声波测距模块(HAL)

 输入捕获主要参考这位大佬

链接:https://blog.csdn.net/as480133937/article/details/99407485

一、HC-SR04简单介绍

HC-SR04超声波模块常用于机器人避障、物体测距、液位检测、公共安防、停车场检测等场所。HC-SR04超声波模块主要是由两个通用的压电陶瓷超声传感器,并加外围信号处理电路构成的.

实物图:

 

接口定义:

序号 接口定义 说明
1 Vcc 供电电源
2 Trig 触发信号
3 Echo 反馈信号
4 Gnd

新版的HC-SR04增加UART和IIC功能,但我是老版的的,只有GPIO模式。

GPIO模式:

 

 外部单片机给模块Trig脚一个大于10 US的高电平脉冲;模块Echo脚会给出一个与距离等比的高电平脉冲信
号,可根据脉宽时间“T”算出:
距离=T*C/2(C为声速)
声速温度公式:c= (331.45+0.61t  /°C) m/s(其中330.45是在0°C)
0°C声速:330.45M/S
20°C声速:342.62M/S
40°C声速:354.85M/S
0°C-40℃声速误差7%左右。实际应用,如果需要箱确距离值,必需要考虑温度影响.做温度补偿.

二 、STM32CubeMX设置

定时器1通道1开启输入捕获

 

PSC=71、重装值 :0xffff (65535)

 

 上升沿触发

开启中断

 再开启一个串口用来发送距离

 

三、代码

一些变量

/* USER CODE BEGIN PM */
uint32_t capture_Buf[3] = {0};   //存放计数值
uint8_t capture_Cnt = 0;    //状态标志位
uint32_t high_time;   //高电平时间
float    distance;   //距离
/* USER CODE END PM */

串口重定向

复制代码
/* USER CODE BEGIN 0 */
void Usart3Printf(const char *format, ...)
{

 uint8_t UartTxBuf[100];
 uint16_t len;
 va_list args;
 va_start(args, format);
 len = vsnprintf((char*) UartTxBuf, sizeof(UartTxBuf) , (char*) format,args);
 va_end(args);
 HAL_UART_Transmit(&huart3, UartTxBuf, len,1000);
}
/* USER CODE END 0 */
复制代码

 

 全部的函数

复制代码
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      switch (capture_Cnt){
      case 0:
        SR04_Start();
         capture_Cnt++;
        __HAL_TIM_SET_CAPTUREPOLARITY(&htim1, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
        HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);    //启动输入捕获       或者: __HAL_TIM_ENABLE(&htim1);
        break;
        
      case 3:
        high_time = capture_Buf[1]- capture_Buf[0];    //高电平时间
        distance = (high_time / 1000000.0) * 340.0 / 2.0 * 100.0;
        Usart3Printf("%.2f cm\n",distance)    ;
        
        HAL_Delay(1000);   //延时1S
        capture_Cnt = 0;  //清空标志位        
        break;
                
    }

    /* USER CODE END WHILE */
复制代码

 

复制代码
/* USER CODE BEGIN 4 */

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    
    if(htim->Instance==TIM1)
    {
          switch(capture_Cnt){
            case 1:
            capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);//获取当前的捕获值.
            __HAL_TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
            capture_Cnt++;
            break;
            case 2:
            capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);//获取当前的捕获值.
            HAL_TIM_IC_Stop_IT(&htim1,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim1);
            capture_Cnt++;    
        }
    
    }
    
}

/* USER CODE END 4 */
复制代码

 

具体流程:

1.设置TIM1 CH1为输入捕获功能;

2.设置上升沿捕获;

3.使能TIM1 CH1捕获功能;

4.捕获到上升沿后,定时器当前计数值存入capture_buf[0],改为捕获下降沿;

5.捕获到下降沿后,定时器当前计数值存入存入capture_buf[1],关闭TIM2 CH1捕获功能; capture_Cnt=3;

6. 高电平时间: capture_buf[1] - capture_buf[0]   计算  distance = (high_time / 1000000.0) * 340.0 / 2.0 * 100.0;  发送到上位机 重新启动输入捕获

四、串口显示

 

可以测量距离,有时会出现73013376.00 cm错误数据,没找到原因。

 

 


 

 

posted @   Yoku  阅读(1813)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示