单片机软件定时器V3.0
使用方法:
1: 把 counter_prosess(); 放入1ms中断回调或1ms的OS任务中
2: 修改 MAX_TIMER_NUM 的定义值,比如需要用到10个定时器就改为>=10
3: 查看底部例程使用方法
4: 记得把printf注释掉,如果没有配置printf会停在printf的while循环里面
.H
#ifndef __SORFTIME_APP_H
#define __SORFTIME_APP_H
typedef unsigned char u8;
typedef unsigned char uint8_t;
typedef unsigned short int u16;
typedef unsigned short int uint16_t;
typedef unsigned int u32;
typedef unsigned int uint32_t;
//**移植修改步骤**//
/*
1: 把 counter_prosess(); 放入1ms中断回调或1ms的OS任务中
2: 修改 MAX_TIMER_NUM 的定义值,比如需要用到10个定时器就改为>=10
3: 查看底部例程使用方法
4: 记得把printf注释掉,如果没有配置printf会停在printf的while循环里面
*/
//***********计数值状态****start*******/
typedef enum timer_state{
//--------------------------------------//
TIM_CRAT_ERROR = 0, //刚刚开始或创建(几乎不用)
TIM_CREATED = 1, //计时结束(常用于状态比较)
TIM_END = 2, //出现错误(几乎不用)
//--------------------------------------//
TIM_ONCE = 3, //单次计数模式(几乎不用)
TIM_CYCLE = 4, //循环计数
//--------------------------------------//
TIM_DESTROYED = 5, //销毁状态(常用于close_timer)
TIM_SUSPEND = 6, //挂起定时器(偶尔用于close_timer)
//--------------------------------------//
TIM_LOCK = 7, //锁定计数,不能再次更新计数值,只能等到计数结束(常用于start_timer)
TIM_UNLOCK = 8 //正在计数中,可以再次手动更新计数值(偶尔用于start_timer)
}state_t;
typedef void (*rtn_func_t)(uint16_t);
//*******定时器结构体 start*********//
typedef struct id_menber{ //
uint16_t id; //
uint32_t count; //计数值 //
uint32_t target; //目标值 //
state_t state; //运行时的状态 //
state_t end_state; //结束后的状态
rtn_func_t rtn_func; //计时结束的回调函数
}s_id; //
//
#define MAX_TIMER_NUM 10 //定时器最大个数(可修改)
//
typedef struct timer_id{ //
s_id id_ary[MAX_TIMER_NUM]; //
uint16_t timer_last_index; //
}s_timer_id; //
//****************end***************//
void counter_init(void);
void counter_prosess(void); //此函数放入定时器中断回调函数
state_t start_timer(u16 ID,u32 count ,state_t state); //开启一个定时器
state_t start_once_timer(u16 ID,u32 count ,state_t state); //开启一次定时器
/**
* @brief state:TIM_LOCK\TIM_UNLOCK\TIM_ONCE\TIM_CYCLE
*/
state_t start_cb_timer(u16 ID, u32 count, state_t run_state,state_t end_state, rtn_func_t rtn_func); //计时结束,执行回调函数,函数执行完毕自动销毁该定时器
state_t close_timer(u16 ID,state_t state ); //关掉或者暂停一个定时器
state_t timer_state(u16 ID); //读取定时器状态
u32 timer_count_value(u16 ID); //查询定时器计数值
//**使用例程 start**//
/* 此例程适用 按键触发等裸机大循环
#define ENTER_WAIT 80
#define BACK_WAIT 90
#define KEY1_DELAY_ID 0x01
#define OPEN_DELAY_ID 0x02
if( !PIN_STATE(key1_pin) ){ //检查按键是否按下
//防抖延时
if( timer_state(KEY1_DELAY_ID) == TIM_END){ //查看是否计时结束
close_timer(KEY1_DELAY_ID,TIM_SUSPEND); //挂起定时器
//do something
}
else{
start_timer(KEY1_DELAY_ID,ENTER_WAIT,TIM_LOCK); //开启一个定时器
//第一个参数是ID,第二个参数是计数值,第三个参数是计数状态
}
}
else{
close_timer(KEY1_DELAY_ID ,TIM_DESTROYED); //挂起定时器
}
-------------------------------------------------
if(timer_state(OPEN_DELAY_ID) == TIM_DESTROYED){ //定时一秒进入
//do something
start_once_timer(OPEN_DELAY_ID,1000,TIM_LOCK);
}
*/
//**end**//
#endif
.C
#include "sorftime_app.h"
#include "config_time.h"
#include "stdio.h"
/***********计数值**************/
#define START_COUNT 0
#define END_COUNT 999999999
#define ID_CLEAR 0
/****************************/
#define NULL_ID 0
#define NEW_ID 1
#define OLD_ID 2
// typedef unsigned char u8;
// typedef unsigned char uint8_t;
// typedef unsigned short int u16;
// typedef unsigned short int uint16_t;
// typedef unsigned int u32;
// typedef unsigned int uint32_t;
s_timer_id timer_id;
u8 OPEN_COUNTER = 0;
uint8_t MAX_USE_NUMBER = 0;
/**
* @bref 定时器中断回调,对所有计数值进行减少
* 中断触发为 1ms
* 根据用户层需要的计时时间,到达就改变状态
**/
void counter_prosess(void)
{ // 此函数放入中断回调
uint8_t i = 0;
state_t temp_state;
if (OPEN_COUNTER)
{
for (i = 0; i < MAX_USE_NUMBER; i++)
{
if ((timer_id.id_ary[i].id) != ID_CLEAR)
{
if ((timer_id.id_ary[i].state != TIM_SUSPEND) && (timer_id.id_ary[i].state != TIM_END))
{
if ((++(timer_id.id_ary[i].count)) >= (timer_id.id_ary[i].target))
{
timer_id.id_ary[i].count = END_COUNT;
temp_state = timer_id.id_ary[i].state;
timer_id.id_ary[i].state = TIM_END;
if (timer_id.id_ary[i].rtn_func != NULL)
{
timer_id.id_ary[i].rtn_func(timer_id.id_ary[i].id);
if (timer_id.id_ary[i].end_state == TIM_CYCLE)
{ // 循环触发
timer_id.id_ary[i].count = START_COUNT;
timer_id.id_ary[i].state = temp_state;
}
}
if (timer_id.id_ary[i].end_state == TIM_ONCE)
{ // 单次计数在结束时需要挂起定时器
close_timer(timer_id.id_ary[i].id, TIM_DESTROYED);
}
}
}
}
}
}
}
/**
@bref 定时器id赋值,使用定时器前先调用一次此接口
**/
void counter_init(void)
{
uint8_t i = 0;
// 清空定时器所有 ID = 0
for (i = 0; i < MAX_TIMER_NUM; i++)
{
timer_id.id_ary[i].id = ID_CLEAR; // 清空ID
timer_id.id_ary[i].count = END_COUNT;
timer_id.id_ary[i].state = TIM_DESTROYED; // 定时器还未创建状态
timer_id.id_ary[i].target = END_COUNT;
timer_id.id_ary[i].end_state = TIM_DESTROYED;
timer_id.id_ary[i].rtn_func = NULL;
}
timer_id.timer_last_index = 0; // 对管理的timer进行计数
OPEN_COUNTER = 1;
// printf("初始化软件定时器 \n");
}
/**
@bref 启动一个定时器
* ID 用户自定义ID
* 需要计数时间MS
* 计数状态,LOCK_TIMING(计数时无法刷新计数值,只能等到计数结束)
* 计数状态,TIMING 可以中途重新刷新计数值
**/
state_t start_timer(u16 ID, u32 count, state_t state)
{
uint8_t i = 0;
uint8_t first_i = 0;
uint8_t flag = NULL_ID;
if (ID == 0 || count == 0)
{
return TIM_DESTROYED;
}
if (!OPEN_COUNTER)
{
counter_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id.id_ary[i].id == ID)
{
first_i = i;
flag = OLD_ID; // 查找相同ID
if ((timer_id.id_ary[i].state == TIM_LOCK) || (timer_id.id_ary[i].state == TIM_END))
{
return TIM_LOCK;
}
break;
}
if ((timer_id.id_ary[i].id == ID_CLEAR) && (!flag))
{
first_i = i;
flag = NEW_ID; // 查找并记录空闲ID
}
}
if (!flag)
{
return TIM_CRAT_ERROR; // 防止未查找到
}
if ((timer_id.timer_last_index) < MAX_TIMER_NUM)
{
timer_id.id_ary[first_i].id = ID; // ID
timer_id.id_ary[first_i].count = START_COUNT; // 计数初始值
timer_id.id_ary[first_i].state = state; // 刚刚创建或启动
timer_id.id_ary[first_i].target = count;
timer_id.id_ary[first_i].end_state = TIM_DESTROYED;
timer_id.id_ary[first_i].rtn_func = NULL;
if (flag == NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
// printf("(%d)",MAX_USE_NUMBER);
}
if (++timer_id.timer_last_index >= MAX_USE_NUMBER) // 新增一个ID ,进行+1计数
{
timer_id.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CREATED; // 返回刚刚创建的状态
}
else
{
// printf("定时器数量到达最大\n");
return TIM_CRAT_ERROR;
}
}
/**
*@bref 启动一次定时器
* 计时结束自动销毁定时器
* **/
state_t start_once_timer(u16 ID, u32 count, state_t state)
{
uint8_t i = 0;
uint8_t first_i = 0;
uint8_t flag = NULL_ID;
if (ID == 0 || count == 0)
{
return TIM_DESTROYED;
}
if (!OPEN_COUNTER)
{
counter_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id.id_ary[i].id == ID)
{
first_i = i;
flag = OLD_ID; // 查找相同ID
if (timer_id.id_ary[i].state == TIM_LOCK)
{
return TIM_LOCK;
}
break;
}
if ((timer_id.id_ary[i].id == ID_CLEAR) && (!flag))
{
first_i = i;
flag = NEW_ID; // 查找并记录空闲ID
}
}
if (!flag)
{
return TIM_CRAT_ERROR; // 防止未查找到
}
if ((timer_id.timer_last_index) < MAX_TIMER_NUM)
{
timer_id.id_ary[first_i].id = ID; // ID
timer_id.id_ary[first_i].count = START_COUNT; // 计数初始值
timer_id.id_ary[first_i].state = state; // 刚刚创建或启动
timer_id.id_ary[first_i].target = count;
timer_id.id_ary[first_i].end_state = TIM_ONCE;
timer_id.id_ary[first_i].rtn_func = NULL;
if (flag == NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
// printf("(%d)",MAX_USE_NUMBER);
}
if (++timer_id.timer_last_index >= MAX_USE_NUMBER) // 新增一个ID ,进行+1计数
{
timer_id.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CREATED; // 返回刚刚创建的状态
}
else
{
// printf("定时器数量到达最大\n");
return TIM_CRAT_ERROR;
}
}
state_t start_cb_timer(u16 ID, u32 count, state_t run_state, state_t end_state, rtn_func_t rtn_func)
{
uint8_t i = 0;
uint8_t first_i = 0;
uint8_t flag = NULL_ID;
if (ID == 0 || count == 0 || rtn_func == NULL)
{
return TIM_DESTROYED;
}
if (!OPEN_COUNTER)
{
counter_init();
}
/*************查找相同ID或者直接创建****************/
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if (timer_id.id_ary[i].id == ID)
{
first_i = i;
flag = OLD_ID; // 查找相同ID
if (timer_id.id_ary[i].state == TIM_LOCK)
{
return TIM_LOCK;
}
break;
}
if ((timer_id.id_ary[i].id == ID_CLEAR) && (!flag))
{
first_i = i;
flag = NEW_ID; // 查找并记录空闲ID
}
}
if (!flag)
{
return TIM_CRAT_ERROR; // 防止未查找到
}
if ((timer_id.timer_last_index) < MAX_TIMER_NUM)
{
timer_id.id_ary[first_i].id = ID; // ID
timer_id.id_ary[first_i].count = START_COUNT; // 计数初始值
timer_id.id_ary[first_i].state = run_state; // 刚刚创建或启动
timer_id.id_ary[first_i].target = count;
timer_id.id_ary[first_i].end_state = end_state;
timer_id.id_ary[first_i].rtn_func = rtn_func;
if (flag == NEW_ID)
{
if (first_i >= MAX_USE_NUMBER)
{
MAX_USE_NUMBER = first_i + 1;
// printf("(%d)",MAX_USE_NUMBER);
}
if (++timer_id.timer_last_index >= MAX_USE_NUMBER) // 新增一个ID ,进行+1计数
{
timer_id.timer_last_index = MAX_USE_NUMBER;
}
}
return TIM_CREATED; // 返回刚刚创建的状态
}
else
{
// printf("定时器数量到达最大\n");
return TIM_CRAT_ERROR;
}
}
/*
@bref 关掉定时器,
TIM_SUSPEND 定时器不销毁,计数暂停
TIM_DESTROYED 销毁定时器,ID将被抹去
*/
state_t close_timer(u16 ID, state_t state)
{
uint8_t i = 0;
if (ID == 0)
{
return TIM_DESTROYED;
}
for (i = 0; i < MAX_USE_NUMBER; i++)
{
if (timer_id.id_ary[i].id == ID)
{
break;
}
}
if (i >= MAX_USE_NUMBER)
{
return TIM_DESTROYED;
}
if (state == TIM_SUSPEND)
{ // 暂停定时器,也就是关掉的意思
/***暂停定时器**** 查看是否有相同ID ********/
if ((timer_id.id_ary[i].id) == ID)
{
timer_id.id_ary[i].id = ID; // ID不能抹去
timer_id.id_ary[i].count = END_COUNT; // 计数初始值
timer_id.id_ary[i].state = TIM_SUSPEND; // 挂起定时器
timer_id.id_ary[i].end_state = TIM_SUSPEND; //
timer_id.id_ary[i].target = END_COUNT;
return TIM_SUSPEND; // 返回刚刚创建的状态
}
}
else if (state == TIM_DESTROYED)
{ // 销毁定时器
/****销毁定时器*** 查看是否有相同ID ********/
if ((timer_id.id_ary[i].id) == ID)
{
timer_id.id_ary[i].id = ID_CLEAR; // 清空ID
timer_id.id_ary[i].count = END_COUNT;
timer_id.id_ary[i].state = TIM_DESTROYED; // 定时器还未创建状态
timer_id.id_ary[i].end_state = TIM_DESTROYED;
timer_id.id_ary[i].target = END_COUNT;
timer_id.id_ary[i].rtn_func = NULL;
if (timer_id.timer_last_index > 0)
{
timer_id.timer_last_index--;
}
// printf("delet_timer:%d ",ID);
if (timer_id.id_ary[MAX_USE_NUMBER - 1].state == TIM_DESTROYED)
{
MAX_USE_NUMBER--;
// printf("(%d)",MAX_USE_NUMBER);
}
return TIM_DESTROYED; // 返回刚刚创建的状态
}
}
return TIM_DESTROYED;
}
/**
*@bref 返回定时器状态
有此ID的定时器就返回当前状态
没有就返回DESTROYED
* **/
state_t timer_state(u16 ID)
{
u8 i = 0;
if (ID == 0)
{
return TIM_DESTROYED;
}
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if ((timer_id.id_ary[i].id) == ID)
{
return timer_id.id_ary[i].state; // 定时器状态
}
}
return TIM_DESTROYED;
}
/*
@bref 查询计数值
*/
u32 timer_count_value(u16 ID)
{
u8 i = 0;
if (ID == 0)
{
return END_COUNT;
}
for (i = 0; i < MAX_TIMER_NUM; i++)
{
if ((timer_id.id_ary[i].id) == ID)
{
return timer_id.id_ary[i].count; // 定时器状态
}
}
return END_COUNT;
}
使用例程
//!定时回调函数样例
void myrtn(void) //自定义函数
{
printf("into _ test");
}
//!按键防抖案例
while(1){
if( !PIN_STATE(key1_pin) )
{ //检查按键是否按下
//防抖延时
if( timer_state(0x110) == TIM_END)//查看防抖计时是否结束
{
close_timer(0x110,TIM_DESTROYED); //销毁定时器
//do something ,执行用户按下按键之后的事情
}else
{
start_timer(0x110,60,TIM_LOCK); //开启一个防抖定时器
//第一个参数是ID,第二个参数是计数值,第三个参数是计数状态
}
}else
{
close_timer(0x110,TIM_DESTROYED); //销毁定时器
}
//--------------------------------------
#define MY_EVENT_FLG 100
#define MY_EVENT_SLEEP_FLG 101
void Tree_Task_ProcessEvent(uint16_t events)
{
if (events == MY_EVENT_FLG)
{
LOG("MY_EVENT_FLG\n");
return;
}
if (events == MY_EVENT_SLEEP_FLG)
{
LOG("MY_EVENT_SLEEP_FLG\n");
return;
}
}
start_cb_timer(MY_EVENT_FLG,2,TIM_LOCK,TIM_CYCLE,Tree_Task_ProcessEvent);
start_cb_timer(MY_EVENT_SLEEP_FLG,2,TIM_LOCK,TIM_CYCLE,Tree_Task_ProcessEvent);