8051中断介绍
8051 系列 MCU 的基本结构包括:
-
32 个 I/O 口(4 组8 bit 端口);
-
两个16 位定时计数器;全双工串行通信;
-
6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;
-
128 字节内置RAM;
-
独立的 64K 字节可寻址数据和代码区。
中断
中断发生后,MCU 转到 5 个中断入口处之一,然后执行相应的中断服务处理程序。
中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。
8051的中断向量表
8051的中断向量表如下:
中断源 中断向量
上电复位 0000H
外部中断0 0003H
定时器0 溢出 000BH
外部中断1 0013H
定时器1 溢出 001BH
串行口中断 0023H
定时器2 溢出 002BH
定义中断处理函数
注意:interrupt 和 using 都是 C51 的关键字,这个跟传统C语言有点区别。
C51 中断过程通过使用 interrupt 关键字和中断号(0 到 31)来实现。
中断号指明编译器中断程序的入口地址中断序号对应着 8051中断使能寄存器IE 中的使能位,对应关系如下:
| IE寄存器 | C51中的8051的使能位 | 中断号 | 中断源 |
| ——– | ——————- | —— | ———— |
| IE.0 | 0 | 0 | 外部中断0 |
| IE.1 | 1 | 1 | 定时器0 溢出 |
| IE.2 | 2 | 2 | 外部中断1 |
| IE.3 | 3 | 3 | 定时器1 溢出 |
| IE.4 | 4 | 4 | 串口中断 |
| IE.5 | 5 | 5 | 定时器2溢出 |
有了这一声明,编译器不需理会寄存器组参数的使用和对累加器A、状态寄存器、寄存器B、数据指针和默认的寄存器的保护。
只要在中断程序中用到,编译器会把它们压栈,在中断程序结束时将他们出栈。
C51 支持所有 5 个 8051 标准中断从 0 到 4 和在 8051 系列(增强型)中多达 27 个中断源。
using 关键字用来指定中断服务程序使用的寄存器组。
用法是:using 后跟一个0 到3 的数,对应着 4 组工作寄存器。
一旦指定工作寄存器组,默认的工作寄存器组就不会被压栈,这将节省 32 个处理周期,因为入栈和出栈都需要 2 个处理周期。
这一做法的缺点是所有调用中断的过程都必须使用指定的同一个寄存器组,否则参数传递会发生错误。
因此对于using,在使用中需灵活取舍。
C51中断处理过程
C51编译器支持在C源程序中直接开发中断过程,因此减轻了使用汇编语言的繁琐工作,提高了开发效率。中断服务函数的完整语法如下:
void 函数名(void)[模式]
[再入]interrupt n [using r]
1. 其中n(0~31)代表中断号。
C51编译器允许32个中断,具体使用哪个中断由80C51系列的芯片决定。
2. r(0~3)代表第r组寄存器。
在调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同。
3. “再入”
用于说明中断处理函数有无"再入"能力。
C51编译器及其对C语言的扩充允许编程者对中断所有方面的控制和寄存器组的使用。
这种支持能使编程者创建高效的中断服务程序,用户只须在C语言下关心中断和必要的寄存器组切换操作。
void INT0()interrupt 0 using 1
{
}
interrupt 0 指明是外部中断0;
interrupt 1 指明是定时器中断0;
interrupt 2 指明是外部中断1;
interrupt 3 指明是定时器中断1;
interrupt 4 指明是串行口中断;
using 0 是第0组寄存器;
using 1 是第1组寄存器;
using 2 是第2组寄存器;
using 3 是第3组寄存器;
51单片机内的寄存器是R0–R7(不是R0-R3)
R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。
using 0时设置 RS1=0,RS0 =0,用第0组寄存器,R0–R7的在数据存储区里的实际地址是00H-07H。R0(00H)….R7(07H)
using 1时设置 RS1=0,RS0 =1,用第1组寄存器,R0–R7的在数据存储区里的实际地址是00H-07H。R0(08H)….R7(0FH)
using 2时设置 RS1=1,RS0 =0,用第2组寄存器,R0–R7的在数据存储区里的实际地址是08H-0FH。R0(10H)….R7(17H)
using 3时设置 RS1=1,RS0 =1,用第3组寄存器,R0–R7的在数据存储区里的实际地址是00H-07H。R0(18H)….R7(1FH)
中断源与标记位
引起CPU中断的根源叫做中断源,中断源向CPU的请求,叫做中断请求,51单片机有5个中断源
| 符号 | 产生条件 |
| —— | —————————————————– |
| INT0 | 外部中断0,中断请求信号由P3.2输入,低电平或下降沿引起 |
| INT1 | 外部中断1,中断请求信号由P3.3输入,低电平或下降沿引起 |
| T0 | 定时器/计数器0中断,由T0计数器记满回0引起 |
| T1 | 定时器/计数器1中断,由T1计数器记满回0引起 |
| RX、TX | 串行口中断,串行口完成一帧数据发送/接收后引起 |
中断系统设置了中断请求标记位,对中断源进行管理(就是对中断进行设置的意思,是否启用这个中断)
| INT0 | 对应IE0 |
| —- | ——- |
| T0 | 对应TF0 |
| INT1 | 对应IE1 |
| T1 | 对应TF1 |
| RX | 对应R1 |
| TX | 对应T1 |
中断允许寄存器IE:
中断优先级寄存器IP:
等于1时表示相应的位设置为高级优先,等于0为低级优先
如果不设置,将会按照优先级由高到低执行
代码
#include <reg52.h>
unsigned char a;
sbit lcden=P3^4;
void main()
{
lcden=0;
EA=1;//中断总开关
EX0=1; //中断允许控制位,控制外部中断
IT0=0; //把IT0设置为低电平触发
a=0xf0;
while(1)
{
P1=a;
}
}
void ext0() interrupt 0 //中断服务程序,‘ 0 ’是外部中断0入口序号
{
a=0x0f;
}