一种基于C51的多任务机制及应用

发布者:WhisperingSoul最新更新时间:2006-11-28 来源: 电子设计应用关键字:程序  代码  嵌入式 手机看文章 扫描二维码
随时随地手机看文章

引言

  传统的单片机程序一般采用单任务机制,单任务系统具有简单直观、易于控制的优点。然而由于程序只能按顺序依次执行,缺乏灵活性,只能使用中断函数实时地处理一些较短的任务,在较复杂的应用中使用极为不便。嵌入式多任务操作系统的出现解决了这个问题。在多任务系统中,可以同时执行多个并行任务,任务之间可以相互跳转。但是嵌入式操作系统在提供强大功能的同时,也带来了代码量大、结构复杂、对硬件要求较高、开发难度大且成本高等问题。而很多时候只需要实现简单的多任务操作就可以满足实际需要,本文设计的这种简单的多任务机制,在只增加极少量C语言代码的前提下,不需使用汇编,无需对原本的程序进行大改动,就可以实现多任务操作。

  实时操作系统RTOS的核心是中断,利用中断进行任务切换。在大部分RTOS如μC/OS-II中,每个任务都有自己的堆栈,用来保存任务的一些信息,任务之间通过信号量、邮箱、消息队列等传递信息。在很多情况下并不需要这些功能,只需要使单片机在接收到控制信号后,切换到不同的工作状态,也就是只要进行任务切换,不需要保存任务的相关信息。舍弃这些复杂的功能可以使程序结构变得简洁易用。

两种机制在应用实例中的比较

  下面用一个应用实例来说明本设计的思路。要设计一个智能安防系统,它的功能包括:当有人入侵时执行报警工作;用户可以通过键盘板进行功能设置;主板能与管理中心进行通讯,当发生火灾、地震等灾情时,管理中心能通知用户。其结构如图1所示。平时状态下,主板的CPU不断地扫描各个传感器的状态。当检测到传感器的异常信号(有人闯入)时,CPU进入入侵报警状态,执行响警铃、拨打户主电话、通知管理中心等工作。当发生火灾地震时,管理中心发送一个串口代码给主板CPU,使CPU进入灾难报警状态,执行响警铃、语音报警等操作。用户需要进行功能设置时可以通过键盘板使主板CPU进入功能设置状态。因此主板的CPU有4种不同的工作状态。



图1 智能安防系统结构示意图

  如果采用单任务机制, 主板的程序流程如图2所示。在主函数中循环检测传感器状态,如有异常则调用报警函数,灾难报警和功能设置在串口中断中完成。这种单任务结构有两个缺点。首先,在各种非平时状态中,程序需要不停地检测是否收到撤除信号,这个要求在程序代码量大、执行工作较多的情况下很难实现。其次,各状态之间的切换十分困难,用C语言写的程序为求模块化,一般函数数量较多,函数调用的嵌套层数也多,要从一个较深的嵌套立刻跳出到主函数,是非常困难的。一般的解决方法或是使用C51的库函数setjmp()和longjmp()实现长跳转,但是这两个函数在中断函数内部是无能为力的;再或是在C函数中嵌入汇编指令。虽然用汇编指令可以实现程序的长距离跳转,但是这种方法的调试过程十分烦琐,而且程序的可移植性差。对于习惯用C51编程而不想用汇编的设计者,该部分程序是一个难题。


图2 单任务机制程序流程

实现多任务机制的程序结构
  本文提供了一种方法,可以在完全不使用汇编指令的前提下实现可移植性强的多任务程序,程序流程如图3所示。


图3 多任务结构程序流程

  实现这个多任务机制的完整源代码如下:
word idata PC_Value, SP_Value;  //储存中断返回点、SP初值的全局变量
byte idata Ctrl_Code;       //控制任务切换的全局变量,在中断函数里被赋值
void main()
{
Initial();              //初始化函数,与程序结构无关
SP_Value=SP;        //获取SP的初始值
  PC_Value=Get_Next_PC();    //获取下一条指令的地址
EA=1;            //获取PC、SP初值后再开中断保证稳定性
if(Ctrl_Code!=0)
  SP=SP_Value;      //重置堆栈指针,防止堆栈溢出
  switch( Ctrl_Code)    //任务入口地址,即中断的返回点
{
case 1: goto TASK1;
case 2: goto TASK2;
case 3: goto TASK3;
default: break;
}
TASK1: for( ; ; )
     {   //任务1代码 }
TASK2: for( ; ; )
     { //任务2代码 }
TASK3: for( ; ; )
     { //任务2代码}
}
word Get_Next_PC(void);  //获取下一条指令的地址
{
?word address;
?address=*((unsigned char *)SP); //PC的高字节
?address <<= 8;
?address+=*((unsigned char *)(SP-1)); //PC的低字节
?return address+4;   //查看反汇编代码,计算所得
}
void Chuan_Kou_Interrupt(void) interrupt 4 using 0
{
  byte a1,a2;
a1=a1*a2;
*((unsigned char *)(SP-5))=PC_Value>>8;
*((unsigned char *)(SP-6))=PC_Value & 0x00ff;
{
  //接收串口代码并根据代码修改Ctrl_Code的值
//其他操作
}
}

任务调度原理与实现
  程序的整体思路是在主函数main中依次放置几个死循环作为任务框架,即每个任务都是一个死循环,利用中断进行任务切换。以刚才所说的安防系统为例,由于主板、键盘、管理中心之间是通过串口通讯的,因此串口是用来触发任务切换的理想中断源。程序为所有任务设置一个总入口并放在主函数中,串口中断每次返回时必须先经过这个总入口,在总入口处检查任务控制变量(全局变量)的值,任务控制变量已在串口中断中被赋值,其值决定要切换到哪个任务。

  设计中可以把平时状态、入侵报警状态、危机报警状态、功能设置状态分别作为任务1、任务2、任务3、任务4。主板CPU平常工作在平时状态,即任务1;当串口收到管理中心的危机代码,在串口中断函数中令Ctrl_Code = 3,中断返回后会切换到任务3;同样,接收到键盘的功能设置代码后,会切换到任务4;由于入侵检测是由主板CPU自己负责,因此如果检测到有人入侵需要切换到入侵报警状态时,可以借由键盘中转产生串口中断,即向键盘发送一串口数据并要求键盘回送。这样就实现了各个状态的切换。

  实现任务调度需要解决3个关键问题:

  ① 获取任务入口点的程序地址。由于使用C语言不能直接获取和修改程序计数器PC的值,而在调用函数时会将PC值入栈,利用这个特点在任务入口处之前调用Get_Next_PC函数即可从堆栈中获得入口地址。Get_Next_PC中,SP为堆栈指针,得到的PC值要加4才是任务入口地址,因为查看反汇编窗口可知,将函数返回值传给全局变量PC_Value需要两条2字节长的mov指令。

  ② 修改中断返回地址。修改中断返回地址的操作与获取PC值类似,都是通过修改堆栈中的内容实现。但是由于编译器自身的特点,在进入中断时,编译器除了把返回地址入栈外,还会计算自身及它所调用的函数对寄存器ACC、 B、 DPH、 DPL、 PSW、 R0 ~ R7的改变,并将它认为被改变了的寄存器也入栈保护。如果堆栈结构会随中断函数内容改变而变化,就没办法计算中断返回地址堆栈中的位置。解决方法是,在中断函数定义时加上关键字using 0 告诉编译器中断函数及其调用的函数将使用寄存器组0,这样工作寄存器R0~R7将不会被保存。ACC、PSW、DPH、DPL在对PC_Value操作时已经用到,在中断函数开头定义两个变量a1、b1并令它们相乘,使B寄存器也被入栈,这样堆栈的结构就是固定的了。

   ③防止堆栈溢出。由于在调用函数时编译器会将当前地址入栈,返回时再出栈,当任务切换即中断多次发生在函数调用过程中时,堆栈会因为只入不出而最终导致溢出。这是不能容许的。因此,应在主函数开头初始化后立刻将SP值保存,再在每次任务切换后都将SP恢复为初值,这可以有效防止堆栈溢出。

结语
  根据以上的比较与分析可以看出这种实现多任务机制的方法具有如下优点:与采用单任务机制的程序相比,其结构简单清晰,易于控制;利用中断和堆栈实现任务切换时的长跳转,完全不需使用汇编语言,可移植性强;增加的代码量极小,实时性好,节省程序开发时间。

  以上介绍的方法已经通过测试并应用于几个实际项目中,包括智能小区安防系统、汽车CAN总线控制系统等,取得了良好效果。只要根据具体的硬件与编译环境稍作修改,亦可应用于其他的单片机系统中。

参考文献
1.张培仁. 基于C语言编程MCS-51单片机原理与应用. 北京:清华大学出版社, 2003.1.
2.胡大可等. 基于单片机8051的嵌入式开发指南. 北京:电子工业出版社, 2003.1

关键字:程序  代码  嵌入式 引用地址:一种基于C51的多任务机制及应用

上一篇:EM78系列单片机在红外遥控系统中的应用
下一篇:微处理器实时时钟芯片MM58167B原理与应用

推荐阅读最新更新时间:2024-03-16 12:18

基于嵌入式系统的手机编程开发平台
引 言 随着移动通信技术的飞速发展,手机已经从单一的电话通信设备转变为信息网络终端,因此,近年来手机编程已经成为一项重要的技术。手机是一个高新技术的集合体,包含了移动终端、嵌入式系统、数字信号处理以及通信协议设置等多项技术。手机编程开发平台是集合了通信技术、嵌入式技术、电子技术、软件工程、操作系统等理论的软硬件的教学与研究开发平台。在这个开发平台上开发相应的程序,可以掌握嵌入式系统设计的流程与方法;可以根据使用者的需求,设计并实现手机的基本功能和扩展功能。 1 手机编程开发平台总体结构 作为专业技术课程,手机编程技术的教学内容包括系统设置、操作系统使用以及应用软件开发,因此,手机编程平台必须支持各项教学内容。另外,作为教学仪
[单片机]
Linux内核的嵌入式系统应用
随着多媒体技术与通讯技术相结合的信息技术的快速发展和互联网的广泛应用,PC 时代也过渡到了后PC时代。在数字信息技术和网络技术高速发展的后PC时代,嵌入式技术越来越与人们的生活紧密结合。    操作系统为用户使用计算机及其外部设备提供最基本的接口程序,管理计算机上的资源。随着应用领域的扩大,为了适应不同的应用场合,考虑到系统的灵活性、可伸缩性以及可裁剪性,一种以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗要求严格的专用计算机系统—— 嵌入式操作系统随之延生。    Linux 操作系统是一种性能优良、源码公开且被广泛应用的免费操作系统,由于其体积小、可裁减、运行速度高、良好的网络性能等优
[嵌入式]
嵌入式系统智能键盘的软件设计
  键盘是智能化测控系统主要的信息输入方式,是实现人机对话的重要途径,因此如何有效地控制键盘并为系统服务是每个设计者需要切实考虑的问题。   嵌入式系统键盘软件设计存在3方面问题:软件去抖动、等待按键抬起和连击处理。   1嵌入式系统键盘软件设计的3个问题   1.1软件去抖动问题   一次完整按键过程的时序波形如图1所示。当按键未被按下时,单片机端口输入为通过上拉电阻获得的高电平;按下时,端口接至地,端口输入为低电平。当机械触点断开、闭合时会有抖动,这种抖动对人来说是感觉不到的,但对计算机来说,则是完全可以感应到的。计算机处理的速度是us级,而机械抖动的时间至少是ms级,对计算机而言,这已是漫长的时间了。
[嵌入式]
单片机音乐演奏程序 经典讲解
关于 世上只有妈妈好 的单片机音乐演奏 单片机演奏一个音符,是通过引脚,周期性的输出一个特定频率的方波。 这就需要单片机,在半个周期内输出低电平、另外半个周期输出高电平,周而复始。 半个周期的时间是多长呢?众所周知,周期为频率的倒数,可以通过音符的频率计算出半周期。 演奏时,要根据音符频率的不同,把对应的、半个周期的定时时间初始值,送入定时器,再由定时器按时输出高低电平。 下面是个网上广泛流传的单片机音乐演奏程序,它可以循环的播放 世上只有妈妈好 这首乐曲。很多人都关心如何修改这个乐曲的内容,但是不知如何入手。 做而论道对这个程序,给出说明,希望对大家有所帮助,以后大家自己就能够编写进去新的乐曲。 在这个程序中,有两个数据表
[单片机]
小米用新Logo引发网友热议,官网一行代码搞定
IT之家 3 月 31 日消息 小米启用新 Logo 了,如下图,什么?新旧 Logo 区别不大,只是改成了圆角?新 Logo 可是由国际著名设计师原研哉设计,号称为小米品牌视觉融入东方哲学的思考,设计理念是 “Alive”(生命感设计),它采用新的‘超椭圆’轮廓设计,不再局限于画面的一角,达到视觉的最佳动态平衡。同时新增了 Motion Logo 设计,以浮游感的姿态出现,就像有生命一样,不同环境下,动态也随之不同。   雷军实际上也预料到了大家的想法,他在发布会上称,“你是不是对这个 logo 很失望,我们只是把原来的 logo 变圆了?”雷军解释说,不用担心,因为公司 “不仅仅是把形状从方改成圆”,还改变了 “品牌的
[手机便携]
基于ARM的嵌入式数字图像处理系统
引言 在研究远程数字图像处理与传输的过程中,需要在远端现场进行图像处理,本文提出一个集图像采集、处理与显示于一体的嵌入式数字图像处理系统,通过图像获取设备获取目标图像并进行相关的算法处理,通过模块化编程,将原始图像和图像处理结果独立显示出来,修改图像处理模块可以对不同的数字图像处理算法进行验证和分析。利用本文所建立的系统可以大大提高远端数字图像处理的效率,并可利用该系统的网络功能实现远程传输,本文仅就系统的图像获取与处理功能作简要分析。 1 系统组成 硬件组成以S3C2410为核心,S3C2410内部集成了一个USB主控制器,所以无须外接USB控制芯片就可以做为USB主机.USB Host控制器与视频采集摄像头相连,通过在US
[单片机]
基于ARM的<font color='red'>嵌入式</font>数字图像处理系统
基于ARM的嵌入式Linux移植真实体验(4)――设备驱动
设备驱动程序是操作系统内核和机器硬件之间的接口,它为应用程序屏蔽硬件的细节,一般来说,Linux的设备驱动程序需要完成如下功能: 设备初始化、释放; 提供各类设备服务; 负责内核和设备之间的数据交换; 检测和处理设备工作过程中出现的错误。 Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Linux的设备操作犹如文件一般。在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。 Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行;而
[单片机]
基于ARM的<font color='red'>嵌入式</font>Linux移植真实体验(4)――设备驱动
用UML建模开发嵌入式软件
引 言 面向对象开发方法无疑是当前最流行的软件开发方法。这归功于面向对象开发的众多优点:可靠性高,所开发的程序更健壮;由于面向对象编程的可重用性,可以在应用程序中大量采用成熟的类库,从而缩短了开发时间;继承和封装使得应用程序的修改带来的影响更加局部化,应用程序更易于维护、更新和升级。另外,UML建模语言和Rosc等CASE工具为面向对象的流行也起了很太作用,这些工具允许应用规范的面向对象分析和设计的方法与理论,远离纠缠不清的源代码,使得构建和设计变得更直观、更容易理解与修改,从而大大提高开发效率。 嵌入式系统的应用越来越广泛,嵌入式计算机在数量上远远超过了各种通用计算机。嵌入式软件的开发与PC软件的开发相比存在一些特别的地方;①
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved