找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3279|回复: 22
打印 上一主题 下一主题
收起左侧

分享自己写的基于时间调度器编程架构,摆脱大循环编程方式 C语言程序

  [复制链接]
跳转到指定楼层
楼主
ID:554500 发表于 2021-10-12 12:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
刚学习单片机编程的时候,喜欢把所有的函数放到while大循环里。
代码量少的时候还凑合,代码量一大就不太好了。效率低。反应慢。
后来参考下面这本书,试着写写。效果还可以。已经用在很多项目产品里。
因为书没办法上传。喜欢的自己去弄一本吧。






  1. #ifndef _SCH_task_
  2. #define _SCH_task_

  3. #include "STC8Hxx.H"
  4. #include<stdio.h>


  5. #define SCH_MAX_TASKS 15  //最大任务个数,实际任务个数必须小于这个值

  6. typedef struct
  7. {
  8.         void (*Ptask)(void); //函数指针
  9.         u16 Delay;        //延迟时标,第一次调度延时
  10.         u16 Period;        //调用函数周期,如果等于0,则表示任务为单次任务。只执行一次就删除了.
  11.         u8 RunMe;                //任务执行标志
  12.         u8 Co_op;                //任务类型,0合作式任务,1及时型任务(在中断函数里执行)
  13.         u8 State;         //任务状态,使能/失能  
  14. }sTask;

  15. extern sTask xdata SCH_tasks_G[SCH_MAX_TASKS];        //定义一个结构体数组
  16. extern volatile u8 xdata SCH_tasks_Count;        //添加成功的任务个数

  17. extern void SCH_Task_Init(void);  //结构体数据初始化
  18. extern   u8 SCH_Task_Add(void (*pFunction)(void),u16 Delay,u16 Period,u8 Co_op,u8 State);  //添加任务
  19. extern void SCH_Task_Update(void);   //更新任务队列
  20. extern void SCH_Task_Dispatch(void); //任务调度
  21. extern void SCH_Task_cmd(u8 NewState);  //使能调度器,没有函数原型。暂时不用
  22. extern          u8 SCH_Task_NewState(void (*pFunction)(void),u8 NewState);  //设置新的任务状态
  23. extern          u8 SCH_Task_Delete(void (*pFunction)(void));  //删除任务

  24. #endif
复制代码
  1. //任务更新(放在中断函数里)
  2. void SCH_Task_Update()
  3. {
  4.         u8 xdata i;
  5.         for(i=0;i<SCH_tasks_Count;i++)
  6.         {
  7.                 if(SCH_tasks_G[i].Ptask!=0)
  8.                 {
  9.                         if(SCH_tasks_G[i].Delay == 1)                //如果等于0,那么:调度周期=时基x2
  10.                         {
  11.                                  //任务需要运行,间隔时间到了
  12.                                  if(SCH_tasks_G[i].Co_op==0)
  13.                                  {
  14.                                           if(SCH_tasks_G[i].State==1)  //判断任务状态是否使能
  15.                                                         SCH_tasks_G[i].RunMe=1;        //合作式任务
  16.                                  }
  17.                                  else
  18.                                  {
  19.                                                 if(SCH_tasks_G[i].State==1)  //判断任务状态是否使能
  20.                                                         SCH_tasks_G[i].Ptask();//及时型立即运行
  21.                                           SCH_tasks_G[i].RunMe=0;
  22.                                           if(SCH_tasks_G[i].Period == 0) //如果是单次任务,则删除
  23.                                           {
  24.                                                 SCH_tasks_G[i].Ptask =0;
  25.                                            }
  26.                                   }
  27.                                 if(SCH_tasks_G[i].Period != 0)
  28.                                 {
  29.                                         //如果不是单次任务,则等待下一个调度周期
  30.                                         SCH_tasks_G[i].Delay = SCH_tasks_G[i].Period;        
  31.                                 }
  32.                         }
  33.                         else
  34.                         {
  35.                                 //如果任务还没准备好运行,延迟减1
  36.                                  SCH_tasks_G[i].Delay -= 1;
  37.                         }
  38.                 }
  39.         }        
  40. }
复制代码

上图.c和.h文件下载: 基于时间的调度器.zip (614.59 KB, 下载次数: 92)

评分

参与人数 2黑币 +55 收起 理由
5083 + 5 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏26 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:672792 发表于 2021-10-12 18:04 | 只看该作者
好文章,值得学习
回复

使用道具 举报

板凳
ID:712493 发表于 2021-10-12 23:59 来自手机 | 只看该作者
在读,标记,好文
回复

使用道具 举报

地板
ID:359272 发表于 2021-10-13 09:21 | 只看该作者
有点rtos的感觉,感谢分享
回复

使用道具 举报

5#
ID:554500 发表于 2021-10-13 10:02 | 只看该作者
slf252 发表于 2021-10-13 09:21
有点rtos的感觉,感谢分享

自学的,我也不咋懂这些!参考文档,随便写写。
自我感觉思路是对的,理解能力有限。
回复

使用道具 举报

6#
ID:71535 发表于 2021-10-13 20:14 | 只看该作者
#在这里快速回复#多谢楼主分享,学习一下
回复

使用道具 举报

7#
ID:744327 发表于 2021-10-14 08:26 | 只看该作者
楼主逻辑能力很好,值得学习一下。
回复

使用道具 举报

8#
ID:960619 发表于 2021-10-14 10:31 来自手机 | 只看该作者
这是不是就相当用定时器延时执行对应需要执行的任务
回复

使用道具 举报

9#
ID:554500 发表于 2021-10-14 13:44 | 只看该作者
baobao125 发表于 2021-10-14 10:31
这是不是就相当用定时器延时执行对应需要执行的任务

对的,周期性执行。
这种方式使代码简洁。效率也高。代码的可读性也清晰。
回复

使用道具 举报

10#
ID:298123 发表于 2021-10-19 13:30 | 只看该作者
实际项目不可能这样的!
回复

使用道具 举报

11#
ID:554500 发表于 2021-10-20 08:35 | 只看该作者
hz_dyg 发表于 2021-10-19 13:30
实际项目不可能这样的!

可以把你的见解贴出来啊。大家学习学习。
这几年我做的项目都用这种方式,没出什么问题。
也许不适合你的项目。把你的方法说说呗,我也想学更好的方法。
回复

使用道具 举报

12#
ID:313048 发表于 2021-10-20 10:01 | 只看该作者
这其实就是定时器定时,然后标志位置位,while循环查询标志位是否true、true就去执行该函数而已,相当于把程序复杂化了吧,只是说这样看起来在while里面的内容比较少,而实际上这个里面的内容并没有发生比较大的变化,任务线还是只有一条。
就比如
while(1)
{
if(led_flag){ LED_show();led_flag = 0;}
else if(beep_flag){ Beep_Run();beep_flag = 0;}
...
}
timer()
{
count++;
if(count==100) led_flag = 1;
else if(count == 200) beep_flag=1;
...
}
这种方式和你的是异曲同工。

不过不得不说你这种写的方式看起来比较舒服点。
慢慢来,路还很长,共同进步。
回复

使用道具 举报

13#
ID:298123 发表于 2021-10-20 10:36 | 只看该作者
18701931930 发表于 2021-10-20 08:35
可以把你的见解贴出来啊。大家学习学习。
这几年我做的项目都用这种方式,没出什么问题。
也许不适合你 ...

你可能做的是简单的项目,没有什么复杂功能的。简单的项目,用定时器,定时器中断记数去做任务标记,主循环查询任务标记做相应任务处理。稍微复杂点项目用类似tinyOS来做任务,更复杂的用类似FreeRTOS或uCOS等
回复

使用道具 举报

14#
ID:339654 发表于 2021-10-20 15:00 | 只看该作者
这本书我看过,并且跟着写了一个调度器,并且添加了串口打印调度器工作状态和系统资源使用情况
回复

使用道具 举报

15#
ID:908826 发表于 2021-10-20 17:23 | 只看该作者
里面那个及时型是不是可以打断合作型,或者换个问法,我没看出来在合作型运行的时候及时型能否打断合作型程序的运行。请楼主指点一下
回复

使用道具 举报

16#
ID:554500 发表于 2021-10-20 20:20 | 只看该作者
AUG 发表于 2021-10-20 10:01
这其实就是定时器定时,然后标志位置位,while循环查询标志位是否true、true就去执行该函数而已,相当于把 ...

谢谢指点!
回复

使用道具 举报

17#
ID:554500 发表于 2021-10-20 20:22 | 只看该作者
hz_dyg 发表于 2021-10-20 10:36
你可能做的是简单的项目,没有什么复杂功能的。简单的项目,用定时器,定时器中断记数去做任务标记,主循 ...

我只是量力而行啊。
经验需要慢慢积累!
回复

使用道具 举报

18#
ID:554500 发表于 2021-10-20 20:26 | 只看该作者
weijoyer 发表于 2021-10-20 15:00
这本书我看过,并且跟着写了一个调度器,并且添加了串口打印调度器工作状态和系统资源使用情况

书是好书,只是自己理解能力有限。
不知道这样写对不对。有时间的话,麻烦帮我看看。
回复

使用道具 举报

19#
ID:554500 发表于 2021-10-20 20:27 | 只看该作者
13205495918 发表于 2021-10-20 17:23
里面那个及时型是不是可以打断合作型,或者换个问法,我没看出来在合作型运行的时候及时型能否打断合作型程 ...

及时型是在中断里执行的
回复

使用道具 举报

20#
ID:908826 发表于 2021-10-25 08:37 | 只看该作者
前辈,方便分享一下您截图的这个工程吗?我移植失败,想对比一下看看是哪里的问题。
回复

使用道具 举报

21#
ID:554500 发表于 2021-10-25 10:57 | 只看该作者
13205495918 发表于 2021-10-25 08:37
前辈,方便分享一下您截图的这个工程吗?我移植失败,想对比一下看看是哪里的问题。

已上传!!

代码工程文件.zip

305.23 KB, 下载次数: 20, 下载积分: 黑币 -5

回复

使用道具 举报

22#
ID:908826 发表于 2021-10-25 19:33 | 只看该作者

谢谢前辈
回复

使用道具 举报

23#
ID:795427 发表于 2021-10-25 23:42 | 只看该作者
学到了中心思想,学以致用。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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