1、使用SYStick專門的延時。
void delay_us(uint32_t us)
{
static uint32_t delay_flag = 0;
delay_flag = 1;
/* set reload register HCLK = 48M */
SysTick->LOAD = (SYSTEM_CORE_CLOCK / 1000000) * us;
/* Load the SysTick Counter Value */
SysTick->VAL = 0;
/* Enable the Systick Timer */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Systick Timer Timeout*/
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != SysTick_CTRL_COUNTFLAG_Msk)
{
/* if(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk) != SysTick_CTRL_ENABLE_Msk) 讀取CTRL進行判斷將會出錯 */
if(delay_flag == 0)
{
/* Tiemr is disabled */
delay_flag = 1;
/* Enable the Systick Timer */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}
}
/* clear timer */
SysTick->VAL = 0;
/* disable timer */
SysTick->CTRL = 0;
delay_flag = 0;
}
2、使用定時器LPTIM(其他定時器也可),系統中LPTIM定時器2.5ms產生一次中斷,中斷函數裏主時間進行自增g_SystemRAM.Debug.System_Tick += 25;
uint16_t System_GetCntLp(void)
{
uint16_t LptimCnt1 = 0;
uint16_t LptimCnt2 = 0;
uint8_t Cnt = 0;
do
{
LptimCnt1 = LL_LPTIM_GetCounter(LPTIM1);
LptimCnt2 = LL_LPTIM_GetCounter(LPTIM1);
if(LptimCnt1 == LptimCnt2)
{
break;
}
else
{
Cnt ++;
if(Cnt > 5)
{
Cnt = 0;
break;
}
continue;
}
}while(1);
return LptimCnt1;
}
uint32_t System_GetTickLp(void) // 單位 100us
{
float Tick = 0;
uint16_t Cnt = 0;
uint32_t Sys_Tick = g_SystemRAM.Debug.System_Tick;
Cnt = System_GetCntLp() + 1;
if(Sys_Tick != g_SystemRAM.Debug.System_Tick)
{
Sys_Tick = g_SystemRAM.Debug.System_Tick;
Cnt = System_GetCntLp() + 1;
}
Tick = Sys_Tick + 0.3048 * Cnt;
return (uint32_t)Tick;
}
void System_Delay100Us(uint32_t Time)
{
/* 只能在主函數中使用,或在中斷優先級小於LPTIM的中斷回調函數中使用 */
/* 延時等待超過2.5ms時,若是在中斷優先級高於LPTIM的中斷回調函數中使用則將出錯
(LPTIM中斷 無法響應,主時間無法自增,僅計數器運行) */
uint32_t Tick = System_GetTickLp();
while((System_GetTickLp() - Tick) < Time);
}