Cortex-M3 supports 256 interrupts, including 16 core interrupts and 240 external interrupts. STM32 has only 84 interrupts, including 16 core interrupts and 68 maskable interrupts. STM32F103 has only 60 interrupts, and F107 has only 68 interrupts.
Interrupt is a very basic function of STM32. Only by learning how to use interrupt can you better use other peripherals. To understand the interrupt of STM32, you must first understand what the interrupt priority grouping of STM32 is. To understand the priority grouping, you must first understand what is the preemptive priority and the secondary priority.
The concept of preemptive priority is equivalent to the interrupt in 51 MCU. Assuming that two interrupts are triggered one after another, if the interrupt that has been executed has a higher preemptive priority than the interrupt that is triggered later, the interrupt with higher preemptive priority will be processed first. In other words, an interrupt with higher preemptive priority can interrupt an interrupt with lower preemptive priority. This is the basis for realizing interrupt nesting.
The secondary priority only works when interrupts of the same preemptive priority are triggered at the same time. If the preemptive priorities are the same, the interrupt with the higher secondary priority will be executed first. The secondary priority will not cause interrupt nesting. If the two priorities of the interrupt are the same, the interrupt with the higher position in the interrupt vector table will be executed first.
Another point that needs to be noted is that the high interrupt priority here refers to whether it is closer to level 0, and level 0 has the highest priority.
So what is the lowest priority? This involves the concept of priority grouping. STM32 uses an interrupt vector controller (NVIC) to allocate the number of preemptive priorities and secondary priorities.
The arm cortex-m3 core has a 3-bit wide PRIGROUP data area, which is used to indicate the position of the decimal point in an 8-bit data sequence to indicate the grouping of interrupt priorities.
Let's take an example to better understand: If the PRIGROUP data bit 000 is 0, it means that the decimal position in the 8-bit data sequence is to the left of the first bit, which is xxxxxxx.y. The meaning of the grouping used to represent the interrupt priority is that the number of preemptive priorities is 128 when the data width is 7 bits, and the number of secondary priorities is 2 when the data width is 1 bit.
So there are 8 priority groups in arm cortex-m3, which is 2 to the power of 3.
However, there are only 5 priority groups in stm32, and the representation method is slightly different. Refer to the following table:
The interrupt-related register structure defined in MDK is:
typedef struct
{
vu32 ISER[2];
u32 RESERVED0[30];
vu32 ICER[2];
u32 RSERVED1[30];
vu32 ISPR[2];
u32 RESERVED2[30];
vu32 ICPR[2];
u32 RESERVED3[30];
vu32 IABR[2];
u32 RESERVED4[62];
vu32 IPR[15];
} NVIC_TypeDef;
ISER[2]: Interrupt enable register group
There are 60 maskable interrupts in stm32. Two 32-bit registers are used here to represent 64 interrupts. stm32 only uses the first 60 bits. To enable an interrupt, the corresponding ISER bit must be set to 1.
The specific interrupt relationship corresponding to each bit is as follows: (see stm32f10x_nvic.h under MDK)
#define WWDG_IRQChannel ((u8)0x00) /* Window WatchDog Interrupt */ #define PVD_IRQChannel ((u8)0x01) /* PVD through EXTI Line detection Interrupt */ #define TAMPER_IRQChannel ((u8)0x02) /* Tamper Interrupt */ #define RTC_IRQChannel ((u8)0x03) /* RTC global Interrupt */ #define FLASH_IRQChannel ((u8)0x04) /* FLASH global Interrupt */ #define RCC_IRQChannel ((u8)0x05) /* RCC global Interrupt */ #define EXTI0_IRQChannel ((u8)0x06) /* EXTI Line0 Interrupt */ #define EXTI1_IRQChannel ((u8)0x07) /* EXTI Line1 Interrupt */ #define EXTI2_IRQChannel ((u8)0x08) /* EXTI Line2 Interrupt */ #define EXTI3_IRQChannel ((u8)0x09) /* EXTI Line3 Interrupt */ #define EXTI4_IRQChannel ((u8)0x0A) /* EXTI Line4 Interrupt */ #define DMA1_Channel1_IRQChannel ((u8)0x0B) /* DMA1 Channel 1 global Interrupt */ #define DMA1_Channel2_IRQChannel ((u8)0x0C) /* DMA1 Channel 2 global Interrupt */ #define DMA1_Channel3_IRQChannel ((u8)0x0D) /* DMA1 Channel 3 global Interrupt */ #define DMA1_Channel4_IRQChannel ((u8)0x0E) /* DMA1 Channel 4 global Interrupt */ #define DMA1_Channel5_IRQChannel ((u8)0x0F) /* DMA1 Channel 5 global Interrupt */ #define DMA1_Channel6_IRQChannel ((u8)0x10) /* DMA1 Channel 6 global Interrupt */ #define DMA1_Channel7_IRQChannel ((u8)0x11) /* DMA1 Channel 7 global Interrupt */ #define ADC1_2_IRQChannel ((u8)0x12) /* ADC1 et ADC2 global Interrupt */ #define USB_HP_CAN_TX_IRQChannel ((u8)0x13) /* USB High Priority or CAN TX Interrupts */ #define USB_LP_CAN_RX0_IRQChannel ((u8)0x14) /* USB Low Priority or CAN RX0 Interrupts */ #define CAN_RX1_IRQChannel ((u8)0x15) /* CAN RX1 Interrupt */ #define CAN_SCE_IRQChannel ((u8)0x16) /* CAN SCE Interrupt */ #define EXTI9_5_IRQChannel ((u8)0x17) /* External Line[9:5] Interrupts */ #define TIM1_BRK_IRQChannel ((u8)0x18) /* TIM1 Break Interrupt */ #define TIM1_UP_IRQChannel ((u8)0x19) /* TIM1 Update Interrupt */ #define TIM1_TRG_COM_IRQChannel ((u8)0x1A) /* TIM1 Trigger and Commutation Interrupt */ #define TIM1_CC_IRQChannel ((u8)0x1B) /* TIM1 Capture Compare Interrupt */ #define TIM2_IRQChannel ((u8)0x1C) /* TIM2 global Interrupt */ #define TIM3_IRQChannel ((u8)0x1D) /* TIM3 global Interrupt */ #define TIM4_IRQChannel ((u8)0x1E) /* TIM4 global Interrupt */ #define I2C1_EV_IRQChannel ((u8)0x1F) /* I2C1 Event Interrupt */ #define I2C1_ER_IRQChannel ((u8)0x20) /* I2C1 Error Interrupt */ #define I2C2_EV_IRQChannel ((u8)0x21) /* I2C2 Event Interrupt */ #define I2C2_ER_IRQChannel ((u8)0x22) /* I2C2 Error Interrupt */ #define SPI1_IRQChannel ((u8)0x23) /* SPI1 global Interrupt */ #define SPI2_IRQChannel ((u8)0x24) /* SPI2 global Interrupt */ #define USART1_IRQChannel ((u8)0x25) /* USART1 global Interrupt */ #define USART2_IRQChannel ((u8)0x26) /* USART2 global Interrupt */ #define USART3_IRQChannel ((u8)0x27) /* USART3 global Interrupt */ #define EXTI15_10_IRQChannel ((u8)0x28) /* External Line[15:10] Interrupts */ #define RTCAlarm_IRQChannel ((u8)0x29) /* RTC Alarm through EXTI Line Interrupt */ #define USBWakeUp_IRQChannel ((u8)0x2A) /* USB WakeUp from suspend through EXTI Line Interrupt */ #define TIM8_BRK_IRQChannel ((u8)0x2B) /* TIM8 Break Interrupt */ #define TIM8_UP_IRQChannel ((u8)0x2C) /* TIM8 Update Interrupt */ #define TIM8_TRG_COM_IRQChannel ((u8)0x2D) /* TIM8 Trigger and Commutation Interrupt */ #define TIM8_CC_IRQChannel ((u8)0x2E) /* TIM8 Capture Compare Interrupt */ #define ADC3_IRQChannel ((u8)0x2F) /* ADC3 global Interrupt */ #define FSMC_IRQChannel ((u8)0x30) /* FSMC global Interrupt */ #define SDIO_IRQChannel ((u8)0x31) /* SDIO global Interrupt */ #define TIM5_IRQChannel ((u8)0x32) /* TIM5 global Interrupt */ #define SPI3_IRQChannel ((u8)0x33) /* SPI3 global Interrupt */ #define UART4_IRQChannel ((u8)0x34) /* UART4 global Interrupt */ #define UART5_IRQChannel ((u8)0x35) /* UART5 global Interrupt */ #define TIM6_IRQChannel ((u8)0x36) /* TIM6 global Interrupt */ #define TIM7_IRQChannel ((u8)0x37) /* TIM7 global Interrupt */ #define DMA2_Channel1_IRQChannel ((u8)0x38) /* DMA2 Channel 1 global Interrupt */ #define DMA2_Channel2_IRQChannel ((u8)0x39) /* DMA2 Channel 2 global Interrupt */ #define DMA2_Channel3_IRQChannel ((u8)0x3A) /* DMA2 Channel 3 global Interrupt */ #define DMA2_Channel4_5_IRQChannel ((u8)0x3B) /* DMA2 Channel 4 and DMA2 Channel 5 global Interrupt */
System interrupts are not declared here, so some system interrupts cannot be used, such as systick interrupts. The most convenient timer Systick [operation register + library function] on stm32 has been analyzed.
ICER[2]: Interrupt clear register group
The structure is the same as ISER[2], but the function is opposite. The interrupt is not cleared by writing 0 to the corresponding bit in ISER[2], but by writing 1 to the corresponding bit in ICER[2].
ISPR[2]: Interrupt Pending Control Register Group
The interrupt corresponding to each bit is the same as ISER. By setting 1, the ongoing interrupt is suspended and the interrupt of the same level or higher level is executed.
ICPR[2]: Interrupt release register group
The structure is the same as ISPR[2], but the function is opposite. Setting it to 1 will clear the corresponding interrupt.
IABR[2]: Interrupt activation flag register group
Interrupt corresponds to ISER[2]. If it is 1, it means the interrupt corresponding to this bit is being executed. This is a read-only register and is automatically cleared by hardware.
IPR[15]: interrupt priority control register group
The IPR register group consists of 15 32-bit registers. Each maskable interrupt occupies 8 bits, so the number of maskable interrupts that can be represented is 15*4 = 60. However, the 8 bits occupied by each maskable interrupt are not all used, but only the upper 4 bits are used. These 4 bits are divided into preemption priority and sub-priority. The preemption priority is in front and the sub-priority is in the back. The number of bits of each of these two priorities is determined by the interrupt grouping setting in SCB->AIRCR.
IPR register description:
STM32 divides interrupts into 5 groups, group 0 to 4. The group is defined by the three bits [10:8] of the SCB->AIRCR register. The specific relationship is as follows:
Group | AIRCR[10:8] | Distribution | Allocation results |
---|---|---|---|
0 | 111 | .xxxx0000 | Bit 0 indicates the preemption priority, bit 4 indicates the corresponding priority |
1 | 110 | y.xxx0000 | 1 bit indicates the preemption priority, 3 bits indicate the corresponding priority |
2 | 101 | yy.xx0000 | 2 represents the preemption priority, and 2 represents the corresponding priority |
3 | 100 | yyy.x0000 | 3 bits represent the preemption priority, 1 bit represents the corresponding priority |
4 | 011 | yyyy.0000 | 4 bits represent the preemption priority, 0 bits represent the corresponding priority |
Interrupt management is implemented as follows:
//Set the vector table offset address //NVIC_VectTab: base address //Offset: offset void Nvic_SetVectorTable(u32 NVIC_VectTab, u32 Offset) { // Check the validity of the parameters assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); assert_param(IS_NVIC_OFFSET(Offset)); SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80); //Set the vector table offset register of NVIC //Used to identify whether the vector table is in the CODE area or the RAM area } //Set NVIC grouping //NVIC_Group: NVIC group 0~4, 5 groups in total void Nvic_PriorityGroupConfig(u8 NVIC_Group) { u32 temp,temp1; //Configure vector table #ifdef VECT_TAB_RAM Nvic_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else Nvic_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif temp1=(~NVIC_Group)&0x07;//Get the last three digits temp1<<=8; temp=SCB->AIRCR; //Read the previous setting temp&=0X0000F8FF; //Clear the previous group temp|=0X05FA0000; //Write key temp|=temp1; SCB->AIRCR=temp; //Set group } //Set up NVIC //NVIC_PreemptionPriority: preemption priority //NVIC_SubPriority: response priority //NVIC_Channel: interrupt number //NVIC_Group: interrupt group 0~4 //Note that the priority cannot exceed the range of the set group! Otherwise, there will be unexpected errors //Group division: //Group 0: 0 bit preemption priority, 4 bit response priority //Group 1: 1-bit preemption priority, 3-bit response priority //Group 2: 2-bit preemption priority, 2-bit response priority //Group 3: 3-bit preemption priority, 1-bit response priority //Group 4: 4-bit preemption priority, 0-bit response priority //The principle of NVIC_SubPriority and NVIC_PreemptionPriority is that the smaller the value, the higher the priority void Nvic_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) { u32 temp; u8 IPRADDR=NVIC_Channel/4; //Each group can only store 4, get the group address u8 IPROFFSET=NVIC_Channel%4; //Offset within the group IPROFFSET=IPROFFSET*8+4; //Get the exact offset position Nvic_PriorityGroupConfig(NVIC_Group); //Set group temp=NVIC_PreemptionPriority<<(4-NVIC_Group); temp|=NVIC_SubPriority&(0x0f>>NVIC_Group); temp&=0xf; //Get the lower four bits if(NVIC_Channel<32)NVIC->ISER[0]|=1<ISER[1]|=1<<(NVIC_Channel-32); NVIC->IPR[IPRADDR]|=temp<
Previous article:stm32 external interrupt nesting [operation register + library function]
Next article:stm32 TIM timer [operation register + library function]
Recommended ReadingLatest update time:2024-11-15 14:06
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Brief Analysis of Automotive Ethernet Test Content and Test Methods
- How haptic technology can enhance driving safety
- Let’s talk about the “Three Musketeers” of radar in autonomous driving
- Why software-defined vehicles transform cars from tools into living spaces
- How Lucid is overtaking Tesla with smaller motors
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- [AB32VG1 development board review] TF card and file reading and writing applications
- 280049Solution to the problem of LaunchPad emulator not being able to connect
- Tips for Powering FPGAs
- [TI recommended course] #[High Precision Laboratory] Interface: 1 RS-485#
- What is the use of connecting Schottky diodes in parallel at both ends of the MOS tube used as a switch at the power input?
- Friends in Xi'an, please get out of this pit as soon as possible.
- Read the good book "Electronic Engineer Self-study Handbook" + my impression
- Three-port network
- RSL10 drives ink screen
- GoKit Case Study: Gizwits IoT Development Platform’s Pet House Transformed into an Air Quality Detector