中断
中断概述
中断的定义
-
中断是单片机系统的一种处理机制与过程,囊括了CPU执行程序时接收到来自硬件或软件的中断请求而作出的一系列反应:
CPU接受到请求后会暂停正在执行的程序,转而去处理相应事件,处理完中断事件后返回断点继续完成被打断的原程序
中断的意义
-
实现系统实时要求
在单片机硬件及软件运行过程中会不断出现新任务,这些任务要求CPU在限定事件内处理,使用中断机制就能合理规划保证实时性要求较高的任务优先完成
-
实现处理速度匹配与CPU效率最大化
在单片机系统中各个任务的数据产生与传送速度有快有慢,使用中断机制可以让CPU先处理快速任务,当慢速外设准备好后再由中断机制通知CPU转去处理,通过合理的安排使得CPU效率最大化
-
实现功耗控制
不需要连续处理数据的任务可以通过让单片机处于功耗低的停机状态,需要时再用中断系统唤醒单片机
中断流程与相关概念
中断的产生
-
中断源
能引起中断事件的来源:例如GPIO端口的外部中断,定时器溢出中断,EEPROM读写操作中断等等,具体的分类请见下文
-
中断请求
当中断源发生中断事件时,需要告知CPU中断发生并请求CPU立即采取处理动作
中断的处理
-
中断响应
当CPU获知中断源的中断请求后,转去处理中断的过程:该过程涉及暂停当前程序进度、保护现场参数、识别中断源信息与跳转到中断入口地址
-
中断服务程序
执行中断的主体部分,中断请求响应后就将调用对应的中断服务子程序
通过查询数据手册的中断向量表可得各个中断源唯一的中断向量号和中断地址入口,比如PA对应EXTI0中断号为3,偏移2(略去0到2这三个不可屏蔽中断的中断向量号)得5,以此类推PB、PC……分别对应EXTI1、2……
这些信息用于配置各个中断源的中断入口地址,构造各中断源的中断服务函数
中断服务函数定义模板如下
#pragma vector = 中断向量号 //这条语句用于给中断服务函数指明中断入口 //例如AWU编号为1,那么中断向量号应是0x03,因为表中开始两个中断RESET与TRAP没有标号,但IAR设置RESET中断地址为入口地址,因此整个向量表需要偏移两位 //也可以使用中断向量名称,如AWU __interrupt void 自定义中断服务函数名(void) //关键字interrupt修饰表示函数类型是中断服务函数 { //此处编写中断服务程序内容 }
中断优先级
-
软/硬件优先级
中断源被分成了若干个级别,以便系统有条不紊地处理发生的所有中断
在中断请求后,CPU先判断软件优先级,优先处理最高软件优先级服务;
- 软件优先级由软件优先级寄存器((20241109133419-3p7aisu "ITC_SPRx"))相应位配置得到
如果中断请求的软件优先级相同,则优先处理最高硬件优先级服务
-
中断向量地址固定在内存中,其地址顺序即硬件优先级,因此硬件优先级唯一
可通过查询数据手册得各个中断源唯一的中断向量号和中断地址入口,中断向量号小的硬件硬件优先级高
-
中断嵌套
在执行中断服务程序时,如果又有另外高优先级的中断或者不可屏蔽的中断发出中断去请求,就需要根据中断优先级去处理这个请求,之后再回到原中断
-
中断屏蔽
无视某些中断请求
-
中断指令
这些指令能够影响CPU的工作状态和优先级配置,单片机内部需要立刻执行这些指令,调整CPU条件代码寄存器CCR中的相应位,中断指令表如下:
由于main函数优先级为最高级,它无法被其它中断打断,因此想要启用中断,需要使用指令RIM将main函数的优先级降为0级,之后才能接收其它的中断
也因此一般不把软件优先级配置为0级(最低级)
-
中断优先级判别流程
-
复位RESET
-
判断是否存在中断请求
-
如果有,判断这个请求是不是TRAP请求
是,则直接响应请求
不是,则判断这个中断的优先级
-
如果发生了中断的嵌套,先响应优先级高的请求,让优先级低的进入等待状态
对于优先级的判断:不可屏蔽优先级最高,可屏蔽中断优先依据软件优先级
-
响应中断,执行中断服务函数,进行保护现场操作
-
处理完成中断服务程序后产生中断返回IRET,回到断点恢复现场继续执行原程序
-
中断返回
- 执行完中断服务程序后会执行中断返回,CPU回返回到上一次被打断的地方恢复现场参数,继续执行原程序
中断的类别
不可屏蔽中断
-
优先级最高,CPU必须无条件响应
-
RESET中断源
优先级在不可屏蔽中断中最高:在单片机上电复位(引起复位的方式有多种)后,所有片上中断源都会被禁止,从主函数开始执行代码;如果需要单片机响应中断请求,就必须开启中断使能,将主函数的优先级降到最低,中断请求才能够打断主函数运行
RESET复位中断可以让CPU从停机状态下退出
-
TLI中断源
在特定的TLI引脚上出现中断信号时将产生硬件中断
在TLI中断服务子程序中禁止使用软件中断TRAP指令,因为TLI与TRAP同级
-
TRAP中断源
一个专用汇编指令,当执行TRAP指令时,CPU就响应软件中断
TRAP中断不能让CPU从停机模式下退出
可屏蔽中断
-
一般是片上外设的各类中断源,分为外部中断与外设中断两种
-
可屏蔽中断触发条件
- 相应中断源的中断资源必须是使能状态,即要先启用该类资源的中断功能
- 其软件优先级一定要比当前正在执行的中断优先级高
- 如果以上条件任一不满足,该中断都会被锁存并保持在等待状态
-
外部中断
-
GPIO引脚具有外部中断能力
配置方法:配置为输入模式,并向控制寄存器2Px_CR2中写入1即可使能GPIO外部中断功能
-
单片机分配了外部中断向量EXTI0-4对应不同GPIO端口组(详见数据手册)
引脚与外部中断的关系是逻辑或,例如:PC组全部引脚开启外部中断,EXTI2向量就同时对应这8个引脚,任一引脚出现触发信号时将导致整个PC组中断
-
外部中断可以将单片机从停机(Halt)或是活跃停机(Active Halt)模式下唤醒
-
-
外设中断
与外设相关的寄存器中一般有控制寄存器与状态寄存器
若使能了控制寄存器的中断使能位,当状态寄存器的中断标志位被置1时将产生一个外设中断请求,此时CPU就可以响应该请求
中断配置流程
中断配置简述
- 此处为GPIO的外部中断配置方式,计时器的中断在计时器章节讲述
-
中断触发方式
配置EXTI_CR1,确定对于该引脚其中断是上升沿还是下降沿触发
-
中断软件优先级
根据中断向量号,查表找到相应的ITC_SPRx寄存器VECTxSPR位,配置其来确定这个中断的软件优先级
这是为了确保在有多个中断执行时其能按所需进行中断嵌套,防止任务出错
-
使能外部中断
启用引脚的中断功能,比如把需要的GPIO端口配置为中断上拉输入
-
写中断服务程序
确定中断之后要做什么
-
开总中断
配置完成后在主程序中写一句
asm("rim");
,这是为了将main程序优先级降低到0级,因为主程序的默认优先级高,如果不这样做的化主程序的执行将屏蔽掉外部中断
中断相关寄存器
-
CPU条件代码寄存器CCR
在使用中断指令时实际上就是在操作和改变CCR寄存器中的相应位
其中I1与I0位是软件中断级配置位,上文提到的RIM中断指令就是配置这两位以调整优先级,具体配置如下:
- I1位:1;I0位:0;级别0 最低
- I1位:0;I0位:1;级别1 次低
- I1位:0;I0位:0;级别2 次高
- I1位:1;I0位:1;级别3 最高
-
软件优先级寄存器ITC_SPRx
修改此寄存器中相应的位可以调整中断的软件优先级
- 共有8个软件优先级寄存器ITC_SPR1-8,而寄存器中每两个位构成向量x的软件优先级位VECTxSPR[1:0] ,总共构成30个软件优先级配置位(ITC_SPR8的后四位保留);这些配置位控制有对应中断向量号的中断源
- 例如:VECT0[1:0]控制中断向量号为0的中断源TLI的软件优先级(至于这两位具体如何配置参见上表)
具体配置示例:
ITC_SPR2 = 0X73;//01 11 00 11 //VECT5SPR[1:O]被置为00,VECT7SPR[1:0]b被置为01 //GPIO端口外部中断EXTI2中断向量号为5,EXTI4中断向量号为7 //因此C端口与E端口软件优先级都被改变了
-
外部中断控制寄存器EXTI_CRx
-
在使用GPIO外部中断功能时,需要确定GPIO接收的电信号以怎样的方式触发中断
电平触发方式:按电平的高低实现电信号的识别与触发
边沿触发方式:电平跳变时的上升沿(低电平跳变到高电平)或下降沿触发
通过配置外部中断控制寄存器EXTI_CRx可以设置各个GPIO端口的触发方式
-
共有两个外部中断控制寄存器,而寄存器中每两个位构成对应端口的外部中断触发位PxIS(x为控制的端口组)
-
EXTI_CR1:配置端口A-D的触发方式:
例如PAIS[1:0]:寄存器的1位与0位,定义端口A的外部中断触发;
这些位只有在CCR寄存器的I1与I0位都为1(软件中断级别最高)时才可写入,具体配置如下:
- 00:下降沿(由高至低电平)和低电平触发
- 01:仅上升沿触发
- 10:仅下降沿触发
- 11:上升沿与下降沿触发
其它端口以此类推,位3:2即是PBIS……
-
EXTI_CR2:位1:0为PEIS配置端口E,同上
位2为TLIS位,高级中断触发位(当TLI中断源的输入引脚禁止中断时才能写入,这个引脚一般是PD7,以数据手册为准):配置0为下降沿触发;1为上升沿触发
其它位为保留位,必须清零
具体配置示例:
EXTI_CR1 = 0x02;//0000 0010;配置端口A为10下降沿触发
-
代码实现
-
配置引脚外部中断
main() { asm("sim");//main程序优先级配置为3级(关总中断)一般此步不必要,因为main优先级默认设置 EXTI_CR1 = 0xE4;//1110 0100 //配置PA为00下降沿和低电平触发,PB为01仅上升沿触发 ITC_SPR2 = 0x73;//01 11 00 11 VECT5SPR=00,VECT7SPR=01 //5这个中断向量号对应EXIT2,控制C端口,7对应E端口,配置了其优先级 //接下来将PA5引脚配制为输入模式(下降沿和低电平触发中断) PA_DDR_DDR5 = 0;//输入模式 PA_CR1_C15 = 1;//弱上拉输入模式 PA_CR2_C25 = 1;//使能外部中断功能 asm("rim");//配置完成,将main程序优先级降低到0级(开总中断) …… } //配置完中断源软件优先级、GPIO引脚模式、外部中断触发方式后,外部中断触发参数配置完成 //还要在程序中编写对应中断源的中断服务程序,以决定中断后干什么 #pragma vector = 0x05//PA对应EXTI0中断号为3,偏移2得5 __interrupt void 自定义中断服务函数名(void) //关键字interrupt修饰表示函数类型是中断服务函数 { //此处编写中断服务程序内容 }
本文来自博客园,作者:无术师,转载请注明原文链接:https://www.cnblogs.com/untit1ed/p/18550450
本文使用知识共享4.0协议许可 CC BY-NC-SA 4.0
请注意: 特别说明版权归属的文章以及不归属于本人的转载内容(如引用的文章与图片)除外
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?