本帖最后由 liuchang 于 2017-5-11 15:33 编辑
1>额,这个不是我原创,代码呢,也是我在网上东拼西凑的(在此感谢网上所有好心人...),如果有人觉得可以用,甚至好用,那是最好不过.如果使用过程中发现某些bug,还请各位神不惜赐教...
2>不用说,以某人目前的能力,不可能写出惊天的代码,本着难度可控的原则,本代码中没有使用类似ucos,lwip中的实现方式,直白点,能力不够(先想到,然后实现,能用即可,最后再想优化...)...
3>由于比较简单,没有搭demo版,附件只是提供.c和.h文件供各位参考.
4>软件定时器相对误差会比较大,ms级别,实时性要求如果很高,还是建议使用硬件定时器...
5>为什么需要软件定时器?
我的理解
1>硬件定时器不够用的时候
2>如果开启很多定时器并且使用中断,导致进入中断比较频繁,假设其中有个中断实时性很高,可能就因为处于其它中断中难以及时响应,就算可以中断嵌套,也会增加软件开销,并且中断管理相对复杂.
3>假设程序中仅仅需要开机3秒钟时"滴"一下,如果为这个3秒单独开个中断,似乎有点不值得.
4>假设程序中需要0.5s采集一次数据,再过0.2s将数据显示在屏上,此时使用软件定时器就比较合适,因为彼此之间有时间关联,类似于485"共模"抗干扰...
6>程序讲解
1>主要数据结构(注意,SOFT_TIMER_CALL_CYCLE =10,我在程序中定义扫描周期为10ms,这个随便弄个定时器都很容易实现吧,我就不贴出这个代码了)
[mw_shl_code=c,true]#define SOFT_TIMER_MAX_NUM 5
#define SOFT_TIMER_CALL_CYCLE 10
#define SOFT_TIMER_USE_OS 0
typedef void (*SOFT_TIMER_CB)(void *arg);
typedef enum
{
SOFT_TIMER_NO_ERR,
SOFT_TIMER_PARA_ERR,
}soft_timer_error_t;
typedef enum
{
SOFT_TIMER_STOP = 0,
SOFT_TIMER_START
}soft_timer_state_t;
typedef enum
{
SOFT_TIMER_ONLY = 0,
SOFT_TIMER_ALWAYS
}soft_timer_mode_t;
typedef struct
{
uint8_t mode;
uint8_t work;
uint8_t state;
uint32_t time;
uint32_t save;
SOFT_TIMER_CB soft_timer_cb;
void * soft_timer_arg;
}soft_timer_t;[/mw_shl_code]
2>开启软件定时器
[mw_shl_code=c,true]soft_timer_error_t soft_timer_start(uint8_t timer, uint8_t mode, uint32_t time, SOFT_TIMER_CB soft_timer_cb, void * soft_timer_arg)
{
if (timer >= SOFT_TIMER_MAX_NUM)
{
return SOFT_TIMER_PARA_ERR;
}
#if SOFT_TIMER_USE_OS
soft_timer_enter_critical();
#endif
SoftTimer[timer].time = time/SOFT_TIMER_CALL_CYCLE;
SoftTimer[timer].save = SoftTimer[timer].time;
SoftTimer[timer].mode = mode;
SoftTimer[timer].soft_timer_cb = soft_timer_cb;
SoftTimer[timer].soft_timer_arg = soft_timer_arg;
SoftTimer[timer].state = SOFT_TIMER_START;
#if SOFT_TIMER_USE_OS
soft_timer_exit_critical();
#endif
return SOFT_TIMER_NO_ERR;
}[/mw_shl_code]
3>关闭软件定时器
[mw_shl_code=c,true]soft_timer_error_t soft_timer_stop(uint8_t timer)
{
if (timer >= SOFT_TIMER_MAX_NUM)
{
return SOFT_TIMER_PARA_ERR;
}
#if SOFT_TIMER_USE_OS
soft_timer_enter_critical();
#endif
SoftTimer[timer].state = SOFT_TIMER_STOP;
#if SOFT_TIMER_USE_OS
soft_timer_exit_critical();
#endif
return SOFT_TIMER_NO_ERR;
}[/mw_shl_code]
4>这个需要在中断服务函数中实现
[mw_shl_code=c,true]void soft_timer_in_isr(void)
{
uint8_t index;
#if SOFT_TIMER_USE_OS
soft_timer_enter_critical();
#endif
for (index = 0; index < SOFT_TIMER_MAX_NUM; index++)
{
if (SoftTimer[index].state)
{
if (SoftTimer[index].time)
{
SoftTimer[index].time--;
}
else if (SoftTimer[index].time == 0)
{
SoftTimer[index].work++;
if (SoftTimer[index].mode == SOFT_TIMER_ALWAYS)
{
SoftTimer[index].time = SoftTimer[index].save;
}
else
{
SoftTimer[index].state = SOFT_TIMER_STOP;
}
}
}
}
#if SOFT_TIMER_USE_OS
soft_timer_exit_critical();
#endif
}[/mw_shl_code]
6>这部分放在while(1)中运行
[mw_shl_code=c,true]void soft_timer_porcess(void)
{
uint8_t index;
for (index=0; index<SOFT_TIMER_MAX_NUM; index++)
{
if (SoftTimer[index].work)
{
SoftTimer[index].soft_timer_cb(SoftTimer[index].soft_timer_arg);
SoftTimer[index].work--;
}
}
}[/mw_shl_code]
7>如下代码依赖具体的环境(例如我没上系统,直接关闭宏,SOFT_TIMER_USE_OS=0,不开启)
[mw_shl_code=c,true]void soft_timer_enter_critical(void)
{
}
void soft_timer_exit_critical(void)
{
}
#endif[/mw_shl_code]
一周热门 更多>