STM32的延時函式,配合系統滴答定時
阿新 • • 發佈:2019-01-09
#include "delay_cfg.h" /////////////////////////////////////////////////////////////////////////////// //////函 數: void Delay_us(UINT32_T us) //////功 能: 微妙的延時函式 //////輸入引數: 延時時間 //////輸出引數: 無 //////說 明: ////////////////////////////////////////////////////////////////////////////// void Delay_us( UINT32_T us ) { DelayN_us( us ); } /////////////////////////////////////////////////////////////////////////////// //////函 數: void Delay_ms(UINT32_T ms) //////功 能: 毫秒的延時函式 //////輸入引數: 延時時間 //////輸出引數: 無 //////說 明: ////////////////////////////////////////////////////////////////////////////// void Delay_ms( UINT32_T ms ) { if (ms!=0) { //---等待延時到達 SysTickTask_WaitDecTick( ms ); } } /////////////////////////////////////////////////////////////////////////////// //////函 數: void Delay_s(UINT32_T ms) //////功 能: 秒延時 //////輸入引數: 延時時間 //////輸出引數: 無 //////說 明: ////////////////////////////////////////////////////////////////////////////// void Delay_s( UINT32_T s ) { if( s != 0 ) { while( s-- ) { Delay_ms( 1000 ); } } } /////////////////////////////////////////////////////////////////////////////// //////函 數: void DelayN_us(UINT32_T us) //////功 能: 查詢的方式,使用系統滴答定時器的作為延時計算 //////輸入引數: 微妙的延時時間 //////輸出引數: 無 //////說 明: ////////////////////////////////////////////////////////////////////////////// void DelayN_us( UINT32_T us ){ if( us != 0 ) { //---系統中斷關閉 CLI(); if (us>6) { //---等待時間的到達 SysTickTask_WaitTimer( us ); } else if (us>1) { //---軟體NOP延時
Delay_nop( ((us-1)*us+1)*( SYS_CLOCK_MHZ - 1 ) );}//---系統中斷開啟SEI();}}/////////////////////////////////////////////////////////////////////////////////////函 數: void DelayN_ms(UINT32_T ms)//////功 能: 查詢的方式,使用系統滴答定時器的作為延時計算//////輸入引數: 毫秒的延時時間
#ifndef DELAY_CFG_H #define DELAY_CFG_H ////////////////////////////////////////////////////////////////////////////////////// //---使用包含的標頭檔案 #include "complier_lib.h" #ifdef USE_MCU_STM32 #include "systick_task.h" #endif //---函式定義 void Delay_us( UINT32_T us ); void Delay_ms( UINT32_T ms ); void Delay_s( UINT32_T s ); void DelayN_us( UINT32_T us ); void DelayN_ms( UINT32_T ms ); void DelayN_s( UINT32_T s ); void Delay_nop( UINT32_T nop ); void Delay_1us( UINT32_T us ); ////////////////////////////////////////////////////////////////////////////////////// #endif /*DELAY_CFG_H */
#ifndef DELAY_CFG_H #define DELAY_CFG_H ////////////////////////////////////////////////////////////////////////////////////// //---使用包含的標頭檔案 #include "complier_lib.h" #ifdef USE_MCU_STM32 #include "systick_task.h" #endif //---函式定義 void Delay_us( UINT32_T us ); void Delay_ms( UINT32_T ms ); void Delay_s( UINT32_T s ); void DelayN_us( UINT32_T us ); void DelayN_ms( UINT32_T ms ); void DelayN_s( UINT32_T s ); void Delay_nop( UINT32_T nop ); void Delay_1us( UINT32_T us ); ////////////////////////////////////////////////////////////////////////////////////// #endif /*DELAY_CFG_H */
#ifndef SYSTICK_CFG_H #define SYSTICK_CFG_H ////////////////////////////////////////////////////////////////////////////////////// //---使用包含的標頭檔案 #include "complier_lib.h" //---變數定義 //---結構體宣告 typedef struct _SysTick_HandlerType SysTick_HandlerType; //---結構體指標的宣告 typedef struct _SysTick_HandlerType *pSysTick_HandlerType; //---定義滴答的計數計數方式 typedef enum { SysTick_1MS_FREQ = 1000U, SysTick_10MS_FREQ = 100U, SysTick_100MS_FREQ = 10U, SysTick_FREQ = SysTick_1MS_FREQ, } SysTickFreqType; //---滴答定時器的結構體 struct _SysTick_HandlerType { VLTUINT32_T msgTickInc; //---定時器遞加計數器 VLTUINT32_T msgTickDec; //---定時器遞減計數器 VLTUINT32_T msgTickOverFlow; //---定時計數器溢位 VLTUINT32_T msgFuncTickTaskInc; //---任務計數器 VLTUINT32_T msgFunTickTaskMaxInc; //---任務計數上限 void (*msgHalTickTask)(void); //---hal庫的計數方式 void (*msgFuncTickTask)(void); //---註冊任務函式 UINT8_T (*msgTask)( SysTick_HandlerType *SysTickHandlerType, UINT8_T msg ); //---任務處理函式 }; //---命令訊息體 #define SysTick_MSG_Init 0 #define SysTick_MSG_DeInit 1 #define SysTick_MSG_IRQTick 2 //---函式定義 UINT8_T SysTick_Init( UINT32_T tickInc, void( *pHalTickInc )( void ) ); UINT8_T SysTick_DeInit( void ); UINT8_T SysTick_TickTask( UINT32_T tickFreq, void( *pLEDTickInc )( void ) ); UINT8_T SysTick_WaitDecTick( UINT32_T waitDecTick ); UINT32_T SysTick_GetTick( void ); UINT8_T SysTick_IRQTick( void ); UINT8_T SysTick_WaitTimer( UINT32_T usTimer ); ////////////////////////////////////////////////////////////////////////////////////// #endif /* SYSTICK_CFG_H */
#include "systick_cfg.h" //---變數定義 SysTick_HandlerType g_SysTick; pSysTick_HandlerType pSysTick = &g_SysTick; extern HAL_TickFreqTypeDef uwTickFreq; /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_Suspend(void) { #ifdef USE_MCU_STM32 //---不使能系統滴答定時器的中斷 SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; #endif return OK_0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_Resume(void) { #ifdef USE_MCU_STM32 //---使能系統滴答定時器的中斷 SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; #endif return OK_0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: 最好1ms的滴答定時器 ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_Init(UINT32_T tickInc, void(*pHalTickInc)(void)) { #ifdef USE_MCU_STM32 //---產生1ms的時間滴答器---該初始化函式沒有註冊中斷 LL_InitTick(SystemCoreClock, tickInc); //---設定中斷搶佔分組 NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); //---配置滴答定時器中斷---設定為最低優先順序 NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); //---使能滴答定時的中斷---預設是1ms SysTick_Resume(); //---hal定時計數器 if ((pHalTickInc!=NULL)&&(pSysTick!=NULL)) { uwTickFreq = HAL_TICK_FREQ_DEFAULT; pSysTick->msgHalTickTask = pHalTickInc; } else { return ERROR_1; } #endif return OK_0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_DeInit(void) { #ifdef USE_MCU_STM32 SysTick_Suspend(); #endif return OK_0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_TickTask(UINT32_T tickFreq, void(*pLEDTickInc)(void)) { if ((pLEDTickInc!=NULL)&&(pSysTick!=NULL)) { //---註冊任務函式 pSysTick->msgFuncTickTask = pLEDTickInc; //---清零任務計數函式 pSysTick->msgFuncTickTaskInc = 0; //---設定任務函式的最大計數上限 pSysTick->msgFunTickTaskMaxInc = tickFreq; } return OK_0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_WaitDecTick(UINT32_T waitDecTick) { if (pSysTick!=NULL) { //---計時函式 pSysTick->msgTickDec = waitDecTick; //---等待時間到達 while (pSysTick->msgTickDec != 0) { WDT_RESET(); } return OK_0; } return ERROR_1; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT32_T SysTick_GetTick(void) { if (pSysTick!=NULL) { return pSysTick->msgTickInc; } return 0; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_IRQTick(void) { if (pSysTick!=NULL) { //---遞加計數 pSysTick->msgTickInc++; pSysTick->msgFuncTickTaskInc++; //---判斷是否溢位 if (pSysTick->msgTickInc==0) { pSysTick->msgTickOverFlow++; } //---註冊hal延時函式 if (pSysTick->msgHalTickTask!=NULL) { pSysTick->msgHalTickTask(); } //---判斷任務函式 if ((pSysTick->msgFunTickTaskMaxInc!=0)&&(pSysTick->msgFunTickTaskMaxInc==pSysTick->msgFuncTickTaskInc)&&(pSysTick->msgFuncTickTask!=NULL)) { pSysTick->msgFuncTickTaskInc = 0; pSysTick->msgFuncTickTask(); } //---遞減計數 if (pSysTick->msgTickDec!=0) { pSysTick->msgTickDec--; } return OK_0; } return ERROR_1; } /////////////////////////////////////////////////////////////////////////////// //////函 數: //////功 能: //////輸入引數: //////輸出引數: //////說 明: ////////////////////////////////////////////////////////////////////////////// UINT8_T SysTick_WaitTimer(UINT32_T usTimer) { #ifdef USE_MCU_STM32 UINT32_T load = SysTick->LOAD; UINT32_T ctrl = SysTick->CTRL; //---關閉定時器,時鐘選擇為系統時鐘,不進行8分頻 SysTick->CTRL = 0x00000004; //---計算裝載值
SysTick->LOAD=usTimer*(SYS_CLOCK_MHZ-1);
//---清零計數器SysTick->VAL = 0x00;//---使能計數器計數SysTick->CTRL |= 0x01;//---等待計數到0while (!(SysTick->CTRL & 0x00010000)){WDT_RESET();}//---關閉定時器,時鐘選擇為系統時鐘,不進行8分頻SysTick->CTRL = 0x00000004;//---恢復裝載值SysTick->LOAD = load;//---清零計數器SysTick->VAL = 0x00;//---恢復計數器配置SysTick->CTRL = ctrl;#endifreturn OK_0;}