stm32 NVIC interrupt management implementation [direct operation register]

Publisher:jiaohe1Latest update time:2017-02-06 Source: eefocusKeywords:stm32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

    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:

 

NVIC_table.png

 

    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:

EXTICR1.png

 

 

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:

 

GroupAIRCR[10:8]DistributionAllocation results
0111.xxxx0000Bit 0 indicates the preemption priority, bit 4 indicates the corresponding priority
1110y.xxx00001 bit indicates the preemption priority, 3 bits indicate the corresponding priority
2101yy.xx00002 represents the preemption priority, and 2 represents the corresponding priority
3100yyy.x00003 bits represent the preemption priority, 1 bit represents the corresponding priority
4011yyyy.00004 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<


Keywords:stm32 Reference address:stm32 NVIC interrupt management implementation [direct operation register]

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

Solution to the problem of no unlink device found when downloading STM32 simulation
The problem of no unlink device found is caused by selecting the wrong emulation downloader: solve: The above two selected models are consistent
[Microcontroller]
How to use STM32's on-chip Flash to store Chinese character library
    In embedded systems, cost is often sensitive. If your Flash is large enough, you can save external Flash. I implemented this function using a structure and shared it with netizens. Finally, a download link is attached. In fonts.h:     typedef struct _tFont {        const uint16_t *table;   uint16_t Width;  
[Microcontroller]
How to use STM32's on-chip Flash to store Chinese character library
STM32 learning GPIO
1. First, the GPIO clock should be enabled. All GPIOs are mounted on the bus AHB1. The corresponding library function is RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); RCC_AHB1Periph is the required peripheral mounted on AHB1, and FunctionalState NewState can be ENABLE or DISABLE. Because i
[Microcontroller]
STMicroelectronics launches long-range wireless microcontroller to improve connectivity energy efficiency in smart metering, smart buildings and industrial monitoring
The new STM32 system chip has low power consumption and supports multiple wireless communication protocols, simplifying the design of wireless systems for various purposes. China, November 24, 2023 - STMicroelectronics (ST;), a world-leading semiconductor company serving multiple electronic applications, has releas
[Embedded]
STMicroelectronics launches long-range wireless microcontroller to improve connectivity energy efficiency in smart metering, smart buildings and industrial monitoring
Use of STM32 Advanced Control Timer 1
The advanced control timer (Tim1) in the STM32 is composed of a 16-bit auto-reload counter, which is driven by a programmable prescaler. The purpose is to measure the pulse width of the input signal (input capture), or generate an output waveform (output comparison, PWM, complementary PWM with embedded dead time, etc.
[Microcontroller]
Notes and summary on GPIO bit settings in STM32
1. Software does not need to disable interrupts when programming individual bits of GPIOx_ODR. 2.GPIO has a locking mechanism, which is mainly used on some key pins to prevent the program from running away and causing unnecessary consequences. 3.GPIO library function problem, GPIO_SetBits: Set one or more bits of th
[Microcontroller]
Teach you how to modify the STM32 system clock
 Today, the company gave me a new STM32 control board to debug. I thought it would be easy to debug. But I was shocked to find that the crystal oscillator was 12MHZ. I found some information online and now I have sorted it out for your reference. Specific steps are as follows: The first step is to search HSE_VALUE
[Microcontroller]
Input filtering mechanism of STM32 timer
The timer input channel of STM32 has a filter unit, which is located on each input path (yellow box in the figure below) and external trigger input path (blue box in the figure below). Their function is to filter out high-frequency interference on the input signal. The specific operating principle is as follows: C
[Analog Electronics]
Input filtering mechanism of STM32 timer
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号