软件定时器设计
软件定时器、一般是基于硬件定时器提供基准时间的软件模拟定时器,定时时间到之后执行回调函数。
一般应用于某个操作需要定时循环执行,如日志记录、每间隔5分钟记录一次日志信息。或者跑裸机、执行多操作循环处理。
1、bsp_soft_time_hw.h
#ifndef __BSP_SOFT_TIME_HW_H_
#define __BSP_SOFT_TIME_HW_H_
#include "main.h"
#define SOFT_TIME_MAX 20 //软件定时器上限数据
/*回调函数类型定义*/
typedef void callback(void *argv, uint16_t argc);
/*可用定时器的id*/
typedef enum eSTIME_ID
{
SOFT_TIME_ID0,
SOFT_TIME_ID1,
SOFT_TIME_ID2,
SOFT_TIME_ID3,
SOFT_TIME_ID4,
SOFT_TIME_ID5,
SOFT_TIME_ID6,
SOFT_TIME_ID7,
SOFT_TIME_ID8,
SOFT_TIME_ID9,
SOFT_TIME_ID_MAX,
}eSTIME_ID;
/*定时器状态枚举*/
typedef enum eSTIME_STA
{
SOFT_TIME_STA_STOP = 0,
SOFT_TIME_STA_RUN,
SOFT_TIME_STA_TIMEOUT,
}eSTIME_STA;
/*定时器模式*/
typedef enum eSTIME_MODE
{
SOFT_TIME_MODE_SINGLE = 0, //单次模式
SOFT_TIME_MODE_PERIOD, //周期模式
SOFT_TIME_MODE_MAX,
}eSTIME_MODE;
/*软件定时器信息结构体*/
typedef struct sSoftTime_TypeDef
{
eSTIME_STA status; //当前状态
eSTIME_MODE mode; //模式
uint32_t start_time; //启动时间
uint32_t delay_time; //延迟时间
callback *callfuns; //超时回调函数
void *argv; //回调函数参数
uint16_t argc; //回调函数参数个数
}sSoftTime_TypeDef;
/*软件定时信息结构体*/
typedef struct sSoftTime_Info
{
uint32_t SoftTime_Count; //定时基准时间
uint16_t SoftTime_CurN; //当前开启的定时器个数
sSoftTime_TypeDef tagSoftTime[SOFT_TIME_MAX];
}sSoftTime_Info;
/*--------------------------接口函数---------------------------*/
void BSP_TIMER_DeInit(void);
void BSP_TIMER_DelTimer(eSTIME_ID id);
uint8_t BSP_TIMER_StartTimer(eSTIME_ID id,
eSTIME_MODE mode,
uint32_t delay_time,
callback pfun,
void * argv,
uint16_t argc
);
void BSP_TIMER_Run(void);
void BSP_TIMER_Calc(void);
#endif
2、bsp_soft_timer_hw.c
#include "bsp_soft_time_hw.h"
#include "gpio.h"
sSoftTime_Info SoftTime;
/*******************************************************************
函 数 名 : BSP_TIMER_DeInit
输 入 : 无
输 出 : 无
功 能 : 初始化软件定时器初始化
作 者 : wx
时 间 : 2020-11-11 21:38:29
备 注 :
*******************************************************************/
void BSP_TIMER_DeInit(void)
{
uint8_t i;
for(i = 0; i < SOFT_TIME_MAX; i++)
{
SoftTime.tagSoftTime[i].status = SOFT_TIME_STA_STOP;
SoftTime.tagSoftTime[i].mode = SOFT_TIME_MODE_SINGLE;
SoftTime.tagSoftTime[i].start_time = 0;
SoftTime.tagSoftTime[i].delay_time = 0;
SoftTime.tagSoftTime[i].callfuns = (callback*)0;
SoftTime.tagSoftTime[i].argv = (void*)0;
SoftTime.tagSoftTime[i].argc = 0;
}
SoftTime.SoftTime_CurN = 0;
SoftTime.SoftTime_Count = 0;
}
/*******************************************************************
函 数 名 : BSP_TIMER_DelTimer
输 入 : 无
输 出 : 无
功 能 : 移除指定id的软件定时器
作 者 : wx
时 间 : 2020-11-11 21:38:29
备 注 :
*******************************************************************/
void BSP_TIMER_DelTimer(eSTIME_ID id)
{
if(id > SOFT_TIME_ID_MAX || SoftTime.SoftTime_CurN <= 0)
{
return;
}
//清除对应id的软件定时器信息
SoftTime.tagSoftTime[id].status = SOFT_TIME_STA_STOP;
SoftTime.tagSoftTime[id].mode = SOFT_TIME_MODE_SINGLE;
SoftTime.tagSoftTime[id].start_time = 0;
SoftTime.tagSoftTime[id].delay_time = 0;
SoftTime.tagSoftTime[id].callfuns = (callback*)0;
SoftTime.tagSoftTime[id].argv = (void*)0;
SoftTime.tagSoftTime[id].argc = 0;
//开启的定时器个数减去1
SoftTime.SoftTime_CurN--;
}
/*******************************************************************
函 数 名 : BSP_TIMER_StartTimer
输 入 :
id - 定时器序号
mode - 定时模式
delay_time - 定时时间
pfun - 超时回调函数
argv - 回调函数参数
argc - 回调函数参数个数
输 出 :
1-成功
2-失败
功 能 : 启动一个软件定时器
作 者 : wx
时 间 : 2020-11-11 21:38:29
备 注 :
*******************************************************************/
uint8_t BSP_TIMER_StartTimer(eSTIME_ID id, //id
eSTIME_MODE mode, //定时模式
uint32_t delay_time, //定时时间
callback pfun, //超时回调函数
void * argv, //回调函数参数
uint16_t argc //回调函数参数个数
)
{
if(id > SOFT_TIME_ID_MAX || SoftTime.SoftTime_CurN > SOFT_TIME_MAX -1)
{
return 2;
}
SoftTime.tagSoftTime[id].status = SOFT_TIME_STA_RUN;
SoftTime.tagSoftTime[id].mode = mode;
SoftTime.tagSoftTime[id].start_time = SoftTime.SoftTime_Count; //当前基准时间
SoftTime.tagSoftTime[id].delay_time = delay_time;
SoftTime.tagSoftTime[id].callfuns = pfun;
SoftTime.tagSoftTime[id].argv = argv;
SoftTime.tagSoftTime[id].argc = argc;
//开启的定时器个数加1
SoftTime.SoftTime_CurN++;
return 1;
}
/*******************************************************************
函 数 名 : BSP_TIMER_Run
输 入 : 无
输 出 : 无
功 能 : 定时器基准时间自增-放到中断服务函数中循环调用
作 者 : wx
时 间 : 2020-11-11 21:38:29
备 注 :
*******************************************************************/
void BSP_TIMER_Run(void)
{
SoftTime.SoftTime_Count++;
}
/*******************************************************************
函 数 名 : BSP_TIMER_Calc
输 入 : 无
输 出 : 无
功 能 : 定时器处理 - 放到主循环中调用
作 者 : wx
时 间 : 2020-11-11 21:38:29
备 注 :
*******************************************************************/
void BSP_TIMER_Calc(void)
{
uint8_t i;
for(i = 0; i < SoftTime.SoftTime_CurN; i++)
{
switch(SoftTime.tagSoftTime[i].status)
{
case SOFT_TIME_STA_STOP:
{
;
}break;
case SOFT_TIME_STA_RUN:
{
//判断时间是否超时
if(SoftTime.tagSoftTime[i].delay_time <= (SoftTime.SoftTime_Count - SoftTime.tagSoftTime[i].start_time+1))
{
SoftTime.tagSoftTime[i].status = SOFT_TIME_STA_TIMEOUT;
}
}break;
case SOFT_TIME_STA_TIMEOUT:
{
if(SoftTime.tagSoftTime[i].callfuns)
{
//执行超时回调函数
SoftTime.tagSoftTime[i].callfuns(SoftTime.tagSoftTime[i].argv,
SoftTime.tagSoftTime[i].argc);
}
if(SoftTime.tagSoftTime[i].mode == SOFT_TIME_MODE_SINGLE) //单次模式
{
//移除软件定时器
BSP_TIMER_DelTimer((eSTIME_ID)i);
}
else //周期模式
{
//更新状态和启动时间
SoftTime.tagSoftTime[i].status = SOFT_TIME_STA_RUN;
SoftTime.tagSoftTime[i].start_time = SoftTime.SoftTime_Count;
}
}break;
default:
{
break;
}
}
}
}