[专业课笔记] 单片机 第五章 中断系统
正文
微机的输入输出方式
在微机的运行过程中,CPU会持续不断地与外部IO设备交换信息,其交换方式往往是以下三种
- 程序控制传送, 又分无条件传送和查询传送两种
- 中断传送
- 直接存储器存取
无条件传送
这种方式下, CPU始终认为外部设备处于准备好收发数据的状态, 只要代码中执行访问外部设备的指令, 就能完成数据的传送
查询传送
这种方式下, 以CPU为主动方, 每次访问外设前程序查询外设的状态是否是准备就绪(这往往通过接口的某一位的置0置1来判别), CPU执行查询访问的整个过程中无法执行其他指令(见下图)
查询传送指令执行的顺序
直接存储器存取(DMA)
这种方式下, CPU让出数据总线, 使外部设备和存储器之间直接传送(不经过cpu)数据
在两种情况下多使用DMA方式
- 外设和存储器之间有大量数据需要传送(比如磁盘往RAM中输送大型数据时)
- 外设的工作速度很高
中断
早期的计算机并没有中断功能, 主机和外设交换数据只能采用程序控制传送的方式, 而这种方式在执行时cpu不能执行别的指令, 将长时间处于等待状态, 等待IO口准备就绪, 导致时间浪费
现代计算机都有实时处理功能, 能对外界随机(异步)发生的事件作出及时处理, 靠的便是中断技术
中断方式解决了程序控制的等待问题, 也实现了对现场数据的实时控制, 能对突发情况进行处理
触发中断时, CPU会中断正在执行的程序(如果允许的话==(此处应该是指中断优先级的高低, 低无法打断高)==), 并把当前pc值入堆栈.
CPU会且只会将原程序地址入栈, 用户需要自行保护现场的数据 , 多通过按顺序入数据栈出数据栈实现
当断点程序结束, 执行断点返回指令后, 自动弹出断点地址到pc, 继续执行被中断的程序
8951的中断系统
8951的中断源
- INT0 : 外部中断0, 低电平有效, 通过p3.2引入
- INT1 : 外部中断1, 低电平有效, 通过p3.3引入
- T0 : 定时器中断0, 计时器0溢出中断请求
- T1 : 定时器中断1, 计时器1溢出中断请求
- TXD/RXD : 串行口中断, 当串行口完成一帧数据的收或发时, 请求中断
==每个中断源都对应一个中断请求标志位, 他们设置在特殊功能寄存器TCON(定时器控制寄存器)和SCON(串行口控制寄存器)中, 当这些中断源请求中断时, 相应标志分别由这两个寄存器中的相应位来锁存
中断源往往有以下几类
- IO设备
- 硬件故障
- 实时时钟
- 调试用中断源
中断控制
中断系统只有中断源的话是没有意义的, 只有通过状态控制器, 在程序中允许中断源在何种情况下请求中断, 之后中断源才能实现中断功能
8951中有以下4个特殊寄存器
- 定时器控制寄存器TCON(用 6 位)
- 串行口控制寄存器SCON(用 2 位)
- 中断允许寄存器IE
- 中断优先级寄存器IP
中断请求标志
TCON
各标志位(从高到低)含义如下:
-
tf1:定时器t1的溢出中断请求标志位
当t1启动后计数器溢出时, 由硬件将tf1置1, 并向CPU发送中断请求
当cpu相应中断后, 硬件自动将其置0 -
tf0:定时器t0的溢出中断请求标志位
作用于t0, 但效果同tf1
-
ie1:外部中断1的溢出中断请求标志位
当检测到外部中断引脚1有有效(取决于it1设置的中断信号方式)的中断请求信号时, 由硬件自动置1
当CPU响应后, 由硬件自动置0 -
it1:外部中断1的中断触发方式控制位
it1决定外部中断1的有效触发方式
-
it1置1时, 外部中断1程控为 电平触发方式
此时, CPU每个 机器周期s5p2 都采样一次请求引脚的输入电平. 若为低电平, 则ie1置1,若为高电平, 则ie置0 -
it1置0时, 外部中断1程控为 边沿触发方式
此时, CPU每个 机器周期s5p2 都采样一次请求引脚的输入电平. 一个周期抽样到高电平, 而下一个周期是低电平, 则ie1置1, 直到CPU响应本中断时, ie才由硬件自动置0
-
-
ie0:外部中断0的溢出中断请求标志位
作用于外部中断0, 但效果同ie1
-
it0:外部中断0的中断触发方式控制位
作用于外部中断0, 但效果同it0
SCON
各标志位(从高到低)含义如下:
-
t1:串行口发送中断请求标志
当CPU将一个数据写入发送缓冲器SBUF时, 就启动发送, 发送完成后, 硬件自动将t1置1, 但CPU响应中断时, 硬件不会自动将其置0(响应中断不代表计算机\设备再次准备好, 故不自动置0), 需要用户在程序适当的地方执行对t1置0的操作 -
r1:串行口接收中断请求标志
当串行口允许接收时, 每接收完一个串行口帧, 硬件自动将t1置1, 同样 , CPU响应中断时, 不会自动将其置0(响应中断不代表计算机\设备再次准备好, 故不自动置0), 需要用户在程序适当的地方执行对t1置0的操作
中断允许控制
ie各标志位的含义如下(从高到低):
- ea: 中断允许总控制位
当ea == 0时, 屏蔽所有中断请求; ea == 1时, CPU开放中断. 在这层总控制之下, 各中断源又有自己的允许开关(类比总电源开关和设备开关之间的关系) - es:串行口中断允许位
均为高电平有效, 即位置1时允许对应串行口中断 - et1: 定时器1中断允许位
- ex1: 外部中断1允许位
- et0: 定时器0中断允许位
- ex0: 外部中断0允许位
中断优先级控制
8951有两个中断优先级, 每个中断源都可以编程为高优先级中断或低优先级
中断系统有两个不可寻址的"优先级生效触发器" , 一个指出CPU是否在执行高优先级的中断服务程序, 另一个指出是否在执行低优先级的中断服务程序, 当两者置1时, 分别屏蔽所有的中断请求
另外,8951片内有一个中断优先级寄存器IP
ip各标志位含义如下:
- ps:串行口中断优先级控制位
- pt1:定时器t1中断优先级控制位
- px1:外部中断1中断优先级控制位
- pt0:定时器t0中断优先级控制位
- px0:外部中断1中断优先级控制位
以上均为置1时对应中断源被视为高级中断
有了ip(中断优先级寄存器)的控制, cpu就可以实现如下两个功能
- 顺序排队
- 实现嵌套中断(高级的中断低级的)
中断响应和中断处理
中断处理过程一般分为三个阶段
- 中断响应
- 中断处理
- 中断返回
CPU在中断中执行的中断服务程序又被称为中断服务子程序, 但和子程序本身不同, 子程序用调用指令来跳转, 中断子程序是通过中断请求实现跳转的, 因此中断子程序也存在保护现场恢复现场的问题
中断响应
响应条件
中断响应的条件(缺一不可):
- 中断源发出中断请求
- 中断总允许位ea为1(即CPU开中断)
- 申请中断的中断源中断允许位为1(即该中断没有被屏蔽)
- 没有正在执行的同级或高级中断正在被服务
- 当前指令周期已结束(机器周期中用来执行指令的部分)
- 如果现行指令是reti或访问ie或ip指令, 则要到该指令和下一条指令执行完(等待中断返回原程序或相关数据保存)
中断响应的自主操作过程
8951在s5p2期间顺序采样各中断源, 又在下一机器周期s6期间按优先级顺序查询中断标志, 如果顺序查到某标志位为1则在接下来的机器周期s1期间按优先级进行中断处理,
中断系统由硬件自动将对应的中断矢量地址装入pc以进入中断服务(子)程序,
这个过程表现为CPU的自主操作
中断响应时间
- 每个周期的s5p2期间采样, 将中断电平锁存到中断标志位
- 下个周期的s6期间检查中断标志位和中断允许位, 符合中断条件, 本周期调用lcall进行矢量跳转到中断程序入口
而lcall指令需要两个机器周期来执行 - 再下一个周期才执行中断程序的第一条指令
因此可得, 从请求中断到中断服务指令执行最短需要三个机器周期
如果正在执行需要中断请求等待的指令如reti, 则需要多等待本指令加下一条指令的时间, 也就是 1 + 指令时间 , 也就是说 从请求中断到中断服务指令执行需要花费三个到八个机器周期
中断处理
CPU响应中断后, 从执行第一条指令开始到返回指令为止, 整个过程叫做 中断处理 或 中断服务
其一般包括两个部分
- 保护现场
- 中断源服务
编写注意事项:
- 各中断源入口之间只间隔8个单元, 一般是无法容纳中断服务程序的, 最常见的是在入口处使用一条无条件转移指令跳转到存储器的某处
- 若执行当前中断程序时, 想要禁止更高级的中断, 可以ea置0关闭CPU中断, 或屏蔽其他高级中断源的中断
- 在保护现场和恢复现场时, 为了不使现场信息受到破坏或造成混乱, 往往会在过程中将ea置0, 防止其他中断打断
中断返回
执行完中断服务程序之后, 执行reti, 表示中断服务结束, 要求CPU返回被断程序处, 即出栈被断程序的下一条指令的地址给pc, 也就是中断请求时入栈的pc值(当时运行的程序的下一个指令的地址)