5.2中断编程
C51 编译器支持在C 源程序中直接开发中断过程,使用该扩展属性的函数定义语法如
下:
返回值 函数名 interrupt n
其中n 对应中断源的编号,其值从0 开始,以80C51 单片机为例,编号从0~4,分别对
应外中断0、定时器0 中断、外中断1、定时器1 中断和串行口中断。
5.2.1 中断应用实例
下面我们同样通过一个例子来说明中断编程的应用。
例 5-2 用中断法实现定时器控制P1.0 所接LED 以60ms 闪烁。
参考图 2 输入源程序,设置工程,同样,本例用实验仿真板难以看到真实的效果,应使
用DSB-1A 型实验板来完成这一实验。
分析:本例与例1 的要求相同,唯一的区别是必须用中断方式来实现。这里仍选用定时
器T0,工作于方式1,无门控,因此,定时器的初始化操作与上例相同。要开启中断,必
须将EA(总中断允许)和ET0(定时器T0 中断允许)置1,程序中用“EA=1;”和“ET0
=1;”来实现。在做完这些工作以后,就用for(;;){;}让主程序进入无限循环中,所有工作均
由中断程序实现。
由于定时器 0 的中断编号为1,所以中断程序中这样写:
void timer0() interrupt 1
{…}
可见,用 C51 语言写中断程序是非常简单的,只要简单地在函数名后加上interrupt 关
键字和中断编号就成了。
图 2 用中断法使用定时器
5.2.2 寄存器组切换
为进行中断的现场保护,80C51 单片机除采用堆栈技术外,还独特地采用寄存器组的方
式,在80C51 中一共有4 组名称均为R0~R7 的工作寄存器,中断产生时,可以通过简单地
设置RS0、RS1 来切换工作寄存器组,这使得保护工作非常简单和快速。使用汇编语言时,
内存的使用均由编程者设定,编程时通过设置RS0、RS1 来选择切换工作寄存器组,但使用
C 语言编程时,内存是由编译器分配的,因此,不能简单地通过设置RS0、RS1 来切换工作
寄存器组,否则会造成内存使用的冲突。
在 C51 中,寄存器组选择取决于特定的编译器指令,即使用using n 指定,其中n 的
值是0~3,对应使用四组工作寄存器。
例如上述例子中可以这么样来写:
void timer0() interrupt 1 using 2
{…}
即表示在该中断程序中使用第2 组工作寄存器。
下:
返回值 函数名 interrupt n
其中n 对应中断源的编号,其值从0 开始,以80C51 单片机为例,编号从0~4,分别对
应外中断0、定时器0 中断、外中断1、定时器1 中断和串行口中断。
5.2.1 中断应用实例
下面我们同样通过一个例子来说明中断编程的应用。
例 5-2 用中断法实现定时器控制P1.0 所接LED 以60ms 闪烁。
参考图 2 输入源程序,设置工程,同样,本例用实验仿真板难以看到真实的效果,应使
用DSB-1A 型实验板来完成这一实验。
分析:本例与例1 的要求相同,唯一的区别是必须用中断方式来实现。这里仍选用定时
器T0,工作于方式1,无门控,因此,定时器的初始化操作与上例相同。要开启中断,必
须将EA(总中断允许)和ET0(定时器T0 中断允许)置1,程序中用“EA=1;”和“ET0
=1;”来实现。在做完这些工作以后,就用for(;;){;}让主程序进入无限循环中,所有工作均
由中断程序实现。
由于定时器 0 的中断编号为1,所以中断程序中这样写:
void timer0() interrupt 1
{…}
可见,用 C51 语言写中断程序是非常简单的,只要简单地在函数名后加上interrupt 关
键字和中断编号就成了。
图 2 用中断法使用定时器
5.2.2 寄存器组切换
为进行中断的现场保护,80C51 单片机除采用堆栈技术外,还独特地采用寄存器组的方
式,在80C51 中一共有4 组名称均为R0~R7 的工作寄存器,中断产生时,可以通过简单地
设置RS0、RS1 来切换工作寄存器组,这使得保护工作非常简单和快速。使用汇编语言时,
内存的使用均由编程者设定,编程时通过设置RS0、RS1 来选择切换工作寄存器组,但使用
C 语言编程时,内存是由编译器分配的,因此,不能简单地通过设置RS0、RS1 来切换工作
寄存器组,否则会造成内存使用的冲突。
在 C51 中,寄存器组选择取决于特定的编译器指令,即使用using n 指定,其中n 的
值是0~3,对应使用四组工作寄存器。
例如上述例子中可以这么样来写:
void timer0() interrupt 1 using 2
{…}
即表示在该中断程序中使用第2 组工作寄存器。