可便携移植的定时应用代码分享
在本文可以学到一个可任意移植而无需做过多修改就可以使用的定时器应用代码
框架结构:
这里罗列应用代码的框架结构:
如下:
1、 初始化定时器
2、 基于高优先级的定时基准
3、 基于低优先级的定时基准
4、 启动或者停止定时器的命令函数
5、定时器中断处理函数
需要用到的变量以及结构体的定义:
需要定义的宏以及变量还有结构体罗列
如下:
1、 定时器缓冲区的最大最小值
2、 定时器的设置命令分类
3、 定时器启动命令分类
4、定时器结构体的定义
变量定义部分的代码
宏定义:定义了定时器缓冲区最大的设置值
#define MC_TIMER_MAX_NUM_HIGH 10
#define MC_TIMER_MAX_NUM_LOW 12
定时器的设置命令分类:
typedef enum _EM_TIMER_CMD
{
EM_TIMER_CMD_SET_STOP = 0,
EM_TIMER_CMD_SET_START,
EM_TIMER_CMD_SET_CONTINUE,
EM_TIMER_CMD_SET_HALT,
EM_TIMER_CMD_SET_MATCH,
EM_TIMER_CMD_SET_COUNT,
EM_TIMER_CMD_SET_CALLBACK,
EM_TIMER_CMD_SET_ARG,
EM_TIMER_CMD_END
}EM_TIMER_CMD;
定时器启动命令分类:
typedef enum _EM_TIMER_STATE
{
EM_TIMER_STATE_STOP = 0,
EM_TIMER_STATE_START,
EM_TIMER_STATE_HALT,
EM_TIMER_STATE_END
}EM_TIMER_STATE;
typedef enum _EM_TIMER_PRIO
{
EM_TIMER_PRIO_HIGH = 0,
EM_TIMER_PRIO_LOW,
EM_TIMER_PRIO_END
}EM_TIMER_PRIO;
定时器结构体的定义:
typedef void ( *pTIMER_CALLBACK ) ( void* Pre );
struct _TIMER_STR
{
volatile uint32_t TimerCount;
uint32_t TimerMatch;
uint8_t TimerFlag;
void* pArg;
EM_TIMER_STATE TimerState;
pTIMER_CALLBACK pTimerCallBack;
};
typedef struct _TIMER_STR TIMER_STR;
typedef struct _TIMER_STR* pTIMER_STR;
以上是.h文件中的定义,需要用的结构体,变量、宏全部完成定义。学理工科的,尤其是码农不喜欢说很多话,一切都在代码里,志同道合的人自己品吧!
函数定义部分的代码
首先定义两个缓冲区用于存储定时器的过程信息
static pTIMER_STR spTimerStrBufHigh[ 12 ] = { 0 };
static pTIMER_STR spTimerStrBufLow[ 10 ] = { 0 };
static volatile uint8_t sTimerIsrFlag = FALSE;
定时器定义:初始化
uint8_t Timer_Open( pTIMER_STR pTimerStr, uint32_t TimerMatch, pTIMER_CALLBACK pTimerCallback, void* pArg, EM_TIMER_PRIO TimerPrio )
{
uint8_t Ret = TRUE;
uint8_t i;
SYSTEM_ASSERT( ( pTimerStr != NULL )&&\
( TimerMatch != 0 )&&\
( pTimerCallback != NULL ) );
pTimerStr->TimerCount = 0;
pTimerStr->TimerState = EM_TIMER_STATE_STOP;
pTimerStr->TimerMatch = TimerMatch;
pTimerStr->pTimerCallBack = pTimerCallback;
pTimerStr->pArg = pArg;
if( TimerPrio == EM_TIMER_PRIO_HIGH )
{
for( i = 0; i < MC_TIMER_MAX_NUM_HIGH; i++ )
{
if( spTimerStrBufHigh[ i ] == NULL )
{
spTimerStrBufHigh[ i ] = pTimerStr;
Ret = TRUE;
break;
}
else
{
SYSTEM_ASSERT( TRUE );
}
}
}
else
{
for( i = 0; i < MC_TIMER_MAX_NUM_LOW; i++ )
{
if( spTimerStrBufLow[ i ] == NULL )
{
spTimerStrBufLow[ i ] = pTimerStr;
Ret = TRUE;
break;
}
else
{
SYSTEM_ASSERT( TRUE );
}
}
}
return Ret;
}
pTimerStr : 基准定时器的结构体指针
TimerMatch : 定时器需要延时的设定值
pTimerCallback : 当定时器到达设定值时需要执行的任务写在callback函数中
TimerPrio : 定时器的优先级设定
基于高优先级的基准定时器处理函数
void Timer_ISR( void )
{
uint8_t i;
sTimerIsrFlag = TRUE;
for( i = 0; i < MC_TIMER_MAX_NUM_HIGH; i++ )
{
if( spTimerStrBufHigh[ i ] == NULL )
{
break;
}
else
{
if( spTimerStrBufHigh[ i ]->TimerState == EM_TIMER_STATE_START )
{
spTimerStrBufHigh[ i ]->TimerCount++;
if( spTimerStrBufHigh[ i ]->TimerCount >= spTimerStrBufHigh[ i ]->TimerMatch )
{
spTimerStrBufHigh[ i ]->TimerCount = 0;
if( spTimerStrBufHigh[ i ]->pTimerCallBack != NULL )
{
spTimerStrBufHigh[ i ]->pTimerCallBack( spTimerStrBufHigh[ i ]->pArg );
}
else
{
}
}
else
{
}
}
else
{
}
}
}
}
基于低优先级的基准定时器的处理函数
void Timer_Loop( void )
{
uint8_t i;
if( sTimerIsrFlag == TRUE )
{
sTimerIsrFlag = FALSE;
for( i = 0; i < MC_TIMER_MAX_NUM_LOW; i++ )
{
if( spTimerStrBufLow[ i ] == NULL )
{
break;
}
else
{
if( spTimerStrBufLow[ i ]->TimerState == EM_TIMER_STATE_START )
{
spTimerStrBufLow[ i ]->TimerCount++;
if( spTimerStrBufLow[ i ]->TimerCount >= spTimerStrBufLow[ i ]->TimerMatch )
{
spTimerStrBufLow[ i ]->TimerCount = 0;
if( spTimerStrBufLow[ i ]->pTimerCallBack != NULL )
{
spTimerStrBufLow[ i ]->pTimerCallBack( spTimerStrBufLow[ i ]->pArg );
}
else
{
}
}
else
{
}
}
else
{
}
}
}
}
}
Timer_ISR 需要在定时中断函数中调用,这样它可以精准的计量并执行
Timer_Loop可以在任意情况下调用,但是注意计算它实际的基准时钟。
启动、停止或者设置定时器的命令函数
uint8_t Timer_Cmd( pTIMER_STR pTimerStr, EM_TIMER_CMD TimerCmd, void* pValue )
{
uint8_t Ret = TRUE;
SYSTEM_ASSERT( ( pTimerStr != NULL ) &&\
( TimerCmd < EM_TIMER_CMD_END) );
switch( TimerCmd )
{
case EM_TIMER_CMD_SET_STOP:
SYSTEM_DISABLE_INT();
pTimerStr->TimerCount = 0;
pTimerStr->TimerState = EM_TIMER_STATE_STOP;
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_START:
SYSTEM_DISABLE_INT();
if( pTimerStr->TimerState == EM_TIMER_STATE_HALT )
{
pTimerStr->TimerState = EM_TIMER_STATE_START;
}
else
{
pTimerStr->TimerCount = 0;
pTimerStr->TimerState = EM_TIMER_STATE_START;
}
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_CONTINUE:
SYSTEM_DISABLE_INT();
pTimerStr->TimerState = EM_TIMER_STATE_START;
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_HALT:
SYSTEM_DISABLE_INT();
if( pTimerStr->TimerState == EM_TIMER_STATE_STOP )
{
Ret = FALSE;
}
else
{
pTimerStr->TimerState = EM_TIMER_STATE_HALT;
}
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_MATCH:
SYSTEM_ASSERT( pValue != NULL );
SYSTEM_DISABLE_INT();
pTimerStr->TimerMatch = *( ( uint32_t* )pValue );
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_COUNT:
SYSTEM_ASSERT( pValue != NULL );
SYSTEM_DISABLE_INT();
pTimerStr->TimerCount = *( ( uint32_t* )pValue );
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_CALLBACK:
SYSTEM_ASSERT( pValue != NULL );
SYSTEM_DISABLE_INT();
SYSTEM_LINT_SUPPRESS(-e{611})
pTimerStr->pTimerCallBack = ( pTIMER_CALLBACK )pValue;
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_SET_ARG:
SYSTEM_ASSERT( pValue != NULL );
SYSTEM_DISABLE_INT();
pTimerStr->pArg = pValue;
SYSTEM_ENABLE_INT();
break;
case EM_TIMER_CMD_END:
default:
SYSTEM_ASSERT( FALSE );
break;
}
return Ret;
}
Timer_Cmd可以随意实现定时器的启动、停止、重新设置、清零等任意操作,使得定时器的应用更下便捷。
定时器实用示例:调用方法
/*在htim1的中断处理函数中调用Timer_ISR()*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1) /*time1:1ms*/
{
Timer_ISR();
}
}
/*定时器初始化示例*/
static TIMER_STR sWindowBaseTimerStr;
void sWindow_BaseTimerCallback( void* pArg );
uint8_t Window_Init( void )
{
uint8_t Ret;
Ret = Timer_Open( &sWindowBaseTimerStr, 1, sWindow_BaseTimerCallback, NULL, EM_TIMER_PRIO_HIGH );
SYSTEM_ASSERT( Ret == TRUE );
Timer_Cmd( &sWindowBaseTimerStr, EM_TIMER_CMD_SET_START, NULL );
return Ret;
}