记录学习github上优秀轮子:
采用单向链表来实现多个定时器的调用、停用、定时处理函数。适合裸奔的单片机。
思路
初始化定时器
定时器的结构体
typedef struct Timer {
uint32_t timeout; //第一次超时时间
uint32_t repeat; //重复时间
void (*timeout_cb)(void);//定时处理函数
struct Timer* next;//单链表
}Timer;
启动/停止定时器
启动的过程就是将该定时器添加到单向列表中,在主循环遍历定时器列表,发现超时调动定时函数;
同理停止定时器,即为移除单向列表;
需要实现的接口
当前时刻的时间数据更新;在定时器中调用;
关于单向链表
全局的 HEAD 变量指针;
删除使用二级指针
XX变量的指针就是XX变量的地址;指针变量就是存放某类数据地址的变量;
为了满足所有节点的遍历
使用一级指针也是可以,只是对第一个元素需要单独的处理(无法在遍历中改变头指针);
void delItem3(struct Timer* handle)
{
struct Timer* p = head_handle;
//需要对第一个元素进行特殊处理,严格意义上有bug
if( p == handle)
head_handle = handle->next;
while(p)
{
if(p->next == handle)
{
printf("timer:%d\r\n",p);
p->next = handle->next;
}
else
{
p = p->next;
}
}
}
使用二级指针就可以从头开始遍历+操作
void delItem1(struct Timer* handle)
{
struct Timer** p = &head_handle;
while(*p)
{
if(handle == *p)
{
printf("timer:%d\r\n",*p);
*p = handle->next;
}
else
{
p = &((*p)->next);
}
}
}
对于指针有意义就是间接操作
想要修改“被传入的参数”本身,需要使用该参数的指针,进行间接访问(参数的传递是值传递,传进来的数据本身是个副本,不是真身);
如果这个参数是个指针,则要使用指针的指针。
int ff = 32,gg =30;
void change(int* tt)
{
tt = &ff;
}
void main() {
int* ss = ≫
printf("init %d - %d\n", ss,*ss);
change(ss);
printf("change %d - %d\n", ss,*ss);
ss = &ff;
printf("last %d - %d\n", ss,*ss);
}
output:
init 4206612 - 30
change 4206612 - 30
last 4206608 - 32