STM32 NVIC
在ST所提供的範例我們可以看到三大設定,RCC、NVIC、GPIO,如下所示:
/* System
Clocks Configuration */
RCC_Configuration();
/* NVIC configuration */
NVIC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
RCC和GPIO 己略介紹過,而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 priority與subpriority
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
STM32中斷優先等級暫存器
(Interrupt Priority Registers)
STM32每個Interrupt Channel都擁有屬於自己的interrupt
priority register, STM32中每個priority register是4個bit,這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。
當我們在使用STM32的NVIC中斷時會發現,中斷的優先等級分成了preemption priority 與subpriority 兩種而這兩優先等級有甚麼不一樣:
1. Preemption
Priority
當中斷發生時,擁有較高Preemption priority=0的interrupt channel可以將較低preemptrion
priority=1,2,3的interrupt chnannel中斷優先被處理。假如兩個interrupt
channel擁有相同peemption priority,後到的interrupt
event必須等到現有的中斷被處理完畢後才能被處理。
2. Subpriority
在兩個interrupt channel的preemption priority相同的前提下,如果兩個subpriority不同的interrupt event同時發生,則subpriority高的interrupt會先被處理,但是如果低優先等級的interrupt channel event 已經在執行,則不能被打斷,高subpriority的event必須等到現有的event被處理完才能被處理。
也就是說NVIC_PriorityGroup_4
中 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 0 的擁有最高的中斷優先權。
而NVIC_PriorityGroup_0 中每個interrupt channel
event 已經在執行中的,則不會被打斷。
留言
張貼留言