概述
? 在使用 DHT11 的時候,時序通信需要微秒來操作,STM32CubeMX 自帶一個系統時鐘,但是實現的是毫秒級別的。因此就自己用通用計時器實現一個。
文章目錄
環境:
- 開發板:STM32F4探索者(正點原子)
1.配置定時器時鐘
- 選擇時鐘源

這里選擇的是內部時鐘,來自 RCC 的TIMxCLK,在通用定時器框圖中我們可以看到如下:

而我們可以在 STM32F4xx中文參考手冊中找到,TIM2 在外設總線1(APB1上),因此其時鐘為 84MHz,如下圖所示:

2.計數器時鐘頻率及計數模式
除了配置定時器的時鐘,還需要配置計數器時鐘頻率,我們要實現微秒延時,因此計數器時鐘頻率應該是1MHz,
而要實現還需要以下3個參數:

- 預分頻系數
根據STM32F4xx中文參考手冊中的時鐘頻率計算,如下圖所示:

其中fCK_PSC就是通用定時器框圖中的CK_PSC, 即值為84MHz,而我們所要的計數器時鐘頻率1MHz
因此:
PSC[15:0] = (fCK_PSC/CK_CNT) - 1 = (84/1) - 1= 83
因此預分頻系數為 83
- 計數器模式
計數器這里采用向下計數模式,也就是 如設置計數值為 1000,那么每隔一個微秒,就減一,一直減到 0
- 自動重裝載值
雖然我們并不使用自動重裝載功能,但是,我們還是要對自動重裝載寄存器進行賦值且不賦值為0即可,但是我測試時發送,如果為1,延時會出現偏差,因此這里賦值為 2,依據如下:

3.打開定時器中斷

4.具體實現代碼
volatile bool elapsed = false; //用于判斷設置的計數值是否耗盡(向下計數模式),耗盡時,在中斷中獎會設置為truevoid setState(bool state)
{elapsed = state;
}bool getState()
{return elapsed;
}void usDelay(uint32_t time)
{__HAL_TIM_SetCounter(&htim2,time); //設置計數值setState(false); HAL_TIM_Base_Start_IT(&htim2); //開啟定時器while(!getState()); //判斷計數值是否耗盡HAL_TIM_Base_Stop_IT(&htim2); //關閉定時器}
計數值耗盡回掉函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM2) {setState(true);}}
5.代碼測試
主函數的主循環中:
while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */printf("hello usDelay");for(int i = 0; i < 1000; i++){usDelay(1000);}}
在串口調試助手中,可以看到如下,一秒打印一條語句

測試代碼已上傳我的博客,歡迎來下載。
后續也將分享如何使用該函數,讀取 DHT11 溫濕度傳感器的值
后續我還會繼續分享STM32CubeMX的相關操作,相信你會學到更多知識,我會在[ STM32CubeMX專欄 ]持續更新,來關注本專欄吧!
文章有幫助到你,點贊,收藏,關注我吧!