单片机的多任务处理思考
对于单片机这样一个非常基础的控制芯片,我们常常用于处理一些针对性比较强的任务,任务的性质比较简单,而且流程是按照顺序执行的,逻辑上非常直白。
现实中的情况往往比这要复杂一些
例如,显示需要定时刷新,红外接收器接受数据需要立即响应并解码,超声波的数据需要立即分析,这些情况利用中断端口的实时响应特性解决,如果端口的数量比较多,而且要求响应时间比较短,那么程序的结构就不能按照正常的顺序执行来设计。
此时,单片机的多任务处理的要求就提出来了,电脑操作系统中有多线程和多任务处理的能力,根据他们的设计思路,我们是不是可以设计出一个符合单片机特性的多任务的程序结构呢!而且对于这个多任务程序结构中不能太依赖单片机的特殊资源,原因就是方便程序的移植。
在计算机的编程中,一个基本的概念就是同时对多个任务进行控制。许多程序设计都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主程序。可以通过多种途径达到这个目的。单片机中是通过硬件级的中断实现的。尽管这是一种有效的方法,但编出的程序很难移植,这样就另外一个问题,代价高昂问题,如果所有的编程都需要从头开始编写,尽管这个问题在其他的项目中,也曾遇到过,那么时间价值就浪费掉了,所以多任务的一个基本要求就是不要太依赖硬件给予的特殊资源,其通用性的价值要体现出来。
好了,现在我们来看,为了同步完成多项任务,单片机的实际运行效率就要提上来,基础单片机的运行速度是1us,通过提高单片机的晶振频率或者采用增强型的单片机其速度可以更快!而一个单片机的所有任务流程执行下来,如果需要5秒以上,那么对于单片机的来说是难以接受的,其实我们仔细把任务的流程抛开来看的化,我们会发现,单片机的真正执行指令的时间并不长,大部分的时间都在延时程序中中空运转。
如果我们能把延时的程序,利用起来,做里外一个工作,那么我们的系统就可以实现两个任务,每个任务的如果只需要简单的逻辑判断,没有非常耗时的浮点运算(其实这也不是单片机的强项)那么我是不是可以多执行两个任务或者N个任务。我就是我想到的简单的思路。
我们现在根据单片机的特点,好好的排布一下。我们把任务的性质划分一下,如果任务之间是并列关系,我们可以称之为弱相关,如果任务之间是顺序执行关系,我们称之为强相关,即对应电路的并联和串联关系。
每个任务都是有步骤的进行,无非是步骤之间的多少不同而已!每个任务都划分好相应的时间片段,什么时候执行,什么条件执行,都有严格的规定,时间的计数交给定时器来完成。
如何划分步骤?
1.第一点根据任务要求的响应时间
2.第二点根据周期执行时间来确定
如果第一个任务完整的流程执行时间在1.5ms,而另外一个任务针对外部条件的变化,系统要求在1ms内做出响应,那么第一个任务的流程应该分为两个步骤完成,这样划分时间片段才能符合系统的时间响应要求。
file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtmlclip1/01/clip_image001.gif
如果是任务之间是并列的关系使用顺序访问是否符合执行条件。例如超声波的数据处理和红外数据的处理,两者之间没有直接的关联,我们称之为若相关,我们使用下面的流程来处理
如果任务之间是串联的关系使用寻址方式,或者称为任务调度器来进行访问
下面贴一段代码吧,项目中的一部分仅供参考
简单说明一下,用定时器做延时的技术参考,设置一个标志位做索引,延时时间到了,满足条件,步骤指针指向下一步!如果条件不满足,把当前指针压入数组做成的伪堆栈,同时给与指针一个空向值,如果满足条件,则把压入堆栈的数值推送给指针。
对于按键的延时检测,可能用到菜单的切换,每个菜单的界面需要做成一个任务,需用时直接当成任务对象调用即可。
void main(void)
{
bitflag_work=0;
bit flag_error_work=0;
bitflag_error_pipe_jam=0;
hard_ini();
serial_one_initial();
Pm_step=0;
while(1)
{
// get_result_volt_value();
switch(Pm_step)
{
case0:
Pm_step=1;
break;
case1:
Pm_step=2;
break;
case2:
Pm_step=0;
break;
default:break;
}
}
}
纰漏之处,可能很多,希望一块能讨论一二,我可是抛了砖了,至于能不能引来美玉,就只能祈祷了。