【外部中断】基于STM32标准库

一、外部中断核心概念

  1. EXTI (External Interrupt/Event Controller)
    STM32 的 GPIO 引脚可配置为外部中断源,通过 EXTI 模块管理中断触发。

  2. NVIC (Nested Vectored Interrupt Controller)
    负责中断优先级管理和中断服务函数(ISR)的路由。

  3. 中断服务函数 (ISR)
    中断触发后自动调用的函数,需用户实现。

二、中断号与管脚的映射关系

STM32 的 EXTI 线(0-15) 对应 GPIO 引脚号,但同一时刻每个 EXTI 线只能绑定到一个 GPIO 端口。

EXTI 线支持的 GPIO 引脚中断通道 (IRQn)中断号
EXTI0PA0, PB0, PC0, …, Px0EXTI0_IRQn6
EXTI1PA1, PB1, PC1, …, Px1EXTI1_IRQn7
EXTI15PA15, PB15, PC15, …, Px15EXTI15_10_IRQn40
关键规则:
  • EXTI 线编号 = GPIO 引脚号(如 PA3 使用 EXTI3)。
  • 同一 EXTI 线可被多个 GPIO 端口复用(但需通过配置选择具体端口)。
  • 不同 EXTI 线对应不同的中断通道(IRQn)和中断号。

三、按键中断配置步骤(以 PA0 为例)

1. GPIO 初始化
GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  // 上拉输入(按键接地时使用)
// GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;  // 下拉输入(按键接电源时使用)
GPIO_Init(GPIOA, &GPIO_InitStruct);
2. 配置 EXTI 中断线
EXTI_InitTypeDef EXTI_InitStruct;

// 绑定 PA0 到 EXTI0 线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发(按键按下)
// EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发(按键释放)
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
3. 配置 NVIC 中断优先级
NVIC_InitTypeDef NVIC_InitStruct;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 优先级分组(根据需求选择)

NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;   // 中断通道为 EXTI0
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;        // 子优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
4. 编写中断服务函数 (ISR)
void EXTI0_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        // 处理按键中断逻辑
        EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
    }
}

四、中断号与管脚关系详解

  1. EXTI 线选择

    • 每个 GPIO 引脚号对应一个 EXTI 线(如 PA5 使用 EXTI5)。
    • 通过 GPIO_EXTILineConfig() 选择具体 GPIO 端口(PA/PB/PC…)。
  2. 中断通道 (IRQn)

    • EXTI0-4 有独立的中断通道(如 EXTI0_IRQn)。
    • EXTI5-9 共享 EXTI9_5_IRQn,EXTI10-15 共享 EXTI15_10_IRQn
  3. 中断服务函数名称

    • 必须与启动文件 (startup_stm32fxxx.s) 中的中断向量名称严格一致。

五、常见问题

  1. 中断未触发

    • 检查 GPIO 时钟和 AFIO 时钟是否使能。
    • 确认中断服务函数名称是否正确。
    • 确保中断标志位被清除。
  2. 多引脚共享同一 EXTI 线

    • 若 PA0 和 PB0 同时使用 EXTI0,需在 ISR 中判断具体引脚:
      if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
          // PA0 触发中断
      }
      
  3. 按键消抖

    • 硬件消抖:并联 0.1μF 电容。
    • 软件消抖:在 ISR 中延时 10-20ms 后再次检测电平。

六、完整示例代码

#include "stm32f10x.h"

void EXTI0_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
            // 处理按键按下事件
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

int main(void) {
    // GPIO 初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // EXTI 配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStruct);

    // NVIC 配置
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    while(1) {
        // 主循环
    }
}

通过以上步骤,您可快速掌握 STM32 标准库的外部中断配置方法,并理解中断号与 GPIO 管脚的对应关系。实际开发中需根据具体型号调整引脚和时钟配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值