51单片机的中断相关知识点
一、中断概念和功能
概念
程序执行过程中CPU会遇到一些特殊情况,是正在执行的程序被“中断”,cpu中止原来正在执行的程序,转到处理异常情况或特殊事件的程序去执行,结束后再返回到原被中止的程序处(断点)继续执行
中断技术可以实现的功能
- 分时操作:使得CPU能与多个外设同时工作
- 实时处理:当单片机用于实时控制时,请求CPU的服务是随机发生的(如按下按键),有了中断系统,就可以使得CPU立即响应并且进行处理
- 故障处理:单片机在运行时往往会出现一些故障(如电源断电、存储器奇偶校验位出错、运算溢出等),有了中断系统,CPU可即使转去处理故障程序
二、中断控制系统
系统结构
中断源
中断源 | 中断源名称 | 中断向量 | 中断号 |
---|---|---|---|
P3.2引脚电平/脉冲 | I N T 0 ‾ \overline {INT0} INT0 | 0003H | 0 |
定时计数器0的溢出标志位状态 | T0 | 000BH | 1 |
P3.3引脚的电平/脉冲 | I N T 1 ‾ \overline {INT1} INT1 | 0013H | 2 |
定时/计数器1的溢出标志位状态 | T1 | 001BH | 3 |
串行口数据缓冲器的工作状态 | TX/RX | 0023H | 4 |
其中, I N T 0 ‾ \overline {INT0} INT0和 I N T 1 ‾ \overline {INT1} INT1都是外部中断(需要引脚电平或脉冲触发),剩下的三个都是内部中断,CPU会定时检测他们的标志位以检测中断。
中断请求标志
在程序运行中,CPU只需要定期查看中断请求标志是否为1,就可以知道有没有中断发生。
下面是中断源对应的标志位以及触发方式说明:
中断源名称 | 中断触发方式 | 中断请求标志以及取值 |
---|---|---|
I N T 0 ‾ \overline {INT0} INT0 | P3.2出现负跳变或低电平 | IE0 = 1 |
T0 | 定时/计数器T0接受的脉冲数达到溢出程度 | TF0 = 1 |
I N T 1 ‾ \overline {INT1} INT1 | P3.3出现负跳变或低电平 | IE1 = 1 |
T1 | 定时/计数器T1接受的脉冲数达到溢出程度 | TF1 = 1 |
TX/RX | 一串行数据被发送/接收后 | TI = 1 (发送) RI = 1 (接收) |
值得一提的是:内部中断源TX/RX在串行数据发送之后的标志位虽然会自动置为1,但是并不会再自动置为0,需要我们在代码中置0
中断的控制
51单片机有四个寄存器与中断有关:
- 定时控制寄存器TCON
- 串行口控制寄存器SCON
- 中断优先级控制寄存器IP
- 中断允许控制
TCON定时控制寄存器
-
IT0(Interrupt0 Touch):当IT0 = 0, I N T 0 ‾ \overline {INT0} INT0 端输入低电平表示输入的是中断请求信号;当IT0 = 1, 则输入下降沿信号表示输入的是中断请求信号。
-
IE0(Interrupt0 Exterior): I N T 0 ‾ \overline {INT0} INT0 端没有中断请求信号输入,IE0不变; I N T 0 ‾ \overline {INT0} INT0 端有中断请求信号输入,IE0变为1。
-
IT1(Interrupt1 Touch): 当IT1 = 0,则 I N T 1 ‾ \overline {INT1} INT1 端输入低电平表示输入的是中断请求信号;当IT1 = 1, 则 I N T 1 ‾ \overline {INT1} INT1 输入下降沿信号表示输入的是中断请求信号。
-
IE1(Interrupt1 Exterior) : I N T 1 ‾ \overline {INT1} INT1 端没有中断请求信号输入,IE1不变; I N T 1 ‾ \overline {INT1} INT1 端有中断请求信号输入,IE1变为1。
-
TR0(Timer0 Run):TR0 = 1,T0定时/计数器开始工作;TR0 = 0,T0定时/计数器停止工作。
-
TF0(Timer0 Flag):当T0定时/计数器溢出,TF0变为1,立个Flag请求中断;T0定时/计数器没有溢出,TF0为0,不申请中断。
-
TR1(Timer1 Run):TR1 = 1,T1定时/计数器开始工作;TR1 = 0,T1定时/计数器停止工作。
-
TF1(Timer1 Flag):当T1计数器溢出,TF1变为1,立个Flag请求中断;T1计数器没有溢出,TF1为0,不申请中断。
当IT0 = 1,往 I N T 0 ‾ \overline {INT0} INT0 端输入下降沿,IE0变为1,并且中断子程序结束后,IE0会自动变回0;当IT0 = 0,往 I N T 0 ‾ \overline {INT0} INT0 端输入低电平,IE0变为1,但是中断子程序结束后,IE0不会自动归零,所以要记得用指令将IE0置零。同理,IT1和IE1也是这样的,负跳变引起的中断可以自动变为0,但是低电平的就不行
SCON串行控制寄存器
RI(Receive Interrupt):串行口每接收完一帧数据,RI就变为1,表明数据已经接收完成,并且向CPU发送中断请求信号。
TI(Text Interrupt):串行口每发送完一帧数据,TI就变为1,表明数据已经发送完成,并且向CPU发送中断请求信号。
注意:单片机的中断子程序结束后,TI和RI不会自动归零,所以要记得用指令将它们归零。
IE中断允许控制寄存器
-
EX0(Enable Exterior0):EX0 = 1,允许 I N T 0 ‾ \overline {INT0} INT0 端口输入的中断请求信号通过;EX0 = 0,不允许 I N T 0 ‾ \overline {INT0} INT0 端口输入的中断请求信号通过。
-
ET0(Enable Timer0):ET0 = 1,允许T0端口输入的中断请求信号通过;ET0 = 0,不允许T0端口输入的中断请求信号通过。
-
EX1(Enable Exterior1):EX1 = 1,允许 I N T 0 ‾ \overline {INT0} INT0 端口输入的中断请求信号通过;EX1 = 0,不允许 I N T 0 ‾ \overline {INT0} INT0 端口输入的中断请求信号通过。
-
ET1(Enable Timer1):ET1 = 1,允许T0端口输入的中断请求信号通过;ET1 = 0,不允许T0端口输入的中断请求信号通过。
-
ES(Enable Serial):ES = 1,允许串行通信接口输入的中断请求信号通过;ES = 0,不允许串行通信接口输入的中断请求信号通过。(从RXD接口接收完一帧数据会发送中断请求信号,从TXD接口发送完一帧数据也会发送中断请求信号)
-
EA(Enable All Interrupt):EA = 1,只要前面的中断允许位为1,中断请求信号就能通过;EA = 0,就算前面的中断允许位为1,中断请求信号也不能通过。
IP中断优先级控制寄存器
-
PX0(Priority Exterior0):当PX0 = 1时, I N T 0 ‾ \overline {INT0} INT0 为高优先级;当PX0 = 0时,
I N T 0 ‾ \overline {INT0} INT0 为低优先级。 -
PT0(Priority Timer0):当PT0 = 1时,T0为高优先级;当PT0 = 0时,T0为低优先级。
-
PX1(Priority Exterior1):当PX1 = 1时, I N T 0 ‾ \overline {INT0} INT0 为高优先级;当PX1 = 0时,
I N T 0 ‾ \overline {INT0} INT0 为低优先级。 -
PT1(Priority Timer1):当PT1 = 1时,T1为高优先级;当PT1 = 0时,T1为低优先级。
-
PS(Priority Serial):当PS=1时,串行通信口为高优先级;当PS=0时,串行通信口为低优先级。
中断向量单元地址和自然优先级
如果同时有多个高优先级的中断源,那么它们在都优先于低优先级中断源的基础上,再以自然优先级别来排序。
三、中断控制过程
中断响应
中断响应是指CPU从发现中断请求,到开始执行中断函数的过程。CPU响应中断的基本条件为:
- 有中断源发出中断请求
- EA = 1
- 对应的中断允许位为1
CPU响应中断后,由硬件自动执行如下功能操作:
- 中断优先级查询,低于优先级的不予理睬
- 保护断点,把PC的内容压入堆栈
- 清除可清除的中断请求标志位
- 调用中断函数
- 返回断点
响应时间
从查询中断请求标志到执行中断函数的第一条语句所经历的时间,称为响应中断时间。
外部中断的响应时间一般在3 ~ 8个机器周期之间。
中断撤销
中断响应后,TCON和SCON中的中断请求标志位应及时清零。
对于不同中断请求的撤销方法是不同的:
- 定时/计数器中断: 全自动,TF0和TF1的清零全部由硬件完成
- 脉冲触发:仍然为全自动
- 电平触发:IE0和IE1在被硬件标记为1(也就是通过低电平被触发了中断时)之后是不会被硬件再置为0的,需要软件清零。
- 对于串行口中断:因为中断响应后,需要测试两个标志位的状态(记得吗,串行后的中断标志位有两个),因此不能自动置0。
中断函数
C51中断函数采用如下的定义方式:
void 函数名 (void) interrupt n [using m] {
...函数语句...
}
其中:
- interrupt :C51扩展关键词,n为对应的中断号,使用interrupt可以让编译器知道对应的中断向量地址(=8 * n + 3),并在该地址上设置一个指向该中断函数首地址的无条件跳转指令,C语言这种处理方式使得比汇编语言的开发效率更加高
- using:C51扩展关键词,使用using m可以切换工作寄存器组,省去中断响应时为了保护断点进行的压栈操作,提高速度。using m省略时默认采用当前工作寄存器组(由PSW特殊功能寄存器的RS1和RS0位确定)
组号m与工作寄存器组的关系如下:
组好m | 工作寄存器组 | 字节地址 | RS1 RS0 |
---|---|---|---|
0 | 第0组:R0~R7 | 0~0x07 | 0 0 |
1 | 第1组: R0~ R7 | 0x08~0x0f | 0 1 |
2 | 第2组: R0~R7 | 0x10~0x17 | 1 0 |
3 | 第3组: R0~R7 | 0x18~ 0x1f | 1 1 |
另外需要注意以下几点:
- 允许在中断函数中使用return语句,但是不能使用带有表达式的语句。
- 可以使用全局变量,以弥补无参和无返回值的使用限制
- 中断函数只能被系统调用
- 中断函数应该尽量简短,在主函数或其他函数中根据中断标志值进行响应处理