本帖最后由 水漫金山2017 于 2019-12-3 10:07 编辑
前一篇文章,我们直接用代码实现了系统节拍时间的产生。其实节拍时间不是一个新的概念,这和操作系统中所提及的时间片是一个含义。那在单片机程序设计中,你真的会利用好这个时间片吗?怎样设置时间片长度比较合理?如合利用好这个时间片,就就是本节内容要讨论的内容。
经常看到有同事这样利用时间片,我看着就特别心疼,好好的CPU时间,就被浪费了。
void main(void)
{
//系统初始化
for(;;)
{
if(Clock.Tick)
{
if(++Clock.Cnt20ms >= 10)
{
Clock.Cnt20ms = 0;
Task_20ms();
}
if(++Clock.Cnt100ms >= 100)
{
Clock.Cnt100ms = 0;
Task_100ms();
}
//添加其它周期性任务
}
}
}
这咋起来看没啥问题,每个任务都在指定周期到了,才会运行。仔细分析起来,这是一种非常粗糙的分时调度写法。任务多了,其各任务都得不到按时的响应。为简单明了,我直接指出这种写法存在的问题:
1、浪费了许多节拍时间
2、任务重叠太多,与我们所设计的一个节拍只执行一个任务相违背
为了让更多的任务可以享受每一次节拍时间的到来,我们应该对这个程序程序稍微改动一下:
理论知识:
假设我们设定的节拍时间为2ms,那么我们可以并发执行20/2=10个20ms周期的任务;500ms以此类推。是的,理论就是这么简单。
现在开始我们的改造:
if(Clock.Cnt20ms == 0) //周期20ms的任务
{
Task0();
}
else if(Clock.Cnt20ms == 1)
{
Task1();
}
else if(Clock.Cnt20ms == 2)
{
Task2();
}
else if(Clock.Cnt20ms == 3)
{
Task3();
}
else if(Clock.Cnt20ms == 4)
{
Task4();
}
else if(Clock.Cnt20ms == 5)
{
Task5();
}
else if(Clock.Cnt20ms == 6)
{
Task6();
}
else if(Clock.Cnt20ms == 7)
{
Task7();
}
else if(Clock.Cnt20ms == 8)
{
Task8();
}
else if(Clock.Cnt20ms == 9)
{
Task9();
}
if(++Clock.Cnt20ms >= 10)
Clock.Cnt20ms = 0;
对于20ms周期的任务,这10个任务是并发的,他们的周期都是20ms,尽管起点和终点不一样。
|