刚学习单片机编程的时候,喜欢把所有的函数放到while大循环里。
代码量少的时候还凑合,代码量一大就不太好了。效率低。反应慢。
后来参考下面这本书,试着写写。效果还可以。已经用在很多项目产品里。
因为书没办法上传。喜欢的自己去弄一本吧。
- #ifndef _SCH_task_
- #define _SCH_task_
- #include "STC8Hxx.H"
- #include<stdio.h>
- #define SCH_MAX_TASKS 15 //最大任务个数,实际任务个数必须小于这个值
- typedef struct
- {
- void (*Ptask)(void); //函数指针
- u16 Delay; //延迟时标,第一次调度延时
- u16 Period; //调用函数周期,如果等于0,则表示任务为单次任务。只执行一次就删除了.
- u8 RunMe; //任务执行标志
- u8 Co_op; //任务类型,0合作式任务,1及时型任务(在中断函数里执行)
- u8 State; //任务状态,使能/失能
- }sTask;
- extern sTask xdata SCH_tasks_G[SCH_MAX_TASKS]; //定义一个结构体数组
- extern volatile u8 xdata SCH_tasks_Count; //添加成功的任务个数
- extern void SCH_Task_Init(void); //结构体数据初始化
- extern u8 SCH_Task_Add(void (*pFunction)(void),u16 Delay,u16 Period,u8 Co_op,u8 State); //添加任务
- extern void SCH_Task_Update(void); //更新任务队列
- extern void SCH_Task_Dispatch(void); //任务调度
- extern void SCH_Task_cmd(u8 NewState); //使能调度器,没有函数原型。暂时不用
- extern u8 SCH_Task_NewState(void (*pFunction)(void),u8 NewState); //设置新的任务状态
- extern u8 SCH_Task_Delete(void (*pFunction)(void)); //删除任务
- #endif
复制代码- //任务更新(放在中断函数里)
- void SCH_Task_Update()
- {
- u8 xdata i;
- for(i=0;i<SCH_tasks_Count;i++)
- {
- if(SCH_tasks_G[i].Ptask!=0)
- {
- if(SCH_tasks_G[i].Delay == 1) //如果等于0,那么:调度周期=时基x2
- {
- //任务需要运行,间隔时间到了
- if(SCH_tasks_G[i].Co_op==0)
- {
- if(SCH_tasks_G[i].State==1) //判断任务状态是否使能
- SCH_tasks_G[i].RunMe=1; //合作式任务
- }
- else
- {
- if(SCH_tasks_G[i].State==1) //判断任务状态是否使能
- SCH_tasks_G[i].Ptask();//及时型立即运行
- SCH_tasks_G[i].RunMe=0;
- if(SCH_tasks_G[i].Period == 0) //如果是单次任务,则删除
- {
- SCH_tasks_G[i].Ptask =0;
- }
- }
- if(SCH_tasks_G[i].Period != 0)
- {
- //如果不是单次任务,则等待下一个调度周期
- SCH_tasks_G[i].Delay = SCH_tasks_G[i].Period;
- }
- }
- else
- {
- //如果任务还没准备好运行,延迟减1
- SCH_tasks_G[i].Delay -= 1;
- }
- }
- }
- }
复制代码
上图.c和.h文件下载:
基于时间的调度器.zip
(614.59 KB, 下载次数: 93)
|