STM32CubeMX之定時器控制微秒延時詳解
阿新 • • 發佈:2019-01-02
寫在前面的話,為什麼另需定時器進行微秒級延時。
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 */
實際波形如下: