关于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);
}
}