作者:云在天涯无无边_737 | 来源:互联网 | 2023-10-10 20:07
设计思想是在定时器的中断里面每次将timerSlice自减,当减到0时,表示时间片的这段时间到了,此时将isRun标志位置1,然后将sliceNumer赋值给timerSlice继续下一个时间片
设计思想是在定时器的中断里面每次将timerSlice自减,当减到0时,表示时间片的这段时间到了,此时将isRun标志位置1,然后将sliceNumer赋值给timerSlice继续下一个时间片的自减指针赋值。当isRun标志为,就开始执行对应task结构体的pTask函数指针指向的函数体。
typedef struct
unsigned char isRun; //表示任务是否在运行
unsigned int timerSlice;//分配给任务的时间片
unsigned int sliceNumber;//时间片的个数
void (*pTask)(void); //任务的函数指针
}Task_t;
【2】定义task任务数组指针赋值,并计算任务个数
Task_t tasks[]=
{0,100,100,DoTask1;}
{0,200,200,DoTask2;}
{0,300,300,DoTask3;}
unsigned int taskCount=sizeof(tasks)/sizeof(Task_t);
【3】时间片自减函数指针赋值,检查时间片是否到了,如果到了,就置位运行标志isRun
void Task_TimerSlice_Decrease()
unsigned char i = 0;
for (i = 0; i if (tasks[i].timerSlice)//判断时间片是否到指针赋值了
展开全文
tasks[i].timerSlice--;
if (tasks[i].timerSlice==0)//时间片到指针赋值了
tasks[i].isRun = 1; //置位 表示任务可以执行
//重新加载时间片值指针赋值,为下次做准备
tasks[i].timerSlice = tasks[i].sliceNumber;
【4】循环检查任务数组中的标志位指针赋值,如果isRun为1,就执行函数指针pTask指向的函数
void Task_Process()
unsigned char i = 0;
for (i = 0; i if (tasks[i].isRun)//若任务可执行指针赋值,则执行任务
tasks[i].isRun = 0; //将标志位清零
tasks[i].pTask();
【5】定义task结构体中指针函数所指向的函数体指针赋值,每个任务要执行的内容
void DoTask1() { LED1 = ~LED1;}
void DoTask2() { LED2 = ~LED2;}
void DoTask3() { LED3 = ~LED3;}
通过以上5步指针赋值,就完成了此框架的所有代码,应用上需要注意的地方
(1)Task_TimerSlice_Decrease()函数是对时间片变量 timerSlice自减指针赋值,一定要放在定时器函数中
void Timer0_ISR() interrupt 1
TL0 = 0x00; //设置定时初值
TH0 = 0xEE; //设置定时初值
Task_TimerSlice_Decrease();
(2)Task_Process()是循环对任务数组中的isRun进行判断指针赋值,如果为1,就执行对应的task,这个函数要放在main函数中的死循环里
void main()
//系统初始化
System_Init();
while(1)
Task_Process();
(3)每个task的任务执行时间要控制好指针赋值,如果其中一个task任务执行时间过长,那么会影响到其他task的执行,要避免这种情况,尽量将执行很长的task进行分割成很多小task
本次代码范例仿真结果如下
可以看出,这个和上篇文档的前后台系统执行效果是完全一样的指针赋值。举例说明,我定义的task1的时间片数字是100,对应间隔执行时间是5ms*100=500ms,如下所示,非常吻合。
刚才提到指针赋值,如果其中1个task执行时间过长,会对其他task有影响,那么我演示下实际效果,
故意将task1加一个delay指针赋值,模拟其执行时间是2s,然后才去执行其他task.
void DoTask1() { LED1 = ~LED1;Delay_ms(2000);}
可以看出,此时task1、task2、task3的频率已经全部是2秒翻转1次,和之前预设的目标相差甚远指针赋值。这是因为在执行task1任务时,因为其执行时间为2s,大于task2/task3定时时间,所以在2s内,task2和task3的isRun都为1了,当轮询时,task1执行完,会马上执行task2/task3,所以他们翻转频率都是一样的。
喜欢这篇文章指针赋值,帮忙点个“关注 + 收藏”哦
下一篇文章指针赋值,我会整理一份关于使用软件定时器+单链表来实现的裸机代码框架,敬请期待,谢谢!
附上源码: