STM32外部中断
in 单片机 with 0 comment
记录一下stm32的中断 我用的型号 STM32F407ZGTx

使用外部中断

首先中断给分组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
然后要开启对应的时钟 比如对应的 GPIOx SYSCFG(stm32f407x)
通过 APB2(低速外设总线)开启SYSCFG AHB(高性能总线)开启GPIO

// 开启对应 GPIOx
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
// 开启 SYSCFG 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

然后正常配置GPIO (GPIO模式输入 上下拉根据硬件设置)

/* GPIO 初始化代码 */

接下来就要连接中断线

// GPIOx的N号引脚
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourceN);

接下来就是配置 NVIC 和 EXTI 了

NVIC_InitTypeDef NVIC_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn; // 中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // 使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; // 主优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; // 次优先级
NVIC_Init(&NVIC_InitStruct);

EXTI_InitStruct.EXTI_Line = EXTI_Line2; // 中断线
EXTI_InitStruct.EXTI_LineCmd = ENABLE; // 使能
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断/事件 模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_Init(&EXTI_InitStruct);

最后写对应的中断程序

extern void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2) == SET) {
        delay_ms(10);
        if (keyScan(2))
            toggleLed(1);
    }
    EXTI_ClearITPendingBit(EXTI_Line2);
}

后记

EXTI_Linex只能对应EXTIx_IRQn吗

基本上是的,EXTI_Linex 通常对应 EXTIx_IRQn,但 有例外,特别是当 EXTI Line ≥ 5 时,它们共用中断向量。
示例:多个中断线共用一个中断服务函数(以 EXTI_Line7 为例)

void EXTI9_5_IRQHandler(void)
{
    // 判断是不是EXTI7触发的
    if (EXTI_GetITStatus(EXTI_Line7) == SET) {
        // 处理 PE7 的中断
        /* ... */
        // 清理EXTI7中断标志位
        EXTI_ClearITPendingBit(EXTI_Line7);
    }
}

中断向量表

EXTI Line对应中断向量中断函数名
EXTI0EXTI0\_IRQnEXTI0_IRQHandler(void)
EXTI1EXTI1\_IRQnEXTI1_IRQHandler(void)
EXTI2EXTI2\_IRQnEXTI2_IRQHandler(void)
EXTI3EXTI3\_IRQnEXTI3_IRQHandler(void)
EXTI4EXTI4\_IRQnEXTI4_IRQHandler(void)
EXTI5\~9EXTI9\_5\_IRQnEXTI9_5_IRQHandler(void)
EXTI10\~15EXTI15\_10\_IRQnEXTI15_10_IRQHandler(void)