STM32查看当前中断信息的方法

在开发STM32时,我们经常会遇到一些需要知道系统当前中断信息的情况,比如某个中断是否被使能、是否pending、是否正在执行该中断等。如果是在调试环境,那么可以直接查看中断信息,KEIL中的操作方法如下。所有中断的Enable状态、Pending状态(已经发生但是还没有执行到中断)、Active状态(正在执行中断)、中断优先级等信息都一目了然。

STM32查看当前中断信息的方法
图1  KEIL调试时查看NVIC信息

 如果想在非调试环境下获取中断信息,那么可以通过NVIC和SCB两个寄存器来查看。官方提供的库中有对这两个寄存器做简单的描述。

typedef struct
{
  __IO uint32_t ISER[1];        /* Interrupt Set Enable Register */
       uint32_t RESERVED0[31];
  __IO uint32_t ICER[1];        /* Interrupt Clear Enable Register */
       uint32_t RSERVED1[31];
  __IO uint32_t ISPR[1];        /* Interrupt Set Pending Register  */
       uint32_t RESERVED2[31];
  __IO uint32_t ICPR[1];        /* Interrupt Clear Pending Register */
       uint32_t RESERVED3[31];
       uint32_t RESERVED4[64];
  __IO uint32_t IP[8];          /* Interrupt Priority Register */
}  NVIC_Type;

typedef struct
{
  __I  uint32_t CPUID;          /* CPUID Base Register */
  __IO uint32_t ICSR;           /* Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1)
  __IO uint32_t VTOR;           /* Vector Table Offset Register */
#else
       uint32_t RESERVED0;
#endif
  __IO uint32_t AIRCR;          /* Application Interrupt and Reset Control Register      */
  __IO uint32_t SCR;            /* System Control Register */
  __IO uint32_t CCR;            /* Configuration Control Register */
       uint32_t RESERVED1;
  __IO uint32_t SHP[2];         /* System Handlers Priority Registers. [0] is RESERVED */
  __IO uint32_t SHCSR;          /* System Handler Control and State Register */
} SCB_Type;

这两个寄存器在具体的芯片参考手册上基本没有提到,因为这是内核寄存器,应该查阅的是CortexM系列权威指南,例如Cortex M3与M4权威指南。以下是权威指南里对SCB的所有寄存器的汇总信息。实际上要以手册为准,官方的库提供的并不是很准确,例如库里描述的NVIC没有IABR寄存器,实际上是有的。

STM32查看当前中断信息的方法
图2  SCB寄存器汇总信息

从表里我们可以知道,跟中断相关的是SCB->ICSR寄存器,事实上从图1里我们也可以知道KEIL仿真时查看到中Enable、Pending等信息也是根据这个寄存器来的。以下是SCB->ICSR的详细信息。

STM32查看当前中断信息的方法
图3  SCB->ICSR寄存器

 从图3可以得知,ICSR寄存器的bit 26表示systick中断是否pending,写bit 25可以清除systick中断pending,bit 22表示是否有片内外设中断在pending等。下图是我截取的某一时刻的KEIL中的NVIC信息和SCB->ICSR寄存器,可以看到两边的ICSR的值是一样的,此时systick中断了已经pending了,ICSR的bit26 也是置1的,和手册上描述的相符。

STM32查看当前中断信息的方法
图4  KEIL对比NVIC信息和SCB->ICSR寄存器

通过查看SCB->SHCSR寄存器可以知道内核的一些中断是否处于active状态,例如bit 11代表了systick中断是否active。

STM32查看当前中断信息的方法
图5  SCB->SHCSR寄存器

片内外设的中断信息需要看权威手册的NVIC寄存器,例如NVIC的ISER、ISPR、ICPR、IABR等寄存器,这里就不再赘述了,好在官方也帮我们封装了一部分。官方没有封装获取中断active状态的函数,我们可以自行封装,读取IABR寄存器就可以了。

/* 使能某一中断 */
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}

/* 失能某一中断 */
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}

/* 获取某一中断的pending状态 */
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}

/* 设置某一中断的pending状态 */
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}

/* 清除某一中断的pending状态 */
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); 
}

 

上一篇:leetcode 190. 颠倒二进制位(c++)


下一篇:STM32-中断应用