STM32 延時函數(shù)解析
一、函數(shù)原型
STM32官方提供的函數(shù)庫中,可以找到類似于 HAL_Delay() 這樣的函數(shù)。這個函數(shù)的就是通過使用定時器,達到一個較為精確的時間延遲,提供給用戶調(diào)用。
這個函數(shù)一般包含在類似于 stm32f4xx_hal.c 這樣的函數(shù)中。函數(shù)原型如下:
__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0U;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}
輸入?yún)?shù)為需要延時的時間,單位為毫秒(ms)。其中調(diào)用的 HAL_GetTick() 函數(shù)為獲取計數(shù)值 uwTick,該計數(shù)值在中段服務(wù)函數(shù)中進行加一操作。
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
在中斷服務(wù)函數(shù)如下:
void SysTick_Handler(void)
{
uwTick++;
}
該中斷服務(wù)函數(shù)為系統(tǒng)定時器SysTick的中斷響應(yīng)。而該定時器的初始化函數(shù) HAL_InitTick() 是在 stm32f4xx_hal.c文件里定義,并在 HAL_Init() 函數(shù)中被調(diào)用。
查看其初始化函數(shù) HAl_InitTick() ,內(nèi)容如下:
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/*Configure the SysTick to have interrupt in 1ms time basis*/
HAL_SYSTICK_Config(SystemCoreClock/1000U);
/*Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U);
/* Return function status */
return HAL_OK;
}
這個函數(shù)首先是為該定時器設(shè)置中斷產(chǎn)生的周期,例如當(dāng)前情況下為1ms,也就是沒一毫秒都要產(chǎn)生一次中斷。其次是為該定時器設(shè)置中斷優(yōu)先級。
二、函數(shù)說明
用戶在使用延時時,直接調(diào)用函數(shù) HAl_Delay(time),填入需要延時的時長,單位為毫秒,例如填入5000,則代表延遲5秒,這段時間MCU會產(chǎn)生5000次中斷,進5000次中斷服務(wù)函數(shù)對計數(shù)值進行加一操作。
延時函數(shù)的核心語句為 while循環(huán),如下:
while((HAL_GetTick() - tickstart) < Delay)
{
}
這個函數(shù)在條件滿足時會一直循環(huán),但是由于循環(huán)體為空,所以實際上循環(huán)是不產(chǎn)生任何操作的,直到循環(huán)不滿足,也就是計數(shù)值在不斷加一操作后的值減去開始延遲時值已經(jīng)大于延時值時。此時條件不滿足,循環(huán)結(jié)束,程序繼續(xù)向下執(zhí)行。
關(guān)于上面這個while循環(huán),還可以用采用for循環(huán)寫的版本,如下:
for( ;(HAL_GetTick() - tickstart) < Delay; );
即僅使用for循環(huán)的一個條件,這段代碼等同于如下代碼:
for(;;)
{
if((HAL_GetTick() - tickstart) > Delay)
break;
}
三、更多說明
1、關(guān)于 SysTick 定時器,數(shù)據(jù)手冊的說明如下:
2、關(guān)于for和while循環(huán)的效率說明