1. 程式人生 > 其它 >STM32驅動HC-SR04 超聲波測距模組(HAL)

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錯誤資料,沒找到原因。