STM32之中断简介

发布时间 2023-06-14 12:05:07作者: 码好每一天

一、F407在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常10个,外部中断82个。

除了个别异常的优先级被定死外,其他异常的优先级都是可以编程的。结构体: IRQn_Type包含全部异常声明。

二、嵌套向量中断控制器 NVIC,在STM32中NVIV 是 Cortex-M4的一个子集。结构体如下:

typedef struct
{
  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register  中断使能寄存器       */
       uint32_t RESERVED0[24];
  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register  中断清除寄存器       */
       uint32_t RSERVED1[24];
  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register     中断使能悬起寄存器     */
       uint32_t RESERVED2[24];
  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register    中断清除悬起寄存器    */
       uint32_t RESERVED3[24];
  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register   中断有效位寄存器        */
       uint32_t RESERVED4[56];
  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide)  中断优先级寄存器 */
       uint32_t RESERVED5[644];
  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register   软件触发中断寄存器  */
}  NVIC_Type;

在配置中断时,我们一般只使用  ISER  , ICER  ,IP。

2.2  NVIC库函数,我们一般很少使用,因为有更为简便的设置方法。

三、中断优先级定义

3.1 优先级的定义

  在NVIC中有一个专门的寄存器:中断优先级寄存器NVIC_IPRx(x = 0..981) 用来专门配置外部中断的优先级。但是在绝大多数的M4芯片中都精简设计,实际的优先级用的更少,

在F407中只是用了高四位来定义优先级。用于表示优先级的这四位,有分为抢占优先级和子优先级,如果多个中断同时响应,抢占优先级高的就会抢占优先执行权,如果抢占优先级相同,那就会比较子优先级。

如果抢占优先级和子优先级都相同,就比较他们的硬件中断编号,编号越小,优先级越高。

 

3.2 中断优先级分组

  设置优先级分组可调用库函数 : void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)   来实现。在F407优先级总共分了5组:

 四、中断编程

4.1 使能外设某个中断,这个具体由每个外设的相关中断使能位控制,比如串口有发送完成中断,接受完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。

4.2 初始化NVIC_InitTypeDef 结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求。

typedef struct
{
  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                   This parameter can be an enumerator of @ref IRQn_Type 
                                                   enumeration (For the complete STM32 Devices IRQ Channels
                                                   list, please refer to stm32f4xx.h file)  中断源 */

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
                                                   specified in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
                                                   A lower priority value indicates a higher priority  中断抢占优先级 */

  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
                                                   in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
                                                   A lower priority value indicates a higher priority 中断子优先级 */

  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
                                                   will be enabled or disabled. 
                                                   This parameter can be set either to ENABLE or DISABLE 中断使能或者失能 */   
} NVIC_InitTypeDef;

1)  结构体 IRQn_Type 定义了所有中断源

2) 抢占优先级和子优先级 ,具体的值要根据优先级分组来确定

3)中断使能或失能  是操作的NVIC_ISER 和NVIC_ICER这两个寄存器

 

4.3 编写中断服务函数

  在启动文件 startup_stm32f40xx.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是空的,为的只是初始化向量表。实际的中断服务函数都需要我们重新编写,中断服务函数我们统一写在 stm32f4xx_it.c 这个库文件中。

  关于中断服务函数的函数名必须跟启动文件里面预设的一样,如果写过,系统就在中断向量表中找不到中断服务函数的入口,就会直接跳转到启动文件里预设的空函数,并在里面无线循环,实现不了中断。