STM32F4 NVIC or Nested Vector Interrupt Controller
Interrupts are important in microcontrollers. WIth them you are able to stop executing main program and jump to some predefined area if there is something important.
I already used interrupts in my USART library. There is an interrupt called each time data arrive to MCU.
Defferent peripheral can trigger interrupt, like data come to USART, ADC finished conversion, timer overflow, and more more.
NVIC
NVIC or Nested Vector Interrupt Controller is used to dinamically tell which interrupt is more important and for enabling or disabling interrupts. It supports up to 256 different interrupt vectors.
NVIC Structure
This is defined in “misc.h” file in CMSIS pack.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
typedef struct { uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. This parameter can be an enumerator of @ref IRQn_Type enumeration (For the complete STM32 Devices IRQ Channels list, please refer to stm32f4xx.h file) */ uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel specified in NVIC_IRQChannel. This parameter can be a value between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table A lower priority value indicates a higher priority */ uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified in NVIC_IRQChannel. This parameter can be a value between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table A lower priority value indicates a higher priority */ FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel will be enabled or disabled. This parameter can be set either to ENABLE or DISABLE */ } NVIC_InitTypeDef; |
NVIC structure accept 4 parameters.
NVIC_IRQChannel
Here you tell for which interrupt you will set settings.
NVIC_IRQChannelPreemptionPriority
With this parameter you set interrupt priority, number from 0x00 to 0x0F. Let’s say we have to use USART receive interrupt and ADC conversion finished interrupt. USART is more important than ADC, so USART will have lower number than ADC.
NVIC_IRQChannelSubPriority
With this parameter you set interrupt priority, number from 0x00 to 0x0F. Let’s say you have 2 USARTs enabled, but USART1 is more important than USART2. So USART1 will have lower number than USART2.
NVIC_IRQChannelCmd
With that you select if interrupt is enabled or disabled.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//USART interrupts are most important //USART1 is more important than USART2, so it has lower sub priority number NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); |
Handle interrupts
For handling interrupts we can use special defined function names. In our example, for handle USART1 interrupts, we can use something like this
1 2 3 4 5 6 7 8 9 10 11 |
//This will handle ALL interrupts which are enabled for USART1 //so you have to find first which one was triggered void USART1_IRQHandler(void) { //Check if interrupt was because data is received if (USART_GetITStatus(USART1, USART_IT_RXNE)) { //Do your stuff here //Clear interrupt flag USART_ClearITPendingBit(USART1, USART_IT_RXNE); } } |
Recent comments