软件定时器

软件定时器设计

软件定时器、一般是基于硬件定时器提供基准时间的软件模拟定时器,定时时间到之后执行回调函数。
一般应用于某个操作需要定时循环执行,如日志记录、每间隔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;
			}
		}
	}
}
上一篇:Soft PLC 可编程式控制器


下一篇:MySQL-NDB7.6集群软件升级