首页资源分类嵌入式处理器51内核 > 如何设计复杂的多任务程序.

如何设计复杂的多任务程序.

已有 445117个资源

下载专区

文档信息举报收藏

标    签:mcu51

分    享:

文档简介

  如何设计复杂的多任务程序 

我们在入门阶段,一般面对的设计都是单一的简单的任务,流程图可以如图 1 所示,通

常会用踏步循环延时来满足任务需要。 

面对多任务,稍微复杂的程序设计,沿用图 1 的思想,我们会做出如图 2 所示的程序,

在大循环体中不断增加任务,通常还要用延时来满足特定任务节拍,这种程序设计思想它有

明显的不足,主要是各个任务之间相互影响,增加新的任何之后,以前很好的运行的任务有

可能不正常,例如数码管动态扫描,本来显示效果很好的驱动函数,在增加新的任务后出现

闪烁,显示效果变差了。 

  

 

(原文件名:1.JPG) 

图1 单一任务简单流程图            图2 多任务简单流程图 

很明显,初学者在设计程序时,需要从程序构架思想上下功夫,在做了大量基本模块练

习之后,需要总结提炼自己的程序设计思路(程序架构思想)。 

首先我们来理解“任务”,所谓任务,就是需要 CPU 周期“关照”的事件,绝大多数任

务不需要 CPU 一直“关照” ,例如启动 ADC 的启动读取。甚至有些任务“害怕”CPU 一直

“关照”例如 LCD 的刷新,因为 LCD 是显示给人看的,并不需要高速刷新,即便是显示的 

内容在高速变化,也不需要高速刷新,道理是一样的。这样看来,让CPU做简单任务一定很

浪费,事实也是如此,绝大多数简单任务,CPU都是在“空转” (循环踏步延时) 。对任务总

结还可以知道,很多任务需要 CPU 不断“关照” ,其实这种“不断”也是有极限的,比如数

码管动态扫描,能够做到40Hz 就可以了,又如键盘扫描,能够做到20Hz(经验值),基本上

也就不会丢有效按键键值了,再如LCD刷新,我觉得做到 10Hz 就可以了,等等。看来,绝

大多数任务都是工作在低速频度。而我们的CPU一旦运行起来,速度又很快,CPU本身就是

靠很快的速度执行很简单的指令来胜任复杂的任务(逻辑)的。如果有办法把“快”的 CPU

分成多个慢的CPU,然后给不同的任务分配不同速度的CPU,这种设想是不是很好呢!确实

很好,下面就看如何将“快”的CPU划分成多个“慢”的 CPU。 

根据这种想法,我们需要合理分配CPU资源来“关照”不同的任务,最好能够根据任务

本身合理占用CPU资源,首先看如图 3 所示的流程图,各个任务流程独立,各任务通过全局

变量来交互信息,在流程中有一个重要的模块“任务切换”,就是任务切换模块实现 CPU 合

理分配,这个任务切换模块是怎么实现的呢? 

文档预览

                                          如何设计复杂的多任务程序  我们在入门阶段,一般面对的设计都是单一的简单的任务,流程图可以如图 1 所示,通 常会用踏步循环延时来满足任务需要。  面对多任务,稍微复杂的程序设计,沿用图 1 的思想,我们会做出如图 2 所示的程序, 在大循环体中不断增加任务,通常还要用延时来满足特定任务节拍,这种程序设计思想它有 明显的不足,主要是各个任务之间相互影响,增加新的任何之后,以前很好的运行的任务有 可能不正常,例如数码管动态扫描,本来显示效果很好的驱动函数,在增加新的任务后出现 闪烁,显示效果变差了。     (原文件名:1.JPG)  图1 单一任务简单流程图                 图2 多任务简单流程图  很明显,初学者在设计程序时,需要从程序构架思想上下功夫,在做了大量基本模块练 习之后,需要总结提炼自己的程序设计思路(程序架构思想)。  首先我们来理解“任务”,所谓任务,就是需要 CPU 周期“关照”的事件,绝大多数任 务不需要 CPU 一直“关照” ,例如启动 ADC 的启动读取。甚至有些任务“害怕”CPU 一直 “关照”例如 LCD 的刷新,因为 LCD 是显示给人看的,并不需要高速刷新,即便是显示的  内容在高速变化,也不需要高速刷新,道理是一样的。这样看来,让CPU做简单任务一定很 浪费,事实也是如此,绝大多数简单任务,CPU都是在“空转” (循环踏步延时) 。对任务总 结还可以知道,很多任务需要 CPU 不断“关照” ,其实这种“不断”也是有极限的,比如数 码管动态扫描,能够做到40Hz 就可以了,又如键盘扫描,能够做到20Hz(经验值),基本上 也就不会丢有效按键键值了,再如LCD刷新,我觉得做到 10Hz 就可以了,等等。看来,绝 大多数任务都是工作在低速频度。而我们的CPU一旦运行起来,速度又很快,CPU本身就是 靠很快的速度执行很简单的指令来胜任复杂的任务(逻辑)的。如果有办法把“快”的 CPU 分成多个慢的CPU,然后给不同的任务分配不同速度的CPU,这种设想是不是很好呢!确实 很好,下面就看如何将“快”的CPU划分成多个“慢”的 CPU。  根据这种想法,我们需要合理分配CPU资源来“关照”不同的任务,最好能够根据任务 本身合理占用CPU资源,首先看如图 3 所示的流程图,各个任务流程独立,各任务通过全局 变量来交互信息,在流程中有一个重要的模块“任务切换”,就是任务切换模块实现 CPU 合 理分配,这个任务切换模块是怎么实现的呢?  (原文件名:2.JPG)  图3 多任务复杂流程图  首先需要理解,CPU 一旦运行起来,就无法停止(硬件支持时钟停止的不在这里讨论),  谁能够控制一批脱缰的马呢?对了,有中断,中断能够让CPU回到特定的位置,设想,能不 能用一个定时中断,周期性的将 CPU这匹运行着的脱缰的马召唤回来,重新给它安排特定的 任务,事实上,任务切换就是这样实现的。  (原文件名:3.JPG)  图 4  定时中断实现任务切换  如图 4A 所示,CPU 在空闲任务循环等待,定时中断将 CPU 周期性唤回,根据任务设计 了不同的响应频度,满足条件的任务将获得CPU资源,CPU为不同任务“关照”完成后,再 次返回空闲任务,如此周而复始,对于各个任务而言,好像各自拥有一个独立的CPU,各自  独立运行。用这种思想构建的程序框架,最大的好处是任务很容易裁剪,系统能够做得很 杂。  在充分考虑单片机中断特性(在哪里中断就返回到哪里)后,实际可行的任务切换如图 4B所示,定时中断可能发生在任务调度,随机任务执行的任何时候,图中最大的框框所示, 不管中断在何时发生,它都会正常返回,定时中断所产生的影响只在任务调度模块起作用, 即依次让不同的任务按不同的节拍就绪。任务调度会按一定的优先级执行就绪任务。  总结不同的任务需要CPU关照的频度,选择最快的那个频度来设定定时器中断的节拍, 一般选择 200Hz,或者 100Hz 都可以。另外再给每个任务设定一个节拍控制计数器 C,也就 是定时器每中断多少次后执行任务一次。例如取定时中断节拍为 200Hz,给任务设定的 C=10, 则任务执行频度为 200/10=20Hz,如果是数码管扫描,按 40Hz 不闪烁规律,则任务节拍控制 计数器 C=5 即可。在程序设计中,C 代表着任务运行的节拍控制参数,我们习惯用 delay 来 描述,不同的任务用task0,task1……来描述。  明天继续写如何用代码实现!2009-6-29  下面我们来用代码实现以上多任务程序设计思想。  首先是任务切换  while(1)  {  if(task_delay[0]==0)   task0();  //task0就绪,  if(task_delay[1]==0)   task1();  //task1就绪,  ……  }  很显然,执行任务的条件是任务延时量task_delay=0,那么任务延时量谁来控制呢?定时 器啊!定时器中断对任务延时量减一直到归零,标志任务就绪。当没有任务就绪时,任务切 换本身就是一个Idle 任务。  void timer0(void) interrupt 1  {  if(task_delay[0]) task_delay[0]--;  if(task_delay[1]) task_delay[1]--;  ……  }  例如 timer0 的中断节拍为 200Hz,task0_delay 初值为 10,则 task0()执行频度为 200/10=20Hz。  有了以上基础,我们来设计一个简单多任务程序,进一步深入理解这种程序设计思想。 任务要求:用单片机不同 IO 脚输出 1Hz,5Hz,10Hz,20Hz 方波信号,这个程序很短,将 直接给出。  #include "reg51.h"  #define TIME_PER_SEC 200    //定义任务时钟频率,200Hz  #define CLOCK 22118400    //定义时钟晶振,单位Hz   #define MAX_TASK 4      //定义任务数量  extern void task0(void);  //任务声明  extern void task1(void);  extern void task2(void);  extern void task3(void);  sbit f1Hz  = P1^0;  //端口定义  sbit f5Hz  = P1^1;  sbit f10Hz = P1^2;  sbit f20Hz = P1^3;  unsigned char task_delay[4];  //任务延时变量定义  //定时器0初始化  void timer0_init(void)  {      unsigned char i;     for(i=0;i

Top_arrow
回到顶部
EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。