购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4.7 中断函数与寄存器组定义

Keil C51编译器支持在C语言源程序中直接编写8051单片机的中断函数,从而减轻了采用汇编语言编写中断服务程序的烦琐程度。为了在C语言源程序中直接编写中断函数的需要,Keil C51编译器对函数的定义进行了扩展,增加了一个扩展关键字interrupt,它是函数定义时的一个选项,加上这个选项即可以将一个函数定义成中断函数。定义中断函数的一般形式为:

void 函数名()[interrupt n] [using n]

关键字interrupt后面的n是中断号,n的取值范围为0~31。编译器从8n+3处产生中断向量,具体的中断号n和中断向量取决于8051系列单片机芯片型号,常用中断源和中断向量如表2-8所示。

表2-8 常用中断源与中断向量

续表

8051系列单片机可以在片内RAM中使用4个不同的工作寄存器组,每个寄存器组中包含8个工作寄存器R0~R7。Keil C51编译器扩展了一个关键字using,专门用来选择8051单片机中不同的工作寄存器组。using后面的n是一个0~3的常整数,分别选中4个不同的工作寄存器组。在定义一个函数时using是一个选项,如果不用该选项,则由编译器自动选择一个寄存器组做绝对寄存器组访问。需要注意的是,关键字using和interrupt的后面都不允许跟带运算符的表达式。

关键字using对函数目标代码的影响如下:在函数的入口处将当前工作寄存器组保护到堆栈中;指定的工作寄存器内容不会改变;函数退出之前将被保护的工作寄存器组从堆栈中恢复。

使用关键字using在函数中确定一个工作寄存器组时必须十分小心,要保证任何寄存器组的切换都只在仔细控制的区域内发生,如果不做到这一点将产生不正确的函数结果。另外还要注意,带using属性的函数原则上不能返回bit类型的值。并且关键字using不允许用于外部函数。

关键字interrupt也不允许用于外部函数,它对中断函数目标代码的影响如下:进入中断函数时,特殊功能寄存器ACC、B、DPH、DPL、PSW将被保存入栈;如果不使用关键字using进行工作寄存器组切换,则将中断函数中所用到的全部工作寄存器都入栈保存;函数退出之前所有的寄存器内容出栈恢复;中断函数由8051单片机指令RETI结束。

例2-29 带有寄存器组切换的中断函数定义。

编写8051单片机中断函数时应遵循以下规则。

(1)中断函数不能进行参数传递,如果中断函数中包含任何参数声明都将导致编译出错。

(2)中断函数没有返回值,如果企图定义一个返回值将得到不正确的结果。因此建议在定义中断函数时将其定义为void类型,以明确说明没有返回值。

(3)在任何情况下都不能直接调用中断函数,否则会产生编译错误。因为中断函数的退出是由8051单片机指令RETI完成的,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断请求的情况下直接调用中断函数,RETI指令的操作结果会产生一个致命的错误。

(4)如果在中断函数中调用了其他函数,则被调用函数所使用的寄存器组必须与中断函数相同。用户必须保证按要求使用相同的寄存器组,否则会产生不正确的结果,这一点必须引起足够的注意。如果定义中断函数时没有使用using选项,则由编译器自动选择一个寄存器组做绝对寄存器组访问。另外,由于中断的产生不可预测,中断函数对其他函数的调用可能形成递归调用,需要时可将被中断函数所调用的其他函数定义成再入函数。

(5)Keil C51编译器从绝对地址8n+3处产生一个中断向量,其中n为中断号。该向量包含一个到中断函数入口地址的绝对跳转。在对源程序编译时,可用编译控制命令NOINTVECTOR抑制中断向量的产生,从而使用户有能力从独立的汇编程序模块中提供中断向量。 Z43a16JPc+LOe7XWslCpFvZI5hbo7LjKI4IwrNL20hKFWAFA41/i6oXyirG9+BWL

点击中间区域
呼出菜单
上一章
目录
下一章
×