Stm32 Nvic Interrupt Management implementation [direct Operation Register]

Source: Internet
Author: User

This article transferred from: http://www.ichanging.org/stm32_NVIC.html

The CORTEX-M3 supports 256 midrange, which contains 16 core interrupts and 240 external interrupts. The STM32 has only 84 interrupts, including 16 core interrupts and 68 unshielded interrupts.     There are only 60 interrupts on the stm32f103 and 68 interrupts on the f107. Interrupts are a very basic feature of stm32, learning to use interrupts to better use other peripherals. To understand Stm32 's interruption, you must first start with the Stm32 Interrupt Priority GroupingWhat's going on. To understand priority groupings, first understand what is First-priorityAnd Sub-priorityFirst-priorityis equivalent to a 51 single-chip interrupt. Assuming that there are two interrupts successively triggered, the interrupt that has been executed first takes precedence if there is no post-trigger interrupt first, and the first high-priority interrupt is processed first. In other words, a higher priority interrupt can interrupt first-priority interrupts. This is the basis for implementing interrupt nesting. Sub-priorityOnly when the same first-priority interrupt is triggered at the same time, the priority is the same, and the priority execution is the higher-priority interrupt. The secondary priority does not cause an interrupt nesting. If the two priority of the interrupt is the same, then the interrupt with the higher position in the interrupt vector table is performed preferentially. It is also important to note that the high interrupt priority here refers to whether it is closer to level 0 and the highest level of 0 priority. So what is the lowest priority level possible? This involves the concept of priority grouping. The stm32 uses an interrupt vector controller (NVIC) to allocate the number of priority and sub-priority in the first order. The arm CORTEX-M3 Core has a 3-bit width prigroup data area that indicates the position of the decimal point in a 8-bit data series and thus represents the grouping of interrupt priorities. For example, a better understanding: if the Prigroup data bit 000 is 0, the decimal position in the 8-bit data series is xxxxxxx.y to the left of the 1th bit, the meaning of the grouping used to represent the interrupt priority is to use the 7-bit data width to represent the first-priority number as 128. 1-bit data width to indicate the number of secondary priority is 2

So 2 of the three in arm cortex-m3 is a 8 priority group. However, there are only 5 priority groupings in Stm32, which represent a slightly different approach, as referenced in 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 GroupA total of 60 stm32 can be shielded interrupts, where two 32-bit registers are used, which can represent 64 interrupts. Stm32 only used the first 60 digits. To enable an interrupt, you must set the corresponding Iser bit to 1. Each of the corresponding interrupt relationships is as follows: (see stm32f10x_nvic.h under MDK)

#ifdef STM32F10X_HD
ADC1_2_IRQN =/*!< ADC1 and ADC2 Global Interrupt * *
USB_HP_CAN1_TX_IRQN =/*!<, USB Device high priority or CAN1 TX interrupts */
USB_LP_CAN1_RX0_IRQN =/*!< USB Device Low priority or CAN1 RX0 interrupts */
CAN1_RX1_IRQN =,/*!< CAN1 RX1 Interrupt * *
CAN1_SCE_IRQN =/*!< CAN1 SCE Interrupt */
EXTI9_5_IRQN =/*!< External Line[9:5] Interrupts * *
TIM1_BRK_IRQN =/*!< TIM1 break Interrupt */
TIM1_UP_IRQN =/*!< TIM1 Update Interrupt */
TIM1_TRG_COM_IRQN =/*!< TIM1 Trigger and commutation Interrupt * *
TIM1_CC_IRQN =/*!< TIM1 Capture Compare Interrupt * *
TIM2_IRQN =/*!< TIM2 Global Interrupt */
TIM3_IRQN =/*!< TIM3 Global Interrupt */
TIM4_IRQN =/*!< TIM4 Global Interrupt */
I2C1_EV_IRQN =/*!< i2c1 Event Interrupt */
I2C1_ER_IRQN = +,/*!< i2c1 Error Interrupt */
I2C2_EV_IRQN =/*!< i2c2 Event Interrupt */
I2C2_ER_IRQN =/*!<, i2c2 Error Interrupt */
SPI1_IRQN =/*!< SPI1 Global Interrupt */
SPI2_IRQN =/*!<, SPI2 global Interrupt */
USART1_IRQN = PNS,/*!< USART1 Global Interrupt */
USART2_IRQN =/*!<, USART2 global Interrupt */
USART3_IRQN =/*!< USART3 Global Interrupt */
EXTI15_10_IRQN =/*!< External line[15:10] Interrupts * *
RTCALARM_IRQN =/*!< RTC Alarm through Exti line Interrupt * *
USBWAKEUP_IRQN =/*!< USB Device WakeUp from suspend through Exti line Interrupt */
TIM8_BRK_IRQN =/*!< TIM8 break Interrupt */
TIM8_UP_IRQN =/*!<, TIM8 Update Interrupt */
TIM8_TRG_COM_IRQN =/*!< TIM8 Trigger and commutation Interrupt * *
TIM8_CC_IRQN =/*!< TIM8 Capture Compare Interrupt * *
ADC3_IRQN =/*!< ADC3 Global Interrupt */
FSMC_IRQN =/*!< FSMC Global Interrupt */
SDIO_IRQN =/*!< SDIO Global Interrupt */
TIM5_IRQN =,/*!< TIM5 Global Interrupt */
SPI3_IRQN = Wuyi,/*!< SPI3 Global Interrupt */
UART4_IRQN =/*!< UART4 Global Interrupt */
UART5_IRQN =/*!< UART5 Global Interrupt */
tim6_irqn = si,/*!< TIM6 global Interrupt */
TIM7_IRQN =/*!< TIM7 Global Interrupt */
DMA2_CHANNEL1_IRQN =/*!< DMA2 Channel 1 Global Interrupt */
DMA2_CHANNEL2_IRQN =/*!<, DMA2 Channel 2 Global Interrupt */
DMA2_CHANNEL3_IRQN =/*!< DMA2 Channel 3 Global Interrupt */
DMA2_CHANNEL4_5_IRQN =/*!< DMA2 Channel 4 and Channel 5 global Interrupt */
#endif/* STM32F10X_HD */

System interrupts are not stated here, so some system interrupts are not available, such as Systick interrupts this is the most convenient timer on Stm32 systick[operation Register + library function] has been analyzed icer[2]: Interrupt purge Register GroupStructure with Iser[2], but the opposite is the effect. The interruption is not clear by the corresponding bit write 0 to iser[2], but to the icer[2] corresponding bit write 1. Ispr[2]: Interrupt suspend control Register groupEach of the corresponding interrupts and Iser is the same. Performs a sibling or higher-level interrupt by placing a pending interrupt on hold. Icpr[2]: Interrupt the Unlock register groupStructure and ispr[2] are the same, acting the opposite. Reset 1 to suspend the corresponding interrupt. iabr[2]: Interrupt activation flag bit Register GroupInterrupts and iser[2] corresponds, if 1, indicates that the interrupt corresponding to the bit is executing. This is a read-only register that is automatically zeroed out by the hardware. ipr[15]: Register Group for interrupt priority controlThe IPR Register group consists of 15 32-bit registers. Each masked interrupt occupies 8 bits, which can be represented by a masked interrupt of 15*4 = 60. The 8 bits that are occupied by each masked interrupt are not used in all, but only high 4 bits are used. These 4 bits are also divided into preemption priority and sub-priority. Preemption priority is before, and child priority is behind. Each of these two priorities is determined by the set of interrupt groupings in SCB-&GT;AIRCR. &NBSP;IPR Register Description:   stm32 will break into 5 groups, group 0~4. The grouping is defined by the [10:8] three bits of the SCB-&GT;AIRCR register. The specific relationship is as follows: 
Group Aircr[10:8] Allocation Situation Allocation Results
0 111 . xxxx0000 0-bit indicates preemption priority, 4-bit indicates corresponding priority
1 110 y.xxx0000 1-bit indicates preemption priority, 3-bit indicates corresponding priority
2 101 yy.xx0000 2 is the preemption priority, and the 2-bit represents the corresponding priority level
3 100 yyy.x0000 3-bit indicates preemption priority, 1-bit indicates corresponding priority
4 011 yyyy.0000 4-bit indicates preemption priority, 0-bit indicates corresponding priority
The interrupt management implementation is as follows:

void Nvic_prioritygroupconfig (uint32_t nvic_prioritygroup)
{
/* Check The parameters * * *
Assert_param (Is_nvic_priority_group (Nvic_prioritygroup));

/* Set the Prigroup[10:8] bits according to Nvic_prioritygroup value */
SCB->AIRCR = Aircr_vectkey_mask | Nvic_prioritygroup;
}

/**
* @brief initializes the NVIC peripheral according to the specified
* Parameters in the nvic_initstruct.
* @param nvic_initstruct:pointer to a NVIC_INITTYPEDEF structure that contains
* The configuration information for the specified NVIC peripheral.
* @retval None
*/
void Nvic_init (nvic_inittypedef* nvic_initstruct)
{
uint32_t tmppriority = 0x00, Tmppre = 0x00, tmpsub = 0x0F;

/* Check The parameters * * *
Assert_param (Is_functional_state (nvic_initstruct->nvic_irqchannelcmd));
Assert_param (Is_nvic_preemption_priority (nvic_initstruct->nvic_irqchannelpreemptionpriority));
Assert_param (Is_nvic_sub_priority (nvic_initstruct->nvic_irqchannelsubpriority));

if (nvic_initstruct->nvic_irqchannelcmd! = DISABLE)
{
/* Compute the corresponding IRQ priority--------------------------------*/
Tmppriority = (0x700-((SCB-&GT;AIRCR) & (uint32_t) 0x700) >> 0x08;
Tmppre = (0x4-tmppriority);
Tmpsub = Tmpsub >> tmppriority;

Tmppriority = (uint32_t) nvic_initstruct->nvic_irqchannelpreemptionpriority << tmppre;
tmppriority |= nvic_initstruct->nvic_irqchannelsubpriority & tmpsub;
Tmppriority = tmppriority << 0x04;

Nvic->ip[nvic_initstruct->nvic_irqchannel] = tmppriority;

/* Enable the Selected IRQ Channels--------------------------------------*/
Nvic->iser[nvic_initstruct- >nvic_irqchannel >> 0x05] =
(uint32_t) 0x01 << (Nvic_initstruct->nvic_irqchannel & (uint8_t) 0x1F);
}
Else
{
/* Disable the Selected IRQ Channels-------------------------------------*/
nvic->icer[ Nvic_initstruct->nvic_irqchannel >> 0x05] =
(uint32_t) 0x01 << (nvic_initstruct->nvic_ Irqchannel & (uint8_t) 0x1F);
}
}

/**
* @brief sets the vector table location and Offset.
* @param nvic_vecttab:specifies if the vector table is in RAM or FLASH memory.
* This parameter can be one of the following values:
* @arg Nvic_vecttab_ram
* @arg Nvic_vecttab_flash
* @param offset:vector Table base Offset field. This value must is a multiple
* of 0x200.
* @retval None
*/
void Nvic_setvectortable (uint32_t nvic_vecttab, uint32_t Offset)
{
/* Check The parameters * * *
Assert_param (Is_nvic_vecttab (Nvic_vecttab));
Assert_param (Is_nvic_offset (OFFSET));

Scb->vtor = Nvic_vecttab | (Offset & (uint32_t) 0x1fffff80);
}

Stm32 Nvic Interrupt Management implementation [direct Operation Register]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.