定时器--函数链表

struct _Timing
{
    void(*Timing)(void);
    struct _Timing *Next;
};
static struct _Timing * TimingHead = NULL;

//列表函数遍历运行
static void Run_Timing(void)
{
    struct _Timing *current  = TimingHead;
    while(current !=NULL)
    {
        if(current->Timing)current->Timing();
        current = current->Next;
    }
}
//函数加入列表
void PushTiming(void(*timing)(void))
{
    struct _Timing* new_node  = TimingHead;
    struct _Timing** head_ref = &TimingHead;

    //遍历链表,排除重复函数
    while(new_node !=NULL)
    {
        if(new_node->Timing == timing)return ;
        new_node = new_node->Next;
    }
    #if 1  //空间已经分配好(限制10数量)
    static struct _Timing  Node[10] = {0}; //函数内部全局变量
    static u8 Cnt                   = 0;   //分配数量
    new_node = NULL;
    if(Cnt<sizeof(Node)/sizeof(Node[0]))
    {
        new_node = NULL;
        new_node = &Node[Cnt++];
        //链表头插入函数
        new_node->Timing = timing;
        new_node->Next = (*head_ref);
        *head_ref = new_node;
    }else{
        COM_Printf("Timing分配空间失败,请增加空间\r\n");
    }
    #else //空间需要malloc分配
    new_node = NULL;
    new_node = (struct _Timing*) malloc(sizeof(struct _Timing));
    if(new_node!=NULL){
        //链表头插入函数
        new_node->Timing = timing;
        new_node->Next = (*head_ref);
        *head_ref = new_node;
    }else{
        COM_Printf("Timing分配空间失败\r\n");
    }
    #endif
}


//定时器中断
void TIM2_IRQHandler(void)  // TIM3中断//==1ms中断
{
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIMx更新中断标志
    LED_Toggle(); //LED控制
    Run_Timing();         //队列定时器回调
  }  //中断中
}

使用

void Timing1(void)
{
    /*code*/
}

在初始化时加入定时器队列
PushTiming(Timing1);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中,可以使用链表来实现软件定时器,常用的方法是将定时器按照时间先后顺序加入到链表中,然后在主程序中不断遍历链表,查找是否有定时器时间已到期,如果有则执行相应的任务并将该定时器链表中删除。 以下是一个简单的使用链表增加软件定时器的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> struct timer_node { int time_left; // 定时器剩余时间 void (*handler)(void*); // 定时器处理函数 void *arg; // 定时器参数 struct timer_node *next; // 链表指针 }; struct timer_node *timer_list = NULL; // 定时器链表 void timer_handler(int signum) { struct timer_node *p = timer_list; while (p != NULL) { if (p->time_left > 0) { p->time_left--; if (p->time_left == 0) { p->handler(p->arg); // 执行定时器处理函数 } } p = p->next; } } void add_timer(int ms, void (*handler)(void*), void *arg) { struct timer_node *node = (struct timer_node*)malloc(sizeof(struct timer_node)); node->time_left = ms / 10; // 将ms转换为10ms的单位 node->handler = handler; node->arg = arg; node->next = NULL; struct timer_node *p = timer_list; struct timer_node *prev = NULL; while (p != NULL) { if (node->time_left <= p->time_left) { if (prev == NULL) { timer_list = node; } else { prev->next = node; } node->next = p; p->time_left -= node->time_left; return; } else { node->time_left -= p->time_left; prev = p; p = p->next; } } if (prev == NULL) { timer_list = node; } else { prev->next = node; } struct itimerval timer; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 10 * 1000; // 定时器时间间隔为10ms timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 10 * 1000; setitimer(ITIMER_REAL, &timer, NULL); // 设置定时器 } void delete_timer(void (*handler)(void*), void *arg) { struct timer_node *p = timer_list; struct timer_node *prev = NULL; while (p != NULL) { if (p->handler == handler && p->arg == arg) { if (prev == NULL) { timer_list = p->next; } else { prev->next = p->next; } free(p); return; } else { prev = p; p = p->next; } } } void task1(void *arg) { printf("Task 1 executed.\n"); add_timer(2000, task1, NULL); // 重新添加定时器 } void task2(void *arg) { printf("Task 2 executed.\n"); } int main() { signal(SIGALRM, timer_handler); // 注册信号处理函数 add_timer(1000, task1, NULL); // 添加定时器1 add_timer(500, task2, NULL); // 添加定时器2 printf("Waiting for timer to expire...\n"); while (1) { pause(); // 等待信号 } return 0; } ``` 在上述代码中,定义了一个结构体timer_node作为定时器链表的节点,包含定时器剩余时间、定时器处理函数定时器参数和链表指针。使用timer_list来存储定时器链表。 在定时器处理函数timer_handler中,遍历链表,查找是否有定时器时间已到期,如果有则执行相应的任务并将该定时器链表中删除。 在add_timer函数中,将新的定时器按照时间先后顺序加入到链表中,并根据定时器时间间隔设置定时器的时间和时间间隔。 在delete_timer函数中,从链表中删除指定的定时器。 在主程序中,添加了两个定时器task1和task2,分别在1000ms和500ms后执行。在task1的处理函数中,重新添加了一个2000ms的定时器。 需要注意的是,软件定时器的精度和稳定性可能受到系统负载、CPU占用率等因素的影响,因此在设计和使用时需要考虑到这些因素。此外,还需要注意定时器的时间间隔不能太小,否则会影响系统的正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值