1. 程式人生 > >STM32CubeMX之定時器控制微秒延時詳解

STM32CubeMX之定時器控制微秒延時詳解

寫在前面的話,為什麼另需定時器進行微秒級延時。
1.在HAL韌體庫中只有使用Systick作為延時計數器,毫秒級延時HAL_Delay()。為了增加精確的微秒級延時,一般都是更改Systick配置引數,但HAL韌體庫許多地方都使用了HAL_Delay()函式,因此建議大家不要修改系統自動配置的Systick引數;
2.個人覺得到加入作業系統時要佔用Systick,而MCU系統自身的時基還要選擇其他的定時器,綜上所述,對Systick做的更改基本白搭;
因此採用定時器控制微妙延時的方法,是比較靈活的。需要使用者增加的程式碼很少,經濟實用,節能環保- -;
步驟1.配置時鐘
這裡寫圖片描述
注意,一定要確定紅色部分標記的晶振頻率要與實際的晶振保持一致。
步驟2.配置定時器
在配置定時器時,需要明確以下幾點:
1. 定時器時鐘頻率;
2. 定時器溢位頻率;

首先,我們看一下比較重要的暫存器,如下所示:
這裡寫圖片描述
用紅線標記的地方可得:
定時器工作頻率=**經過內部時鐘分頻的**APBx Timer Clock/PSC暫存器的值+1;
舉個栗子,如下:
即定時器的時鐘頻率為84MHz,不用用內部時鐘分頻,要使定時器的工作頻率為1MHz(1us),如下:
1MHz=84MHz/(83+1);

定時器的溢位頻率=定時器的工作頻率/arr

關於arr過載值何時載入,即發生溢位更新事件後,才會載入新值;

相關配置如下:
系統時鐘配置,見上圖;
這裡我使用了TIM14通用定時器來進行1us延時,配置如下:
這裡寫圖片描述

步驟3.編寫程式碼

void delay_us(uint16_t us)
{
    uint16_t differ=0xffff-us-5;
    /*為防止因中斷打斷延時,造成計數錯誤.
     如從0xfffE開始延時1us,但由於中斷打斷
    (此時計數器仍在計數),本因計數至0xffff)
    便停止計數,但由於錯過計數值,並重載arr值,
    導致實際延時(0xffff+1)us
    */

    HAL_TIM_Base_Start(&htim14);

    __HAL_TIM_SetCounter(&htim14,differ);

    while(differ<
0xffff-5) { differ=__HAL_TIM_GetCounter(&htim14); } HAL_TIM_Base_Stop(&htim14); }

因為採用的是向上計數方式,因此需要轉換一下,向下計數方式不用;
測試程式碼如下:

 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
delay_us(5);
 }
 /* USER CODE END 3 */

實際波形如下:
這裡寫圖片描述