中断使一种被广泛使用的计算机技术。 中断技术实质上使一种资源共享技术,是解决资源竞争的有效方法,最终实现多项任务共享一项资源。
因为计算机中通常只有一个CPU,任何时刻他只能进行一项工作,而它所面对的任务却可能是多个,所以资源竞争现象不可避免. 对此只能使用中断技术解决.
计算机中的资源竞争,同时是因为计算机在运行程序时会发生一些可预测或不可预测的随机事件引起的. 这些随机事件包括:
了解了什么是中断后,现在对单片机中的中断系统进行介绍. 由于初学单片机,因此我先从80C51的中断系统进行介绍,对中断系统有一定了解后,再去介绍STM32的中断系统
计算机系统中,中断可以由各种硬件设备产生,以便请求服务或报告故障等. 中断也可由处理器自身产生. 例如,程序错误或对操作系统的请求做出响应等.
计算机中的中断服务需求是以中断请求(Interrupt Request)的形式提出来的,不管是来自硬件还是软件的中断请求,凡是中断请求的来源,都统称为中断源
80C51的中断系统具有6个中断源,2个外部中断,2个定时器中断和2个串行中断.
中断向量(Interrupt Vector),其实就是程序存储器的一个地址, 表明一个中断的服务程序从这里开始存放. 中断发生后要通过它引导CPU转向相应的中断服务. 正因为它具有指向性,所以称其为中断向量(或中断矢量)
中断源及其对应的中断向量如下表所示:
中断名称 | 中断向量 |
---|---|
外部中断0 | 0003H |
定时器0中断 | 000BH |
外部中断1 | 0013H |
定时器1中断 | 001BH |
串行发送中断 | 0023H |
串行接受中断 | 0023H |
中断响应后,系统能按中断种类自动转到各中断区的首地址执行程序
理论上讲,在中断地址区中应存放中断服务程序,但通常情况下,8个单元难以放下一个完整的中断服务程序. 因此一般的做法是,在中断地址区首地址处(也就是中断向量)存放一条无条件转移指令,以便中断响应后能通过中断地址区的这个跳板,转到中断服务程序的实际入口地址中.
在80C51的中断系统中,外部中断是由外部原因引起的,共有两个中断源,即外部中断0和外部中断1. 他们的中断请求信号分别由引脚 INT0 ‾ \overline{\text{INT0}} INT0和 INT1 ‾ \overline{\text{INT1}} INT1引入. 外部中断请求有两种信号方式:
定时器中断是为满足定时或计数的需要而设置的. 在单片机芯片内部有两个定时器/计数器 T0和T1, 所以定时器中断也有两个. 当计数器溢出时候,表明定时时间到或计数值满,这时内部电路就产生中断请求. 由于这种中断请求是在芯片内部发生的,因此在芯片上没有对应的中断请求引入段
串行中断只有1个,但是有两个中断源: 串行发送中断和串行接收中断. 他们对应同一个中断向量0023H. 串行中断是为串行数据传送而设置的. 每当串行口发送或接收完一帧串行数据时,就产生相应的中断请求. 同样因为中断请求是在芯片内部自动发生的,所以不需要在芯片上设置中断请求引脚.
这里的中断控制是指提供给用户使用的中断控制手段. 具体到80C51,中断控制的内容共四项:中断允许控制,中断请求标志,中断优先控制和外中断触发方式控制
这些控制内容分布在4个控制寄存器中,包括:中断允许寄存器,定时控制寄存器,串行控制寄存器和中断优先级寄存器
中断控制是通过硬件实现的,但是需要经过软件设置
该寄存器用来控制是否允许使用中断. 中断允许控制寄存器地址为A8H,位地址位AFH~A8H.寄存器位定义及位地址如下表:
位地址 | AFH | AEH | ADH | ACH | ABH | AAH | A9H | A8H |
---|---|---|---|---|---|---|---|---|
位符号 | EA | – | – | ES | ET1 | EX1 | ET0 | TX0 |
可见,通过该寄存器对中断允许实现两级控制: 中断系统总控制和各类中断单个控制.
当总控制位EA=0时,关闭中断系统,整个系统处于禁止中断状态,即使各分类中断是允许的也不管用
只有当EA=1时,开放中断系统,这时候才能由各分类中断控制位控制各类中断的允许和禁止
寄存器地址为88H,位地址为8FH~88H. 虽然该寄存器名称为定时器控制寄存器,但多数位都是为中断控制而设置的.位定义和位地址如下表:
位地址 | 8FH | 8EH | 8DH | 8CH | 8BH | 8AH | 89H | 88H |
---|---|---|---|---|---|---|---|---|
位符号 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
SCON是一个用于串行数据通信控制的寄存器,其中只有两位与中断控制有关
各中断的优先级通过中断优先级控制寄存器IP设定
该寄存器地址为B8H,位地址为BFH~B8H,其位定义及位地址如下表:
位地址 | BFH | BEH | BDH | BCH | BBH | BAH | B9H | B8H |
---|---|---|---|---|---|---|---|---|
位符号 | — | — | — | PS | PT1 | PX1 | PT0 | PX0 |
通过中断优先级控制寄存器可以把全部中断分为高低两个优先级,对应位为0表示低优先级,为1表示高优先级
顾名思义是中断处理有先后之分. 这种先后次序在中断响应和中断嵌套过程中都有体现.
因为80C51只有高低两个优先级. 因此如何为一个中断定义优先级是一个关键问题. 下面是一些基本原则:
中断优先原则首先体现在中断响应过程中,即保证高优先级中断请求被优先响应. 按两种情况安排:
中断优先原则除了体现在中断响应时,也体现在中断服务过程中, 即允许把正在进行的中断服务暂停下来,而转去进行优先级高的中断服务
,这就是中断嵌套.
例如可以把正在执行的数据发送服务停下来,而转去进行十万火急的掉电处理
中断可以多层嵌套. 即一个正在执行的中断服务可以被另一个中断优先级高的中断请求所打断,使CPU转去为新的中断服务; 而新的中断服务又可以被优先级更高的中断所打断,形成又一层嵌套. 这样的嵌套可以继续多层,如同多级子程序调用一样.
具体到80C51,因为只具有两个优先级,所以中断嵌套只能一层
嵌套的原则
在80C51中,为了实现中断嵌套,除了需要使用中断优先级控制寄存器IP来定义高低中断优先级以外,还得用两个优先级触发器的配合. 对应高低两个中断优先级有高低两个优先级触发器,分别指示当前是否正在进行高低优先级的中断服务
当某一高级优先级中断请求被响应后,高优先级触发器设置为1,从而屏蔽其他高优先级中断以及所有低优先级中断;
当某一低优先级中断请求被响应后,低优先级触发器设置为1,从而屏蔽其他低优先级中断,但不能屏蔽高优先级中断
只有外部中断需要采样,因为他们来自单片机芯片的外部,并且是随机的,只有通过采样才能知道是否有中断请求信号到来
采样是在每个机器周期的S5P2对芯片引脚 INT0 ‾ \overline{\text{INT0}} INT0和 INT1 ‾ \overline{\text{INT1}} INT1进行的,根据采样结果来设置定时器控制寄存器TCON外部中断标志位的状态,从而把外部中断请求锁定在寄存器中.
对于电平方式的外部中断请求,采样到低电平即为有效中断信号,把IE0/IE1设置为1;
对于脉冲方式的外部中断请求,若相邻机器周期的采样结果为先高电平后低电平,即为有效中断信号,把IE0/IE1设置为1
因为中断发生是随机的,无法事先预知,所以必须主动检测,这一过程称为中断查询. 中断查询是查看是否有中断去请求发生并确定是哪一个中断源的中断请求. 中断查询操作是由CPU逐个检测定时器控制寄存器TCON和串行控制寄存器SCON中各中断标志位的状态而实现的,
因为所有中断请求最终都要汇集到这两个寄存器中. 其中的外部中断的中断请求是通过采样得到的,而定时中断和串行中断的中断请求就发生在芯片内部,若有中断发生,就通过硬件把相应的标志位直接置位
80C51单片机是在每个机器周期的最后一个状态S6进行中断查询,查询按优先级顺序进行. 具体为先高级后低级.同级中断按
外部中断0-->定时器0中断-->外部中断1-->定时器1中断-->串行中断
的顺序进行.
为了说明信号的时间关系,需要定义几个定时单位. 80C51的定时单位一共有四个,从小到大分别为拍节,状态,机器周期和指令周期.
- 拍节与状态
- 把振荡脉冲的周期定义为拍节用P表示. 振荡脉冲经二分频后,就是单片机的时钟信号,把时钟信号的周期定义为状态用S表示. 这样一个状态就有两个拍节,前半个拍节为拍节1(P1),后半个拍节为拍节2(P2)
- 机器周期
- 80C51采用同步控制方式,因此,它有固定的机器周期. 规定一个机器周期的宽度为6个状态,并依次表示为S1~S6. 由于一个状态有两个拍节,因此一个机器周期有12个拍节. 由于一个机器周期共有12个振荡脉冲周期,因此机器周期就是振荡脉冲的十二分频.
当振荡脉冲频率为12MHz时,一个机器周期就是1μs. 振荡脉冲频率为6MHz时,一个机器周期就是2μs.
- 指令周期
- 指令周期十最大的时序单位,执行一条指令所需要的时间称为指令周期. 指令周期以机器周期的数目表达. 80C51的指令周期根据指令不同,可包含1,2,4个机器周期.
如果查询到有标志位为1,则表明有中断请求发生,接着就从相邻的下一个机器周期的S1状态开始进行中断响应.
由于中断请求是随机发生的,CPU无法预知,因此,在程序执行过程中,中断查询要在指令执行的每一个机器周期进行一遍.
中断响应就是对中断源提出中断请求的接受. 在一次中断查询之后,当发现有中断请求时,紧接着就进行中断响应.
中断响应的主要内容是由硬件自动生成一条长调用指令,指令格式为LCALL addr16
这里的addr16就是程序存储器中断区中响应中断的入口地址
例如对于外部中断0的响应,产生的长调用指令为
LCALL 0003H
生成LCALL指令后,紧接着由CPU执行.
首先将程序计数器PC的内容压入堆栈以保护断点,再将中断入口地址装入PC,使程序执行转向响应的中断区入口地址.
中断响应是有条件的,并不是查询到的中断请求都能立即响应. 当存在下列情况之一时,中断响应将被封锁:
80C51对中断查询的结果不作记忆,由于上述这些原因而被拖延的查询结果将不复存在. 其后将按新的查询结果进行中断响应.
如果中断查询的机器周期恰好是指令的最后一个机器周期,则最快只需要3个机器周期就可以转向中断服务程序的入口. 其中查询占一个机器周期, 在这个机器周期结束后中断即被响应,生成LCALL指令. 执行这条指令需要2个机器周期.
实际上,中断响应不一定这么顺利,下面看一个中断响应最慢的情况. 如果中断查询刚好是开始执行RET,RET1或访问IE,IP指令,则需把当前指令执行完再继续执行一条指令后才能进行中断响应. 这些指令中最长执行时间需要2个机器周期. 而如果接着执行的指令恰好是MUL或DIV指令,又需要4个机器周期. 再加上执行长调用指令LCALL所需的2个机器周期,从而形成8个机器周期的最长响应时间.
一般i情况下,中断响应时间的长度无需考虑,只有在精确定时的应用场合才认真对待中断响应时间,以保证定时的精确控制.
当单片机接收到一个中断请求信号后,就挂起它的当前操作,保存其工作状态,并将控制权交给中断服务程序,以便通过执行中断服务程序(Interrupt Handler)来完成该中断所对应的操作内容
中断都是在运行主程序时发生的,时主程序的随机事件. 是否允许发生以及如何发生,都应该在主程序中预先设置,这就是中断初始化. 中断初始化的内容包括堆栈设置,中断系统总开放,中断允许设置,中断请求方式设置(只限外部中断)和中断优先级设置等.
所有计算机的中断服务流程都十分相似,单片机也不例外. 80C51单片机的中断服务流程如图所示:
流程图表明,只有在一条指令全部执行完之后,才能响应中断请求,以确保指令的完整执行. 下面对流程中的一些问题进行说明
STM32的中断系统基本上由两个部分控制,NVIC和EXTI.
和80C51的中断优先级不同.STM32的优先级复杂一些.
STM32中断优先级基本概念:
抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断;
响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能相互打断;
抢占优先级和响应优先级都相同的情况下,自然优先级越高的先执行;
自然优先级:中断向量表中的优先级;
数值越小,表示优先级越高;
NVIC的权臣是嵌套向量中断控制器(Nested Vectored Interrupt Controller).其主要功能如下:
中断优先级管理:NVIC用于管理不同中断的优先级。它允许对中断请求进行优先级分配,确保高优先级的中断能够及时被处理。
中断使能和禁止:NVIC提供了使能和禁止中断的功能。通过设置相应的中断使能位,可以启用或禁用特定的中断。禁用中断后,即使中断请求发生,处理器也不会响应。这对于在特定情况下临时屏蔽某些中断是很有用的。
中断嵌套:NVIC支持中断的嵌套。当一个中断正在处理时,如果发生了更高优先级的中断请求,NVIC可以中断当前中断的处理,转而处理更高优先级的中断。这种嵌套中断机制使得处理器可以有效地管理多个并发的中断事件。 不同优先级的中断同时发生,优先处理优先级编号较小的那个,同样优先级的中断同时发生,中断向量号较小的那个优先响应
中断状态控制:NVIC提供了一些功能来控制中断的状态。它可以查询中断是否处于挂起状态、中断是否正在处理中,以及中断是否已经完成处理。这些状态信息对于实时系统的调度和管理非常有用。
中断向量表管理:NVIC用于管理中断向量表。中断向量表是一个存储中断处理程序地址的表格。NVIC允许在运行时修改中断向量表的地址,以实现中断处理程序的动态配置和切换。
EXTI(External Interrupt)是STM32微控制器中的外部中断控制器.用于处理外部引脚的中断请求。EXTI模块与NVIC紧密合作,使得处理器能够响应外部事件并执行相应的中断处理程序。
以下是EXTI的主要特点和功能:
外部中断线:EXTI模块与微控制器的外部引脚相连,通过配置外部中断线,可以将特定的外部引脚与EXTI关联起来,以便监测其状态变化并触发中断请求。
中断触发方式:EXTI支持多种中断触发方式,包括上升沿触发、下降沿触发、双边沿触发等。可以根据需求配置中断触发方式,以适应不同的外部事件。
中断屏蔽和使能:EXTI允许对不同的外部中断进行屏蔽和使能。通过配置相应的屏蔽位,可以控制特定中断是否允许触发中断请求。这对于临时屏蔽某些中断或动态调整中断使能状态很有用。
中断线映射:STM32微控制器通常具有多个外部中断线和多个GPIO引脚。EXTI允许将不同的外部中断线映射到特定的GPIO引脚,从而实现外部中断与引脚之间的关联。
中断优先级:与NVIC配合使用,EXTI允许为不同的外部中断设置优先级。优先级决定了中断的相对顺序,当多个中断同时触发时,具有较高优先级的中断将先被处理。
中断处理回调函数:通过配置EXTI的中断处理回调函数,可以在中断触发时执行特定的代码。这样,当外部事件发生时,可以自动跳转到预定义的中断处理回调函数,执行相应的操作。
EXTI模块提供了一种方便的方式来处理外部事件的中断请求,它与GPIO引脚相连,允许监测外部引脚状态的变化,并通过中断机制触发相应的中断请求。这使得处理器能够及时响应外部事件,并执行相应的中断处理程序。