STM32 NVIC

ST所提供的範例我們可以看到三大設定,RCCNVICGPIO,如下所示:

/* System Clocks Configuration */
  RCC_Configuration();
      
  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

RCCGPIO 己略介紹過,而NVIC在本章將簡單介紹一下。
NVIC是對中斷優先的管理,首先看在ST所提供的範例 USART 中的DMA_Polling
void NVIC_Configuration(void)
#ifdef  VECT_TAB_RAM 
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif
}

接著看USART  Interrupt 的範例中 NVIC副程式
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM 
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif

  /* Configure the NVIC Preemption Priority Bits */ 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
 
  /* Enable the USART1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Enable the USART2 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


最後看I2C Interrupt的範例中 NVIC副程式

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
#ifdef  VECT_TAB_RAM 
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif

  /* 1 bit for pre-emption priority, 3 bits for subpriority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* Configure and enable I2C1 interrupt -------------------------------------*/
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Configure and enable I2C2 interrupt -------------------------------------*/ 
  NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_Init(&NVIC_InitStructure);
}

USART 中的DMA_Polling 中沒有用到中斷,

USART  Interrupt 的範例中有用到中斷,所以多了

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USART1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

I2C Interrupt的範例中

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;


USART  Interrupt I2C Interrupt的差異
USART 中的
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
I2C Interrupt
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

其中差異在於pre-emption prioritysubpriority
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;


STM32中斷優先等級暫存器 (Interrupt Priority Registers)
  STM32每個Interrupt Channel都擁有屬於自己的interrupt priority register, STM32中每個priority register4bit,這4-bits可以依據功能分成下面五組
NVIC_PriorityGroup_0 => 0 bits for pre-emption priority, 4 bits for subpriority  
NVIC_PriorityGroup_1 => 1 bits for pre-emption priority, 3 bits for subpriority  
NVIC_PriorityGroup_2 => 2 bits for pre-emption priority, 2 bits for subpriority  
NVIC_PriorityGroup_3 => 3 bits for pre-emption priority, 1 bits for subpriority  
NVIC_PriorityGroup_4 => 4 bits for pre-emption priority, 0 bits for subpriority  

NVIC_PriorityGroup
Preemption Priority
Subpriority
NVIC_PriorityGroup_0
0 (1 種設定)
0~15(16 種設定)
NVIC_PriorityGroup_1
0,1(2 種設定)
0~7(8 種設定)
NVIC_PriorityGroup_2
0,1,2,3 (4 種設定)
0,1,2,3(4 種設定)
NVIC_PriorityGroup_3
0,1,2,3,4,5,6,7 (8 種設定)
0,1(2 種設定)
NVIC_PriorityGroup_4
0~15(16 種設定)
0(1 種設定)

注意 (Preemption Priority的設定種類數) (Subpriority的設定種類數)=16
也就是符合2^4=16


     當我們在使用STM32NVIC中斷時會發現,中斷的優先等級分成了preemption priority  subpriority 兩種而這兩優先等級有甚麼不一樣:

1. Preemption Priority
    當中斷發生時,擁有較高Preemption priority=0interrupt channel可以將較低preemptrion priority=1,2,3interrupt chnannel中斷優先被處理。假如兩個interrupt channel擁有相同peemption priority,後到的interrupt event必須等到現有的中斷被處理完畢後才能被處理。
 
2. Subpriority 
     在兩個interrupt channelpreemption priority相同的前提下,如果兩個subpriority不同的interrupt event同時發生,則subpriority高的interrupt會先被處理,但是如果低優先等級的interrupt channel event 已經在執行,則不能被打斷,高subpriorityevent必須等到現有的event被處理完才能被處理。

也就是說NVIC_PriorityGroup_4 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0 的擁有最高的中斷優先權。
NVIC_PriorityGroup_0 中每個interrupt channel event 已經在執行中的,則不會被打斷。

留言

這個網誌中的熱門文章

STM32 I2C-EEPROM 的讀寫

如何提高STM32 ADC的精度

ENC28J60+Uip TCP Server/Client