STM32的中断和事件

学习单片机一贯的套路,搞完时钟和GPIO就要折腾中断了。

1. 中断和异常的区别

1.1 中断是指系统停止当前正在运行的程序转而其他服务,可能是程序接收了比自身高优先级的请求,或者是人为设置中断,中断是属于正常现象。
1.2 异常是指由于cpu本身故障、程序故障或者请求服务等引起的错误,异常属于不正常现象。

Cortex-M3内核总共支持256个中断,其中包含16个内核异常和240个外部中断,但是各个芯片产商在设计芯片的时候会对CM3内核的芯片进行精简设计,如STM32F103系列,所搭载的异常响应系统,包含10个系统异常和60个外部中断,用一张表将它们管理起来,编号0~15位系统异常,16以上称为外部中断。

系统异常清单:
这里写图片描述
外部中断清单:
这里写图片描述

这里写图片描述

外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能。

2. 中断优先级

STM32支持两种优先级:抢占优先级和子优先级。所有优先级可编程的中断源都需要指定这两种优先级。
抢占优先级决定是否可以产生中断嵌套,子优先级决定中断响应顺序,若两种优先级一样则看中断源在中断向量表中的偏移量,偏移量小的先响应。
对这句话的解释为:

(1)抢占优先级高的中断源可以中断抢占优先级低的中断处理函数,进而执行高优先级的中断处理函数,执行完毕后再继续执行被中断的低优先级的处理函数。
(2)当两个中断源的抢占优先级相同时,即这两个中断将没有嵌套关系,当一个中断到来后,若此时cpu正在处理另一个中断,则这个后到来的中
断就要等到前一个中断处理函数处理完毕后才能被处理,当这两个中断同时到达,则中断控制器会根据它们的子优先级决定先处理哪个。
(3)如果它们的抢占优先级和子优先级都相等,则根据它们在中断表中的排位顺序决定先处理哪一个。

每个中断源都需要被指定抢占优先级和子优先级,自然需要相应的寄存器来记录。在NVIC中有一个专门处理中断优先级的寄存器NICV_IPRx,用于配置中断源的优先级。IPR的宽度为8Bit,对于CM3内核来说,因为它支持的中断源为256个,那么原则上每个外部中断源可配置的优先级位0~255,数值越小优先级越高。但是因为绝大多数CM3芯片都会精简设计,所以不会使用到全部位,在STM32F103中只使用4Bit。
这里写图片描述
注意,个别系统系统的优先级是固定的,所以它们的中断优先级是不可编程的。

2.1 CM3核的优先级分组方式
CM3中定义了8个Bit用于设置中断源的优先级,这8个Bit可以分配为:

(1)8bit用于响应优先级
(2)最高1位用于指定抢占优先级,最低7位用于执行子优先级
(3)最高2位用于指定抢占优先级,最低6位用于执行子优先级
(4)最高3位用于指定抢占优先级,最低5位用于执行子优先级
(5)最高4位用于指定抢占优先级,最低4位用于执行子优先级
(6)最高5位用于指定抢占优先级,最低3位用于执行子优先级
(7)最高6位用于指定抢占优先级,最低2位用于执行子优先级
(8)最高7位用于指定抢占优先级,最低1位用于执行子优先级

CM3核的优先级分组方式,使用的设置函数

NVIC_SetPriorityGrouping()

在Libraries\CMSIS\CM3\CoreSupport\core_cm3.h文件中实现:

static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  uint32_t reg_value;
  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */

  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
  reg_value  =  (reg_value                       |
                (0x5FA << SCB_AIRCR_VECTKEY_Pos) | 
                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */
  SCB->AIRCR =  reg_value;
}

该函数写在.h文件中,且声明为内联函数(__INLINE),

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值