其他分享
首页 > 其他分享> > STM32 中断和事件

STM32 中断和事件

作者:互联网

中断和事件(Interrupts and events)

嵌套向量中断控制器(Nested vectored interrupt controller -NVIC)

寄存器介绍

上面说到 NVIC 控制着芯片的中断相关功能, 那么肯定有很多对应的寄存器,在固件库 core_cm3.h 文件内定义了一个 NVIC 结构体,里面定义了相关寄存器,如下:

typedef struct
{
    __IO uint32_t ISER[8]; //中断使能寄存器
    uint32_t RESERVED0[24];
    __IO uint32_t ICER[8]; //中断清除寄存器
    uint32_t RSERVED1[24];
    __IO uint32_t ISPR[8]; //中断使能悬起寄存器
    uint32_t RESERVED2[24];
    __IO uint32_t ICPR[8]; //中断清除悬起寄存器
    uint32_t RESERVED3[24];
    __IO uint32_t IABR[8]; //中断有效位寄存器
    uint32_t RESERVED4[56];
    __IO uint8_t IP[240]; //中断优先级寄存器
    uint32_t RESERVED5[644];
    __O uint32_t STIR; //软件触发中断寄存器
} NVIC_Type;

在配置中断时,我们通常使用的只有 ISER、 ICER 和 IP 这三个寄存器,ISER是中断使能寄存器,ICER是中断清除寄存器,IP 是中断优先级寄存器。在固件库 core_cm3.h文件后面,还提供了一些对 NVIC 操作的库函数,这些函数都是遵循 CMSIS 标准, 所以只要是基于 Cortex-M3 内核的芯片都可以用这些函数来操作 NVIC,只不过我们很少这样做,甚至不使用这些函数,因为在后面我们会有更简单的办法来配置中断。至于这些函数内容,大家如果有兴趣的话,可以打开我们库函数版本任意程序,找到 core_cm3.h 文件查看即可。

这里多提一点__IO的用法:

/* IO definitions (access restrictions to peripheral registers) */
#ifdef __cplusplus
  #define __I  volatile         /*!< defines 'read only' permissions                 */
#else
  #define __I  volatile const   /*!< defines 'read only' permissions                 */
#endif
#define   __O  volatile         /*!< defines 'write only' permissions                */
#define   __IO volatile         /*!< defines 'read / write' permissions              */ 

其实就是将volatile关键字进行了重定义,用来区分读写,仅仅是语法提醒层面,并不强制。

中断配置

前面讲解了那么多中断知识, 如果大家不理解也没有关系, 我们会应用即可,等到后面 STM32 熟练了,再回过头深入了解自然就会明白。要使用中断我们就需要先配置它,通常都需经过这几步:

(1)使能外设某个中断,这个具体是由外设相关中断使能位来控制,比如

定时器有溢出中断,这个可由定时器的控制寄存器中相应中断使能位来控制。

(2)设置中断优先级分组,初始化 NVIC_InitTypeDef 结构体,设置抢占

优先级和响应优先级,使能中断请求。

NVIC_InitTypeDef 结构体如下:

typedef struct
{
  uint8_t NVIC_IRQChannel; //中断源
  uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
  uint8_t NVIC_IRQChannelSubPriority; //响应优先级
  FunctionalState NVIC_IRQChannelCmd; //中断使能或失能
} NVIC_InitTypeDef;

下面我们对 NVIC_InitTypeDef 结构体成员进行一下简单介绍。

1.NVIC_IRQChannel:中断源的设置,不同的外设中断,中断源不一样,自

然名字也不一样,所以名字不能写错,否则不会进入中断。中断源放在stm32f10x.h 文件的 IRQn_Type结构体内,由于内容太多,这里就不复制所有中断源,只截取一部分,如下:


typedef enum IRQn
{
  //Cortex-M3 处理器异常编号
  NonMaskableInt_IRQn = -14,
  MemoryManagement_IRQn = -12,
  BusFault_IRQn = -11,
  UsageFault_IRQn = -10,
  SVCall_IRQn = -5,
  DebugMonitor_IRQn = -4,
  PendSV_IRQn = -2,
  SysTick_IRQn = -1,
  //STM32 外部中断编号
  WWDG_IRQn = 0,
  PVD_IRQn = 1,
  TAMP_STAMP_IRQn = 2,
  // 限于篇幅,中间部分代码省略,具体的可查看库文件 stm32f10x.h
  DMA2_Channel2_IRQn = 57,
  DMA2_Channel3_IRQn = 58,
  DMA2_Channel4_5_IRQn = 59
}IRQn_Type;

2.NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,可以参考前面中断优先级分组内容。

3.NVIC_IRQChannelSubPriority:响应优先级,具体的值要根据优先级分组

来确定,可以参考前面中断优先级分组内容。

4.NVIC_IRQChannelCmd:中断使能/失能设置,使能配置为 ENABLE,失能配置为 DISABLE。

标签:__,NVIC,优先级,中断,STM32,IRQn,事件,寄存器
来源: https://www.cnblogs.com/RegressionWorldLine/p/12203676.html