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
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 the systick interrupt. 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< else NVIC->ISER[1]|=1<<(NVIC_Channel-32); NVIC->IPR[IPRADDR]|=temp< }
Previous article:ARM Learning Notes--C Program Basics
Next article:STM32F10X SPI operation flash MX25L64 read and write data
Recommended ReadingLatest update time:2024-11-16 16:48
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Please help explain the principle of PWM2 generated in the following picture
- Clock module of MSP430G2553 microcontroller
- [National Technology N32WB452 Review] 5. Encryption Algorithm Library
- Is there anyone who can run the SPI of CH32V103?
- Free gift of old punch card machine (for disassembly and research)
- I need help from an expert to look at the program and tell me how to modify it so that the buzzer can sound three times and then pause for 0.5 seconds before sounding again.
- MSP430G2755 Main Memory Bootloader UART Porting Guide
- McAsp multi-channel understanding
- Please help me look at this oscillator circuit
- About NCP1236 automatic recovery function test after removing short circuit and overload test