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