单片机软件定时器V4.0
单片机软件定时器V4.0
用于单片机定时执行任务等,比如LED GPIO等定时控制,内置前后台工作模式
头文件有使用例子
#ifndef __SORFTIME_APP_H
#define __SORFTIME_APP_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
// #define ST_CLIENT_SERVER_MODE 1 /*取消注释切换到前后台模式*/
#define MAX_TIMER_NUM 16 /* 定时器最大个数(可修改) */
/**移植修改步骤**/
/*
1:st_sorft_timer_init(); 初始化
2: 把 st_sorft_timer_counter_prosess(); 放入1ms中断回调或1ms的OS任务中
3: 修改 MAX_TIMER_NUM 的定义值,比如需要用到10个定时器就改为>=10
4: 查看底部例程使用方法
5: 记得把printf注释掉,如果没有配置printf会停在printf的while循环里面
*/
#if 1
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
#endif
#if 0
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
#endif
typedef enum timer_run_mode
{
TIM_INTERUPUT_MODE = 0, /* 中断模式*/
#ifdef ST_CLIENT_SERVER_MODE
TIM_CLIENT_SERVER_MODE = 1, /* 前后台模式*/
#endif
} st_e_run_mode_t;
/***********状态枚举***********/
typedef enum timer_init_state
{
TIM_CRAT_SUCES = 0, /* create succes 创建成功状态 */
TIM_CRAT_ERROR = 1, /* create faild 创建失败状态 */
} st_e_state_crat_t;
typedef enum timer_run_state
{
TIM_LOCK = 2, /* 锁定计数,不能再次更新计数值,只能等到计数结束 */
TIM_UNLOCK = 3, /* 不锁定计数,可以中途手动更新计数值 */
TIM_END = 4, /* 计数值到达目标值,停止计数 */
} st_e_state_run_t;
typedef enum timer_end_state
{
TIM_ONCE = 5, /* 单次计数模式*/
TIM_CYCLE = 6, /* 循环计数模式*/
} st_e_state_end_t;
typedef enum timer_close_state
{
TIM_DESTROYED = 7, /* 销毁状态 (擦除这个定时器所占坑位资源)*/
TIM_SUSPEND = 8 /* 挂起定时器 (会占用一个定时器坑位,不推荐)*/
} st_e_state_close_t;
typedef void (*st_rtn_func_t)(uint16_t);
/*******单个定时器结构体 *************/
typedef struct id_menber
{
uint16_t id; /* 软件定时器id */
uint32_t count; /* 计数运行值 */
uint32_t target; /* 计数目标值 */
st_e_state_run_t run_state; /* 运行时的状态 */
st_e_state_end_t end_state; /* 结束后的状态 */
st_rtn_func_t rtn_func; /* 计时结束的回调函数 */
} st_id_t;
/*******所有定时器结构体 *************/
typedef struct timer_id
{
st_id_t id_ary[MAX_TIMER_NUM]; /*数组*/
uint16_t timer_last_index; /*当前定时器最大个数*/
} s_timer_id;
#ifdef ST_CLIENT_SERVER_MODE
/*前后台模式,前台运行在main while模式,后台中断定时器设置标志*/
typedef struct timer_event
{
uint16_t event_id[MAX_TIMER_NUM];
st_rtn_func_t event_ary[MAX_TIMER_NUM]; /*数组*/
} s_event_id;
#endif
void st_sorft_timer_init(void); /*初始化软件定时器*/
void st_sorft_timer_counter_prosess(void); /*此函数放入定时器中断回调函数*/
#ifdef ST_CLIENT_SERVER_MODE
/*这个函数放入main 的while循环*/
void st_sorft_timer_event_prosess(void);
#endif
st_e_state_crat_t st_start_timer(uint16_t timer_id, uint32_t count, st_e_state_run_t run_state); /*开启一个定时器*/
st_e_state_crat_t st_start_once_timer(uint16_t timer_id, uint32_t count, st_e_state_run_t run_state); /*开启一次定时器*/
st_e_state_crat_t st_start_cb_timer(uint16_t timer_id, uint32_t count, st_e_state_run_t run_state, st_e_state_end_t end_state, st_rtn_func_t rtn_func); /*计时结束,执行回调函数,函数执行完毕自动销毁该定时器*/
st_e_state_close_t st_close_timer(uint16_t timer_id, st_e_state_close_t close_state); /* 关掉或者暂停一个定时器 */
st_e_state_run_t st_timer_state(uint16_t timer_id); /* 读取定时器状态 */
uint32_t st_timer_count_value(uint16_t timer_id); /*查询定时器计数值 */
//**使用例程 start**//
/*
#define EVENT_ID_LED 0x10
#define EVENT_ID_GPIO 0x11
#define EVENT_ID_SPI 0x12
#define EVENT_ID_TIME 0x13
#define LOG(...) printf(__VA_ARGS__)
void app_main_process(uint16_t id)
{
if (id == EVENT_ID_LED)
{
st_start_cb_timer(EVENT_ID_LED, 30, TIM_LOCK, TIM_ONCE, app_main_process);
LOG("LED\n");
return;
}
if (id == EVENT_ID_GPIO)
{
st_start_cb_timer(EVENT_ID_GPIO, 40, TIM_LOCK, TIM_ONCE, app_main_process);
LOG("GPIO\n");
return;
}
if (id == EVENT_ID_SPI)
{
LOG("SPI\n");
return;
}
}
main()
{
st_sorft_timer_init();
st_start_cb_timer(EVENT_ID_LED, 5, TIM_LOCK, TIM_ONCE, app_main_process);
st_start_cb_timer(EVENT_ID_GPIO, 10, TIM_LOCK, TIM_CYCLE, app_main_process);
st_start_cb_timer(EVENT_ID_SPI, 20, TIM_UNLOK, TIM_CYCLE, app_main_process);
while (1)
{
// st_sorft_timer_event_prosess(); //前后台模式
}
return 0;
}
*/
//**end**//
#ifdef __cplusplus
}
#endif
#endif
#include "sorftime_app.h"
#include "stdio.h"
/***********计数值**************/
#define ST_START_COUNT_VALUE 0
#define ST_END_COUNT_VALUE 0xFFFFFFFE
#define ST_ID_NULL 0
/************ID值****************/
#define ST_NULL_ID 0
#define ST_NEW_ID 1
#define ST_OLD_ID 2
static s_timer_id timer_id_ary;
static uint8_t OPEN_COUNTER = 0;
static uint8_t MAX_USE_NUMBER = 0;
#ifdef ST_CLIENT_SERVER_MODE
static s_event_id event_id_ary;
static void add_event_to_list(st_rtn_func_t event_cb, uint16_t id);
#endif
/**
* @brief 定时器中断回调,对所有计数值进行减少
* 中断触发为 1ms
* 根据用户层需要的计时时间,到达就改变状态
**/
void st_sorft_timer_counter_prosess(void)
{ /* 此函数放入中断回调*/
uint8_t i = 0;
st_id_t end_id;
if (OPEN_COUNTER)
{
for (i = 0; i < MAX_USE_NUMBER; i++)
{
if ((timer_id_ary.id_ary[i].id) != ST_ID_NULL)
{
if ((timer_id_ary.id_ary[i].run_state != TIM_SUSPEND) && (timer_id_ary.id_ary[i].run_state != TIM_END))
{
if ((++(timer_id_ary.id_ary[i].count)) >= (timer_id_ary.id_ary[i].target))
{
timer_id_ary.id_ary[i].count = ST_END_COUNT_VALUE;
end_id.id = timer_id_ary.id_ary[i].id;
end_id.run_state = timer_id_ary.id_ary[i].run_state;
end_id.end_state = timer_id_ary.id_ary[i].end_state;
end_id.rtn_func = timer_id_ary.id_ary[i].rtn_func;
timer_id_ary.id_ary[i].run_state = TIM_END;
/*结束定时*/
if (end_id.end_state == TIM_ONCE)
{
timer_id_ary.id_ary[i].id = ST_ID_NULL;
timer_id_ary.id_ary[i].count = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].run_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].end_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].target = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].rtn_func = NULL;
}
/*循环触发*/
if (end_id.end_state == TIM_CYCLE)
{
timer_id_ary.id_ary[i].count = ST_START_COUNT_VALUE;
timer_id_ary.id_ary[i].run_state = end_id.run_state;
}
/*执行回调*/
if (end_id.rtn_func != NULL)
{
#ifdef ST_CLIENT_SERVER_MODE
add_event_to_list(end_id.rtn_func, end_id.id);
#else
end_id.rtn_func(end_id.id);
#endif
}
}
}
}
}
}
}
#ifdef ST_CLIENT_SERVER_MODE
/**
* @brief 前台调用,处理对应id的事件
* 后台中断将触发的timer id 标记
* 此函数负责处理对应的id事件调用
**/
void st_sorft_timer_event_prosess(void)
{
uint16_t i = 0;
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (event_id_ary.event_ary[i] != NULL)
{
event_id_ary.event_ary[i](event_id_ary.event_id[i]);
event_id_ary.event_id[i] = ST_ID_NULL;
event_id_ary.event_ary[i] = NULL;
return;
}
}
}
#endif
#ifdef ST_CLIENT_SERVER_MODE
/**
* @brief 添加事件回调到列表
**/
static void add_event_to_list(st_rtn_func_t event_cb, uint16_t id)
{
uint16_t i = 0;
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (event_id_ary.event_ary[i] == NULL)
{
event_id_ary.event_ary[i] = event_cb;
event_id_ary.event_id[i] = id;
return;
}
}
}
#endif
/**
@brief 定时器id赋值,使用定时器前先调用一次此接口
**/
void st_sorft_timer_init(void)
{
uint16_t i = 0;
/* 清空定时器所有 timer_id = 0*/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
timer_id_ary.id_ary[i].id = ST_ID_NULL;
timer_id_ary.id_ary[i].count = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].target = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].run_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].end_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].rtn_func = NULL;
#ifdef ST_CLIENT_SERVER_MODE
event_id_ary.event_id[i] = ST_ID_NULL;
event_id_ary.event_ary[i] = NULL;
#endif
}
timer_id_ary.timer_last_index = 0; /* 对管理的timer进行计数*/
OPEN_COUNTER = 1;
}
/**
@brief 启动一个定时器
* timer_id 用户自定义ID
* 需要计数时间MS
* 计数状态,LOCK_TIMING(计数时无法刷新计数值,只能等到计数结束)
* 计数状态,TIMING 可以中途重新刷新计数值
**/
st_e_state_crat_t st_start_timer(uint16_t timer_id, uint32_t count, st_e_state_run_t run_state)
{
uint16_t i = 0;
uint8_t first_i = 0;
uint8_t flag = ST_NULL_ID;
if (timer_id == 0 || count == 0)
{
return TIM_CRAT_ERROR;
}
if (!OPEN_COUNTER)
{
st_sorft_timer_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id_ary.id_ary[i].id == timer_id)
{
first_i = i;
flag = ST_OLD_ID; // 查找相同ID
if ((timer_id_ary.id_ary[i].run_state == TIM_LOCK) || (timer_id_ary.id_ary[i].run_state == TIM_END))
{
return TIM_LOCK;
}
break;
}
if ((timer_id_ary.id_ary[i].id == ST_ID_NULL) && (!flag))
{
first_i = i;
flag = ST_NEW_ID; /* 查找并记录空闲ID*/
}
}
if (!flag)
{
return TIM_CRAT_ERROR; /* 防止未查找到*/
}
if ((timer_id_ary.timer_last_index) < MAX_TIMER_NUM)
{
timer_id_ary.id_ary[first_i].id = timer_id;
timer_id_ary.id_ary[first_i].count = ST_START_COUNT_VALUE; /* 计数初始值*/
timer_id_ary.id_ary[first_i].target = count;
timer_id_ary.id_ary[first_i].run_state = run_state;
timer_id_ary.id_ary[first_i].end_state = TIM_DESTROYED;
timer_id_ary.id_ary[first_i].rtn_func = NULL;
if (flag == ST_NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
}
if (++timer_id_ary.timer_last_index >= MAX_USE_NUMBER) /* 新增一个ID ,进行+1计数 */
{
timer_id_ary.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CRAT_SUCES; /* 返回创建成功的状态 */
}
else
{
return TIM_CRAT_ERROR;
}
}
/**
*@brief 启动一次定时器
* 计时结束自动销毁定时器
* **/
st_e_state_crat_t st_start_once_timer(uint16_t timer_id, uint32_t count, st_e_state_run_t run_state)
{
uint16_t i = 0;
uint8_t first_i = 0;
uint8_t flag = ST_NULL_ID;
if (timer_id == 0 || count == 0)
{
return TIM_DESTROYED;
}
if (!OPEN_COUNTER)
{
st_sorft_timer_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id_ary.id_ary[i].id == timer_id)
{
first_i = i;
flag = ST_OLD_ID; /* 查找相同ID */
if (timer_id_ary.id_ary[i].run_state == TIM_LOCK)
{
return TIM_LOCK;
}
break;
}
if ((timer_id_ary.id_ary[i].id == ST_ID_NULL) && (!flag))
{
first_i = i;
flag = ST_NEW_ID;
}
}
if (!flag)
{
return TIM_CRAT_ERROR;
}
if ((timer_id_ary.timer_last_index) < MAX_TIMER_NUM)
{
timer_id_ary.id_ary[first_i].id = timer_id;
timer_id_ary.id_ary[first_i].count = ST_START_COUNT_VALUE;
timer_id_ary.id_ary[first_i].target = count;
timer_id_ary.id_ary[first_i].run_state = run_state;
timer_id_ary.id_ary[first_i].end_state = TIM_ONCE;
timer_id_ary.id_ary[first_i].rtn_func = NULL;
if (flag == ST_NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
}
if (++timer_id_ary.timer_last_index >= MAX_USE_NUMBER)
{
timer_id_ary.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CRAT_SUCES;
}
else
{
return TIM_CRAT_ERROR;
}
}
/**
* @brief 启动一次定时器
* 计时结束自动销毁定时器
**/
st_e_state_crat_t st_start_cb_timer(uint16_t timer_id,
uint32_t count,
st_e_state_run_t run_state,
st_e_state_end_t end_state,
st_rtn_func_t rtn_func)
{
uint16_t i = 0;
uint8_t first_i = 0;
uint8_t flag = ST_NULL_ID;
if (timer_id == 0 || count == 0 || rtn_func == NULL)
{
return TIM_DESTROYED;
}
if (!OPEN_COUNTER)
{
st_sorft_timer_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id_ary.id_ary[i].id == timer_id)
{
first_i = i;
flag = ST_OLD_ID;
if (timer_id_ary.id_ary[i].run_state == TIM_LOCK)
{
return TIM_LOCK;
}
break;
}
if ((timer_id_ary.id_ary[i].id == ST_ID_NULL) && (!flag))
{
first_i = i;
flag = ST_NEW_ID;
}
}
if (!flag)
{
return TIM_CRAT_ERROR;
}
if ((timer_id_ary.timer_last_index) < MAX_TIMER_NUM)
{
timer_id_ary.id_ary[first_i].id = timer_id;
timer_id_ary.id_ary[first_i].count = ST_START_COUNT_VALUE;
timer_id_ary.id_ary[first_i].target = count;
timer_id_ary.id_ary[first_i].run_state = run_state;
timer_id_ary.id_ary[first_i].end_state = end_state;
timer_id_ary.id_ary[first_i].rtn_func = rtn_func;
if (flag == ST_NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
}
if (++timer_id_ary.timer_last_index >= MAX_USE_NUMBER)
{
timer_id_ary.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CRAT_SUCES; /*返回创建成功的状态*/
}
else
{
return TIM_CRAT_ERROR;
}
}
/**
* @brief 关掉定时器,
* TIM_SUSPEND 定时器不销毁,计数暂停
* TIM_DESTROYED 销毁定时器,ID将被抹去
*/
st_e_state_close_t st_close_timer(uint16_t timer_id, st_e_state_close_t close_state)
{
uint16_t i = 0;
if (timer_id == 0)
{
return TIM_DESTROYED;
}
for (i = 0; i < MAX_USE_NUMBER; i++)
{
if (timer_id_ary.id_ary[i].id == timer_id)
{
break;
}
}
if (i >= MAX_USE_NUMBER)
{
return TIM_DESTROYED;
}
if (close_state == TIM_SUSPEND)
{ /* 暂停定时器,也就是关掉的意思 */
/***暂停定时器**** 查看是否有相同ID ********/
if ((timer_id_ary.id_ary[i].id) == timer_id)
{
timer_id_ary.id_ary[i].id = timer_id; /*ID不能抹去 */
timer_id_ary.id_ary[i].count = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].run_state = TIM_SUSPEND; /*挂起定时器 */
timer_id_ary.id_ary[i].end_state = TIM_SUSPEND;
timer_id_ary.id_ary[i].target = ST_END_COUNT_VALUE;
return TIM_SUSPEND;
}
}
else if (close_state == TIM_DESTROYED)
{ /* 销毁定时器 */
/****销毁定时器*** 查看是否有相同ID ********/
if ((timer_id_ary.id_ary[i].id) == timer_id)
{
timer_id_ary.id_ary[i].id = ST_ID_NULL;
timer_id_ary.id_ary[i].count = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].run_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].end_state = TIM_DESTROYED;
timer_id_ary.id_ary[i].target = ST_END_COUNT_VALUE;
timer_id_ary.id_ary[i].rtn_func = NULL;
if (timer_id_ary.timer_last_index > 0)
{
timer_id_ary.timer_last_index--;
}
if (timer_id_ary.id_ary[MAX_USE_NUMBER - 1].run_state == TIM_DESTROYED)
{
MAX_USE_NUMBER--;
}
return TIM_DESTROYED; // 返回刚刚创建的状态
}
}
return TIM_DESTROYED;
}
/**
*@bref 返回定时器状态
有此ID的定时器就返回当前状态
没有就返回DESTROYED
* **/
st_e_state_run_t st_timer_state(uint16_t timer_id)
{
uint16_t i = 0;
if (timer_id == 0)
{
return TIM_DESTROYED;
}
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if ((timer_id_ary.id_ary[i].id) == timer_id)
{
return timer_id_ary.id_ary[i].run_state;
}
}
return TIM_DESTROYED;
}
/*
@bref 查询计数值
*/
uint32_t st_timer_count_value(uint16_t timer_id)
{
uint16_t i = 0;
if (timer_id == 0)
{
return ST_END_COUNT_VALUE;
}
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if ((timer_id_ary.id_ary[i].id) == timer_id)
{
return timer_id_ary.id_ary[i].count;
}
}
return ST_END_COUNT_VALUE;
}