關于GD32F1系列同時使用多個GPIO外部中斷時的資料詳解
1、中斷優先級分組和搶占優先級/響應優先級
① 優先級分組
NVIC_PRIGROUP_PRE0_SUB4: 0 bit 搶占優先級 ,4 bit 子優先級
NVIC_PRIGROUP_PRE1_SUB3: 1 bit 搶占優先級 ,3 bit 子優先級
NVIC_PRIGROUP_PRE2_SUB2: 2 bit 搶占優先級 ,2 bit 子優先級
NVIC_PRIGROUP_PRE3_SUB1: 3 bit 搶占優先級 ,1 bit 子優先級
NVIC_PRIGROUP_PRE4_SUB0: 4 bit 搶占優先級 ,0 bit 子優先級
注:整個系統執行過程中,隻需設定一次中斷分組
②搶占優先級/響應優先級差別
* 高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的
* 搶占優先級相同的中斷,高響應優先級不可以打斷低響應優先級的中斷
* 搶占優先級相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先級高,哪個先執行
* 如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行
2、GPIO外部中斷對應EXTI Line 0~15,共16個
PA0,PB0........,PG0對應EXTI0;
PA1,PB1........,PG1對應EXTI1;
................
PA15,PB15........,PG0對應EXTI15;
注:例如:PA0占用EXTI0後,就不可再使用PB0~PG0開啟GPIO中斷
3、中斷函數名
EXTI10~EXTI15對應中斷子函數名:EXTI10_15_IRQHandler
EXTI5~EXTI9對應中斷子函數名:EXTI5_9_IRQHandler
剩餘的EXTI0~EXTI4,例如EXTI0對應中斷子函數名:EXTI0_IRQHandler
4、以下為代碼:
GPIO口配置:
void light_gpio_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,
GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_11);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_13|GPIO_PIN_14);
}
中斷配置:
void light_exti_init(void)
{
/* enable the AF clock */
rcu_periph_clock_enable(RCU_AF);
/* enable and set light EXTI interrupt to the specified priority */
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable(EXTI1_IRQn, 2U, 3U);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_1);
exti_init(EXTI_1, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_flag_clear(EXTI_1);
nvic_irq_enable(EXTI5_9_IRQn, 2U, 1U);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_5);
exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_flag_clear(EXTI_5);
nvic_irq_enable(EXTI10_15_IRQn, 2U, 0U);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_11);
exti_init(EXTI_11, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_flag_clear(EXTI_11);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_13);
exti_init(EXTI_13, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_flag_clear(EXTI_13);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_14);
exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_flag_clear(EXTI_14);
}
中斷子函數:
void EXTI1_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(EXTI_1))
{
exti_interrupt_flag_clear(EXTI_1);
}
}
void EXTI5_9_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(EXTI_5))
{
exti_interrupt_flag_clear(EXTI_5);
}
}
void EXTI10_15_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(EXTI_12)) //K1
{
exti_interrupt_flag_clear(EXTI_12);
}
}