深入NVIC
1. 看看 Cortex-M3 中与 NVIC 相关的寄存器有哪些
SysTick Control and Status Register Read/write 0xE000E010
SysTick Reload Value Register Read/write 0xE000E014
SysTick Current Value Register Read/write clear 0xE000E018
SysTick Calibration Value Register Read-only 0xE000E01C
//==================
Irq 0 to 31 Set Enable Register Read/write 0xE000E100
. . . . .
Irq 224 to 239 Set Enable Register Read/write 0xE000E11C
//=================
Irq 0 to 31 Clear Enable Register Read/write 0xE000E180
. . . . .
Irq 224 to 239 Clear Enable Register Read/write 0xE000E19C
//==================
Irq 0 to 31 Set Pending Register Read/write 0xE000E200
. . . . .
Irq 224 to 239 Set Pending Register Read/write 0xE000E21C
//==================
Irq 0 to 31 Clear Pending Register Read/write 0xE000E280
. . . . .
Irq 224 to 239 Clear Pending Register Read/write 0xE000E29C
//==================
Irq 0 to 31 Active Bit Register Read-only 0xE000E300
. . . . . .
Irq 224 to 239 Active Bit Register Read-only 0xE000E31C
//===================
Irq 0 to 3 Priority Register Read/write 0xE000E400
. . . . .
Irq 224 to 239 Priority Register Read/write 0xE000E4EC
//========================
CPUID Base Register Read-only 0xE000ED00
Interrupt Control State Register Read/write or read-only 0xE000ED04
Vector Table Offset Register Read/write 0xE000ED08
Application Interrupt/Reset Control Register Read/write 0xE000ED0C
System Control Register Read/write 0xE000ED10
Configuration Control Register Read/write 0xE000ED14
System Handlers 4-7 Priority Register Read/write 0xE000ED18
System Handlers 8-11 Priority Register Read/write 0xE000ED1C
System Handlers 12-15 Priority Register Read/write 0xE000ED20
2.STM32 中用了哪些
(下面是从 ST 公司提供的函数库的头文件得到的,库的版本是 v3.1.0)
/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
typedef struct
{
__IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Software Trigger Interrupt Register */
} NVIC_Type;
a/ 寄存器 ISER、ICER、ISPR、ICPR、IABR 在 STM32 中都使用的 8 个(实际 3 个就够
了,后面的留在后面扩充?)。这些 32 位的寄存器中每一位对应了一个中断通道相应的标志。
比如地址在 0xE000E100 的 ISER[0]这个 32 位的寄存器,第 0 位是中断通道 0 的允许位,
第 1 位是中断通道 1 的允许标志……第 31 位是中断通道 31 的允许位;接下来地址在
0xE000E104 的 ISER[1]则是中断通道 32-63 的允许位。ICER、ISPR、ICPR、IABR 的结构相
同,只是含义不同。
注意是对这些寄存器的操作:写 1 表示置位或清除,写 0 无任何影响。
例如:对地址在 0xE000E100 的 ISER[0]的第 0 位写 1,表示允许中断通道 0 中断;
但对 0xE000E100 的 ISER[0]的第 0 位写 0,则没有任何作用,该位保持不变。
如果要禁止中断通道 0 的中断响应,那么就必须:
对地址 0xE000E180 的 ICER[0]的第 0 位写 1,表示禁止中断通道 0 的中断;
对 0xE000E180 的 ICER[0]的第 0 位写 0,也是不起任何作用的。
b/ IP[240]用于定义 240 个外部中断通道的优先级,每 1 个字节对应一个中断通道。4 个
中断通道的 IP[n]字构成一个 32 位的寄存器。在 STM32 中最多有 68 个外部中断通道,每个
IP[n]的 1 个字节中只使用高 4 位(见前面介绍)。IP[n]的结构如下:
c/ 在 ST 公司提供的函数库的头文件中另一个数据结构中,还有一个重要的 32 位寄存器需要关注 :AIRCR
/* memory mapping struct for System Control Block */
typedef struct
{
__I uint32_t CPUID; /*!<CPU ID Base Register */
__IO uint32_t ICSR; /*!< Interrupt Control State Register */
__IO uint32_t VTOR; /*!< Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
__IO uint32_t SCR; /*!< System Control Register */
__IO uint32_t CCR; /*!< Configuration Control Register */
__IO uint8_t SHP[12]; /*!<System Handlers Priority Registers(4-7,8-11,12-15) */
__IO uint32_t SHCSR; /*!< System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Hard Fault Status Register */
__IO uint32_t DFSR; /*!< Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Mem Manage Address Register */
__IO uint32_t BFAR; /*!< Bus Fault Address Register */
__IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Processor Feature Register */
__I uint32_t DFR; /*!< Debug Feature Register */
__I uint32_t ADR; /*!< Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< ISA Feature Register */
} SCB_Type;
它就是地址在 0xE000ED0C 的 32 位寄存器 AIRCR(Application Interrupt/Reset
Control Register),该寄存器的[10:8]3 位就是 PRIGROUP 的定义位,它的值规定了系统中
有多少个抢先级中断和子优先级中断。而 STM32 只使用高 4 位 bits,其可能的值如下(来
自 ST 的函数库头文件中的定义)
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
由于这个寄存器相当重要,为了防止误操作(写),因此当改写这个寄存器的内容时,
必须要同时向这个寄存器的高 16 位[31:16]写验证字(Register key) 0x05FA。
例如:SBC->AIRCR |= (0x05FA0000 || 0x300); // 设置系统中断有 16 个抢先优先
// 级,无子优先级
d/ 下面的定义与SYSTICK相关,有时也会用到的。
/* memory mapping struct for SysTick */
typedef struct
{
__IO uint32_t CTRL; /*!< SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< SysTick Reload Value Register */
__IO uint32_t VAL; /*!< SysTick Current Value Register */
__I uint32_t CALIB; /*!< SysTick Calibration Register */
} SysTick_Type;
e/ 另外的几个寄存器,也是需要使用的(请具体参考相关的资料)
__IO uint8_t SHP[12]; /*!<System Handlers Priority Registers(4-7,8-11,12-15) */
同每个外部中断通道优先级定义字相同,它们是内核中断通道4-15的优先级定义字所在
的寄存器。用户可以通过设置SHP[n],改变内部中断通道的优先级。
__IO uint32_t VTOR; /*!< Vector Table Offset Register */
如果你的代码要在RAM中启动执行,就需要对这个寄存器进行设置。