接上篇:时驱函数了解一下
前一篇帖子我写了时驱函数的设计本质是一种前后台程序,本文依旧如故。后台程序放到定时器里面,周期性的调用。这个程序程序是扫描一个链表,链表中每一个成员 噢 应该说没一个节点都设计好数据的结构体,到达设定的时间就执行回调函数。
功能:完成约定时间调用回调函数。
头文件:
- #ifndef _TIMELIST_H_
- #define _TIMELIST_H_
- #include "sys.h"
- typedef struct _time
- {
- void *next;//指向后一个
- uint8_t handle;//自己的ID号
- uint8_t start;//开关1开0关
- uint32_t cnt;//累计次数的变量
- uint32_t time_out;//设定次数的常量
- void (*fun)(void);//计数达到以后做啥的函数
- }time_type;
- typedef void (*time_call_back)(void);
- typedef struct
- {
- uint8_t (*creat) ( uint32_t time_out ,uint8_t start, time_call_back call_back);
- uint8_t (*stop) ( uint8_t handle);
- uint8_t (*start) ( uint8_t handle);
- }time_ops_type;
- extern time_ops_type timer;
- void timer_isr( void );
- #endif
复制代码 看这个头文件基本就能懂一大半了。每个节点的6个成员我都批注了,handle这个词语意思很宽 ID更准确。
- #include "timelist.h"
- #include "malloc.h"
- #define NULL 0
- enum
- {
- false,
- true
- };
- uint8_t timerTaskId = 0;//全局变量 每个节点的ID号从0开始
- time_type *time = NULL; //链表的头 第一个节点
- void timer_isr( void )
- {
- time_type *priv = time;
- while( priv != NULL )
- {
- if( priv->start)//这个节点是开的 就进去 否则pass
- {
- if( ++priv->cnt >= priv->time_out)//进来累计一次 直达到达约定设定值
- {
- priv->cnt = 0;
- if(priv->fun != NULL)
- priv->fun();
- }
- }
- priv = priv->next;
- }
- }
- //只有malloc没有free 我没有释放
- //返回void*
- void *timer_malloc(int size)
- {
- return mymalloc(SRAMIN,sizeof(time_type));
- }
- uint8_t timer_stop_time(uint8_t handle)
- {
- time_type *priv = time;
-
- while( priv != NULL )
- {
- if( priv->handle == handle)
- {
- priv->start = false;
- priv->cnt = 0;
- return true;
- }
- priv = priv->next;
- }
-
- return false;
- }
- uint8_t timer_start_time(uint8_t handle)
- {
- time_type *priv = time;
-
- while( priv != NULL )
- {
- if( priv->handle == handle)
- {
- priv->start = true;
- return true;
- }
- priv = priv->next;
- }
-
- return false;
- }
- uint8_t timer_register_isr( uint32_t time_out ,uint8_t start, time_call_back call_back)
- {
- time_type *priv;
- time_type *this;
- this = (time_type *)timer_malloc(sizeof(time_type));
- if( this != NULL)
- {
- this->cnt = 0;
- this->start = start;
- this->handle = timerTaskId++;
- this->time_out = time_out;
- this->fun = call_back;
- this->next = NULL;
- if( time == NULL)
- {
- time = this;
- }
- else
- {
- priv = time;
- while( priv->next != NULL ) priv = priv->next;
- priv->next = this;
- }
- }
- else
- {
- return 0xFF;
- }
- return (this->handle);
- }
- //KEIL不支持该写法??
- //time_ops_type timer =
- //{
- // .creat = timer_register_isr,
- // .stop = timer_stop_time ,
- // .start = timer_start_time,
- //};
- time_ops_type timer =
- {
- timer_register_isr,
- timer_stop_time ,
- timer_start_time,
- };
复制代码 实现如上 因为用了链表需要malloc函数 我没有用C库 而是自己写的内存分配模块
举一个例子吧
int IDID=0;
int wang=0;
void saywang(void)
{
wang++;
if(wang==4)
timer.stop(IDID);
}
void Business_Init(void)
{
IDID=timer.creat(100,1,saywang);
。。。。。
}
初始化的时候创建了一个定时器节点,时间是100个节拍,1是直接打开,到达设定时间就会调用saywang函数。
可以在找一个条件比较按键来 timer.start(IDID); 再次打开这个节点功能。
而后天程序放到it.c即可
void TIM3_IRQHandler(void)
{
static char count=0;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
timer_isr( );
}
|