目录
一、中断是什么
二、STM32中断和异常
1、STM32异常类型
三、NVIC(中断控制器)
1、简介
2、NVIC寄存器介绍
1)NVIC-ISER(中断使能寄存器)
2)NVIC-ICER(中断清除寄存器)
3)NVIC-IPR(中断优先级寄存器)
3、中断优先级
1、优先级定义
2、优先级分组
三、EXTI-外部中断 /事件控制器
1、EXTI介绍
2、EXTI功能框图解析
1)中断线路
2)事件线路
四、中断/事件线
五、中断服务函数
在生活中会发生这样的一些事情,当我们正在看书的时候,突然电话铃声响起。这个时候你会把书本做个标记然后去接电话,接完电话后,你就会放下电话回去继续看书。
而在我们的单片机中,中断就是在CPU处理事件A时,突然发生事件B,请求CPU处理(中断请求),CPU暂停当前工作(中断响应),转而处理事件B(中断处理),处理完又返回到被打断的地方,继续处理事件A(中断返回)这样一个过程(我们也把中断称作异常)
ARM Cortex_M3内核支持256个中断(16个内核和240个外部)和可以编程的256级中断优先级的设置。但是STM32并没有全部使用ARM Cortex_M3内核,STM32F103在内核上搭载异常(中断)响应系统,支持众多的系统异常和外部中断。系统异常8个,外部中断60个及16级可编程中断优先级。
我们可以在俩个地方找到这些异常清单,一个stm32f10x.h头文件的IRQn_Type这个结构体里找到F103系列的全部异常声明因为异常声明过于繁多这里不再具体列表格了。
或者翻看 STM32F1X手册的第九章节向量表部分https://pan.baidu.com/s/1sk1_DSbL5ZV33I7zqzJEsg
提取码:pyj1
NVIC是中断控制器,控制着整个芯片的中断相关的功能,他跟内核紧密联系,是内核里的一个外设。但是芯片厂商会对Cortex-M3内核里的NVIC进行阉割,吧不需要的部分去掉。
这些都是NVIC的寄存器,但是我们在配置中断的时候一般用不到这么多,所以我们只介绍我们用的到的,其他的可以用看Cortex-M3内核编程手册的4.3节NVIC的寄存器,手册链接我放这了,链接:https://pan.baidu.com/s/1rAZWKWpzWYiZckFPwDfm2Q
提取码:pyj1
那些是我们需要了解的寄存器呢我们可以看下NVIC初始化函数
可以看到我们需要了解到的就NVIC中断使能/清除寄存器和中断优先级寄存器
用来使能NVIC中断
用来清除NVIC中断
配置中断优先级组别
接着上面NVIC-IPR寄存器说,这个寄存器是用来配置中断优先级的,原则上每个外部中断可配置的优先级为0~255,但是绝大多数M3内核的芯片都会阉割一些,以实际上的支持优先级数量为准,在本片文章介绍的F103中,就只用了高4位。
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
表达优先级 | 保留读取为0 |
用于表达其优先级的4位 又被分成了抢占优先级和子优先级俩组。如果有多个中断响应,抢占优先级高就会优先执行,如果抢占优先级相同就会比较子优先级。如果都相同的话就会比较他们在硬件中的中断编码就这玩意。
优先级的分组由内核外设SCB-AIRCR(应用中断和复位控制寄存器)的第PRIGROUP([10:8])位来设定。对了这是STM32的内核手册上的4.4.5节手册链接我放这了,链接:https://pan.baidu.com/s/1rAZWKWpzWYiZckFPwDfm2Q
提取码:pyj1
它说的135页的那张图我也放这里,也可以看我画的图,更好理解点。
这里我在给张真值表,我们后面配置NVIC的抢占优先级和子优先级的比例的时候就用这张表里的值
优先级分组 | 主优先级 | 子优先级 | 描述 |
NVIC_PriorityGroup_0 | 0 | 0~15 | 主-0Bit;子-4Bit |
NVIC_PriorityGroup_1 | 0~1 | 0~7 | 主-1Bit;子-3Bit |
NVIC_PriorityGroup_2 | 0~3 | 0~3 | 主-2Bit;子-2Bit |
NVIC_PriorityGroup_3 | 0~7 | 0~1 | 主-3Bit;子-1Bit |
NVIC_PriorityGroup_4 | 0~15 | 0 | 主-4Bit;子-0Bit |
在介绍NVIC的时候其实初始化就介绍的差不多了,优先级分组、抢占优先级、子优先级、使能NVIC、还有一个设置中断源,在这里就介绍了。
NVIC_IROChannel:用来设置中断源,不同的中断,中断源不一样,并且不能出错,因为写错了程序不会报错,只是不会响应中断。具体成员配置可以看手册的中断向量表,或者在stm32f10x.h里查看IRQn_Type结构体的定义。
EXTI(External interrupt /event controller)外部中断 /事件控制器,管理20个中断/事件线。EXTI可以实现对每个中断/事件线进行单独的配置,可以单独配置为中断或者是事件,以及触发事件的属性。
上面介绍说了EXTI可以单独配置为中断或者事件,下面我们介绍功能框图就从这中断和事件走向为主线来介绍。
EXTI有19个中断/事件输入线,这些输入线可以通过寄存器设置成任意一个GPIO,也可以是一些外设的事件,如定时器向上、向下或者中间技术完成一次就会发送中断请求,这部分内容在讲完框图后在详细介绍。
II、边沿检测电路
它会根据上EXTI-RTSR(上升沿触发寄存器)和EXTI-FTSR(下降沿触发寄存器)对应位来设置什么信号触发,以输入线为信号来源,如果检测到信号有跳变就输出给后面的电路作为信号来源,反之则输出无效信号。可以设置成只有上升沿或者下降沿;上升下降沿都触发也行。
它有俩个信号来源一个是上一个边沿检测电路,还有一个就是EXTI-SWIER(软件中断/事件寄存器),EXTI-SWIER允许我们通过程序来启动中断/事件线。这俩个随便一个有有效信号都形。
IV、与门电路
它有俩个输入,一个来自上一个或门电路,另一个来自EXTI-IMR(中断屏蔽寄存器)。与门电路导致只要EXTI-IMR寄存器设置成0时,那么不管上个或门电路的信号是否有效,最终输出都不会有效,如果设置成1,那么最终的输出将由上个或门电路绝对。
我们可以控制EXTI-IMR来实现是否产生中断的目的。那么我们输出的信号会被保存到EXTI-PR(请求挂起寄存器)中,如果确定产生中断就把对应的EXTI-PR设置1。
就是我们上面的NVIC实现系统中断/事件控制。
I、与门电路
之前的电路都是共用的就不再说了,到这它的信号来源一个是前面的或门电路,另一个是EXTI-EMR(事件屏蔽寄存器)这个和上面中断路线的与门电路非常相似,只要EXTI-EMR设置成0,那么输出都是无效的,只有EXTI-EMR设置成1,那么我们的输出才是前面的或门电路,这样我们就可以通过控制EXTI-EMR来实现是否产生事件的目的。
II、脉冲发生器
当它的输入端(与门电路)有效时,那么它就会产生一个脉冲信号,就是线路的最终信号,这个脉冲信号可以给外设电路使用,比如前面谈到的定时器(TIM)或者ADC(模拟数字转换器)等。
STM32中,每个GPIO都可以触发一个外部中断,GPIO的中断是以组为单位的,同组之间的外部中断同一时间只能使用一个。例如PA0、PB0、PC0、PD0、PE0、PF0、PG0、为一组,如果使用PA0为外部中断的话,那么其他的就不能在使用。这种情况下只能使用PB1、PC2等末端序号不同的外部中断源了,下面是外部中断GPIO映像。
每一组使用一个中断标志位EXTIx,EXTI0~EXTI4这5个都有单独的中断服务函数,但EXTI5~9共用一个EXTI10~15共用一个。
另外四个EXTI线的连接方式如下:
● EXTI线16连接到PVD输出
● EXTI线17连接到RTC闹钟事件
● EXTI线18连接到USB唤醒事件
● EXTI线19连接到以太网唤醒事件(只适用于互联型产品)
中断服务函数,在启动文件startup_stm32f10x_ld.s中,这些函数都是空的,为的只是初始化中断向量表。实际的函数需要我们重新编写,写的话只需要编写用到的服务函数。
注意:中断服务函数必须与启动文件里预先设置的一样,写错的话系统会找不到函数的入口,之间跳到启动文件里的那个去,但启动文件里的是空的,导致在里面无限循环,无法实现我们需要的功能。
可以看到我们熟悉的EXTI0的中断服务函数就可以在这里找到。
到这里STM32的中断介绍差不多全介绍到了,关注后面更新使用中断来实现写简单的功能帮助理解中断,后面还会更新STM32的所有特色外设