用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心解决方案电子通信

MCS-51系统中断优先级的软扩展

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-01-10 22:36:47
最高的物理中断优先级)提出中断请求时,系统将立即响应,而不管系统此时忙否。如果此时 系统正在执行其它中断的ISR,X1的ISR将以嵌套形式执行,因为其它中断湖泊的物理中断优先级都为最低(51系统仅有两级物理优先级:最高或最低)。

②当定时器0(T0,其优先级为2)的中断请求正被响应时,来自串口(S,其优先级为3)和外部中断0(X0,其优先级为4)的中断请求将被禁止;而只允许外部中断1(X1,其优先级为0)和定时器1(T1,其优先级为1)提出中断请求。如果是X1提出中断请求,则X1的ISR将立即嵌套执行;如果是T1提出,尽管其优先级高于当前中断T0,但因其物理中断优先级与T0一样(同为最低),故而将不会像X1那样被系统立即响应,并嵌套执行,而只能等待,直到T0的中断服务例程执行完毕。

③如果在串口(S,其优先级为3)中断正被响应过程中,定时器1(T1,其优先级为1)与定时器0(T0,其优先级为2)分别提出中断请求。由于它们有高于S的优先级,所以系统允许它们提出中断请求;但因其物理优先级与S一样,故而直到S的中断服务例程执行完毕,系统才会受理T1与T0的中断请求。逻辑上,由于T1具有高于T0的优先级,所以T1应先为系统响应。但因物理优先级相同时,中断请求的响应次序取决于内部查询顺序,而T0先于T1,所以实际上T0先 系统响应,即出现了“优先级反转”的问题。

可见,方法一虽然可以部分地达到“扩充中断优先级”的目的,但其存在两个问题:

*某些高优先级中断不能中断嵌套低优先级中断;

*会出现“优先级中反转”。

方法二和方法三是针对方法一的这两个不足而提出的,并最终实现对51系统的中断优先级的真正扩展。

2.2 方法二

该方法是在方法一基础上,为解决“优先级反转”的问题,而实施的简单策略而得。

根据方法一中对“优先级反转”问题的分析可知,出现该问题的原因是:各中断源的逻辑优先级与其内部查询顺序不一致。只要在系统设计时,兼顾中断源相关事件的紧迫程度与中断源的内部查询逻辑:将最紧迫的事件(如掉电)赋以最高的优先级0,并使其与系统中的最先被查询的中断源(外部中断0<X0>)相关联;使次紧迫的事件的优先为1,并使之与系统内第二个被查询的中断源(定时器0<T0)相关联。以此类推,给紧追程度最低的事件赋以最低的优先级N-1(N为中断源个数),并使之与系统中最后被查询的中断源(串口中断<S>)相关联,即51系统内的各中断源应有表3所列的优先级。

表3 中断源的优先级分配

中断源X0T0X1T1S
优先级01234

如此,即可解决“优先级反转”的问题。

2.3 方法三

本法是在方法一、二的基础上,针对“某些高优先级中断不能中断嵌套低优级中断”的问题,引入相应的策略,以实现对51系统中断优先级的“真正”扩展。
javascript:window.open(this.src);" style="cursor:pointer;"/>
3 优先级软扩展的函数库实现

为了真正扩展51系统的优先级,各中断源的优先级、优先级屏蔽字、中断屏蔽字应是确定的,如表3、4所列。C51编写断服务例程时,应给出相应的中断源编号(中断号)。特定中断源有特定的中断号,而此中断号恰与各中断应有的优先级一致。

本文用C51,以函数库的形式实现方法三所述的策略,其包含两个文件:ExtIntPri.H、ExtIntPri.C。须要指出,为使优先级的设置和恢复具有原子性以防出现混乱,应对SetPriority()和ResetPriority()作临界处理,以使其不被“再入”访问。另外,应对系统栈作调整。如图1所示,其中“1”代表SetPriority()所作的调整,其将IP、IE保存于系统栈中;“2”代表ResetPriority()所作的调整,其从系统栈中恢复IE、IP;“HAddr”、“LAddr”分别代表当前函数返回地址的高位字节和低字节(栈中的地址是以小端字节序<Little Endian>方式存储,这是C51中唯一的例外,而所有其它多字节数据则皆以大端字节序<Big Endian>方式存储)。如果不这样做,而是定义两个全局变量来保存IE、IP,由于SetPriority()和ResetPriority()都要访问这两个全局变量,而这两个函数又应在ISR的开关和结尾处被分别调用,从而使ISR成为临界区,而不可被其它ISR中断,这将使优先级的存在失去意义。

//ExtIntPri.H

extern void SetPriority(unsigned char);

extern void SetPriority(unsigned char);

extern void ResetPriority(void);

//ExtIntPri.C

#pragma src

#include "ExtIntPri.H"

#include<reg51.h>

//静态(局部)函数声明

static void ResetIntSys(void);//仅含一条指令:RETI

//宽两个宏用作“临界区”的进入区和退出区

#define ENTER_CRITICAL()EA=0//关中断,以防临界再入

#define EXIT_CRITICAL() EA=1

//中断屏蔽字和优先级屏蔽字的宏定义,如表3所列。

#define S_INT_MASK 0x8F//;1-01111B

//…

#define S_PRI_MASK 0x0F//;---01111B

//…

//先调整系统栈以保存IP、IE,其过程如图1所示,再为给定中断

//(prio也是中断号)设置优先级

void SetPriority(unsigned char prio){

ENTER_CRITICAL();//关中断

#pragma asm

POP ACC //弹出返回地址的高位字节HAddr

POP B //弹出返回地址的低位字节Laddr

PUSH IPjavascript:window.open(this.src);" style="cursor:pointer;"/>

PUSH IE //EA= =0

PUSH B //LAddr进栈

PUSH AC

上一页  [1] [2] [3]  下一页

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:9,687.50000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号