找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3382|回复: 1
收起左侧

适合51单片机和STM32的简易任务调度器

[复制链接]
ID:68814 发表于 2019-9-14 18:38 | 显示全部楼层 |阅读模式
这个代码是从网上看到,经过少量修改得到的,如果有侵删请告知。

  1. //===========简易任务调度器==============

  2. #define  TASK_MAX   2 //任务的数量记得匹配一下

  3. typedef struct _TASK_COMPONENTS
  4. {
  5.     unsigned char TaskNumber; //表示任务的编号
  6.                 unsigned char Run;    // 0表示任务不运行,1表示任务运行
  7.     unsigned int Timer;   // 表示任务的执行间隔时间
  8.     unsigned int ItvTime; // 参数传递作用,数值上等于Timer
  9.     void (*TaskHook)(void); //任务函数
  10. }TASK_COMPONENTS;  

  11. static TASK_COMPONENTS TaskComps[]=   //任务的编号,从0开始
  12. {   
  13.     {0,0,1000,1000, Task1}, //因为定时器是1ms的,也就是这个任务的执行间隔时间是200ms
  14.     {1,0,10,        10,  Task2}, //****按照格式可以补充你的任务****/
  15. };

  16. void TaskHangup(unsigned char Task_Num)//任务挂起函数,参数就是你的任务编号
  17. {
  18.         TaskComps[Task_Num].Run=0;
  19. }

  20. void TaskRecovery(unsigned char Task_Num)//任务恢复函数,参数就是你的任务编号
  21. {
  22.         TaskComps[Task_Num].Run=1;
  23. }

  24. void TaskRemarks(void) //放在你的定时器中断里面  定时器需要设定1ms中断一次
  25. {
  26.         unsigned char i;
  27.         for (i=0; i<TASK_MAX; i++)          // 逐个任务时间处理
  28.                         {
  29.                                          if (TaskComps[i].Timer)          // 时间不为0
  30.                                         {
  31.                                                         TaskComps[i].Timer--;         // 减去一个节拍
  32.                                                         if ((TaskComps[i].Timer == 0) ||(TaskComps[i].Timer>0XFFF0))  // 时间减完了 [/size][/indent][size=4]//如果任务执行时间比较长,可能当时间片减到0的时候任务还在执行,然后减下去就溢出,是0XFFFF
  33.                                                                                                                                                                                                                                                                                                         //所以用[/size][size=4]0XFFF0[/size][size=4]这个值保证溢出的时候也能执行下面的语句
  34.                                                         {
  35.                                                                          TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次
  36.                                                                          TaskComps[i].Run = 1;           // 任务可以运行
  37.                                                         }
  38.                                         }
  39.                  }
  40. }

  41. void TaskProcess(void)//放在你的while(1)循环里面
  42. {
  43.     unsigned char  i;
  44.                 for (i=0; i<TASK_MAX; i++)           // 逐个任务判断是否达到执行条件
  45.     {         
  46.                         if (TaskComps[i].Run)     // 达到执行条件
  47.         {
  48.              TaskComps[i].Run = 0;     // 标志清0  把这句话放下面会出现异常 原因暂未查明
  49.                                                  TaskComps[i].TaskHook();  // 运行任务
  50.         }
  51.     }   
  52.                 MCU_IDLE();//进入低功耗模式
  53. }[/size]</font>
复制代码
一些说明:
1、MCU_IDLE();//进入低功耗模式  32和51的低功耗函数是不一样的,这里只是提供一种低功耗的思路,比如51低功耗函数直接操作PCON寄存器,定时器中断会唤醒,唤醒后会执行TaskRemarks函数,判断任务时间是否到了,到了标志位置1。
2、Task1等函数具体可以更换为自己的任务函数名称,但是在这个文件内使用的话记得加extern声明一下是外部函数。
3、这个调度器实际上就是一个定时器做事件的时间基准,建议任务函数内部的延时时间不要大于任务执行的间隔时间。因为实际的执行过程一定是任务0先执行(即使里面有长延时函数),接着执行任务1,任务2等。


总结:该调度器只是简单按照任务次序轮询,无法按照任务执行的间隔时间做实时切换。对于大部分对任务执行时间精确度要求不高的场合,是比较好用的。这样的架构也会使代码相对简洁一些。





回复

使用道具 举报

ID:807361 发表于 2023-6-24 22:37 | 显示全部楼层
思路好像还不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表