1. 程式人生 > >STM32的延時函式,配合系統滴答定時

STM32的延時函式,配合系統滴答定時

#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_ms1000 ); } } } /////////////////////////////////////////////////////////////////////////////// //////函    數: 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)//////功    能: 查詢的方式,使用系統滴答定時器的作為延時計算//////輸入引數: 毫秒的延時時間
//////輸出引數: //////說    明: //////////////////////////////////////////////////////////////////////////////void DelayN_ms( UINT32_T ms ){if( ms != 0 ){while( ms-- ){DelayN_us1000 );WDT_RESET();}}}/////////////////////////////////////////////////////////////////////////////////////函    數: void DelayN_s(UINT32_T s)//////功    能: 查詢的方式,使用系統滴答定時器的作為延時計算//////輸入引數: 秒的延時時間//////輸出引數: //////說    明: //////////////////////////////////////////////////////////////////////////////void DelayN_s( UINT32_T s ){if( s != 0 ){while( s-- ){DelayN_ms1000 );}}}/////////////////////////////////////////////////////////////////////////////////////函    數: void Delay_nop(UINT32_T nop)//////功    能: 系統時鐘的延時//////輸入引數: 系統時鐘延時的個數//////輸出引數: 無//////說    明: //////////////////////////////////////////////////////////////////////////////void Delay_nop( UINT32_T nop ){if( nop != 0 ){while( nop-- ){__asm"NOP" );}}}/////////////////////////////////////////////////////////////////////////////////////函    數: void Delay_1us(UINT32_T us)//////功    能: 使用nop延時函式,進行1us的整數倍的延時時間的計算//////輸入引數: us延時的個數//////輸出引數: 無//////說    明: //////////////////////////////////////////////////////////////////////////////void Delay_1us( UINT32_T us ){UINT32_T i = 0;if( us != 0 ){for( i = 0; i < us; i++ ){Delay_nop( SYS_CLOCK_MHZ - 1 ) );}}}
#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;}