STM32对于中断的简单理解

🧠 什么是中断?(生活化比喻)

想象一下,你正在家里专心看书(这代表单片机的主程序 main 函数在正常运行)。

突然,电话响了(这就是一个"中断信号")。你不得不停下书本,去接电话(执行"中断服务函数"),和对方聊完后挂断电话,然后你回到刚才看的地方继续看书(返回主程序继续执行)。

这就是中断的核心逻辑:打断 -> 处理 -> 返回。

如果不使用中断,你就得每隔几秒钟放下书本去检查一下电话有没有响(这叫"轮询")。这样效率极低,而且你根本看不进去书。而中断让单片机具备了"一心二用"的能力。

⚙️ STM32 中断系统的三大核心组件

在 STM32 内部,处理中断主要靠三个部分协作:

  1. 中断源 (Source):谁在捣乱?
    • 比如按键被按下、定时器时间到了、串口收到了数据。
  2. EXTI (External Interrupt/Event Controller):外部中断控制器
    • 相当于家里的"分机线"。如果你有多个电话(比如客厅电话 PA0、卧室电话 PB0),EXTI 负责把它们接到同一条主线路上。
  3. NVIC (Nested Vectored Interrupt Controller):嵌套向量中断控制器
    • 相当于你的"优先级处理大脑"。如果电话响了(高优先级),你必须立刻停下看书;如果门铃也响了(低优先级),你得等打完电话再去开门。

💻 手把手实战案例:按键控制 LED(标准库版)

我们来写一个简单的代码,实现:主程序让 LED 闪烁,同时随时响应按键按下,一旦按下 LED 状态翻转。

第一步:配置步骤(思维导图)

  1. 初始化外设:初始化 LED 引脚(输出)、按键引脚(输入)。
  2. 配置 EXTI:告诉单片机"我要监控这个按键引脚的变化"。
  3. 配置 NVIC:给这个中断分配一个优先级。
  4. 编写中断服务函数:写好"接电话"时要做的事。

第二步:代码实现

复制代码
include "stm32f10x.h"

// 1. 定义 LED 和按键的 GPIO
define LED_PIN GPIO_Pin_5
define LED_PORT GPIOA
define KEY_PIN GPIO_Pin_0
define KEY_PORT GPIOA

void GPIO_Config(void);
void EXTI0_Config(void);

int main(void)
{
    // 初始化硬件
    GPIO_Config();
    EXTI0_Config();

    while (1)
    {
        // 主程序:LED 慢闪,模拟在做其他工作
        GPIO_SetBits(LED_PORT, LED_PIN);    // 灯灭
        Delay(0x0FFFFF);                    // 延时
        GPIO_ResetBits(LED_PORT, LED_PIN);  // 灯亮
        Delay(0x0FFFFF);                    // 延时
        // 如果没有中断,按键必须在这里才能被检测到,响应很慢!
    }
}

// 2. 配置 GPIO
void GPIO_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 配置 LED 为推挽输出
    GPIO_InitStructure.GPIO_Pin = LED_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT, &GPIO_InitStructure);

    // 配置按键为上拉输入
    GPIO_InitStructure.GPIO_Pin = KEY_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_Init(KEY_PORT, &GPIO_InitStructure);
}

// 3. 配置外部中断
void EXTI0_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    // 连接 EXTI Line0 到 PA0 引脚
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;           // 监控第 0 号线路
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   // 中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发(按键按下通常是从高变低)
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    // 4. 配置 NVIC 优先级
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 设置优先级分组

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;            // 选择中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   // 抢占优先级最高
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// 5. 中断服务函数 (ISR) - 这就是"接电话"的过程
// 注意:函数名是固定的,必须这么写,由启动文件定义
void EXTI0_IRQHandler(void)
{
    // 1. 必须先判断是不是这个中断发生的(防止误判)
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 2. 在这里写你的处理逻辑
        // 比如:翻转 LED 状态
        GPIO_WriteBit(LED_PORT, LED_PIN, 
                      (BitAction)(1 - GPIO_ReadOutputDataBit(LED_PORT, LED_PIN)));
        
        // 3. 清除中断标志位 (非常重要!如果不清理,CPU 会认为还在响铃,一直进中断)
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

// 简单的延时函数
void Delay(__IO uint32_t nCount)
{
    for(; nCount != 0; nCount--);
}

🔍 代码关键点分析

  1. 下降沿触发 (EXTI_Trigger_Falling)
    • 按键未按下时是高电平,按下瞬间变成低电平。这个从"高"到"低"的变化叫下降沿。我们只在这个瞬间触发一次中断,避免按住不放导致反复触发多次。
  2. 清除标志位 (EXTI_ClearITPendingBit)
    • 这是新手最容易忘记的一步!就像电话挂断后,电话机上的红灯必须熄灭。如果不手动清除,单片机会以为电话还在响,从而卡死在中断里出不来。
  3. NVIC 优先级
    • 如果你有多个中断(比如同时有按键和定时器),优先级高的会先处理。STM32 支持中断嵌套(高优先级打断低优先级)。

📌 总结

  • 轮询 (Polling):主动去查,"按键按了吗?按了吗?" ------ 效率低,实时性差。
  • 中断 (Interrupt):被动通知,"叮咚!按键按了!" ------ 效率高,实时性强。
相关推荐
来自晴朗的明天4 小时前
23、MCU 上电复位(POR)电路
单片机·嵌入式硬件·硬件工程
上海合宙LuatOS6 小时前
LuatOS核心库API——【fft 】 快速傅里叶变换
java·前端·人工智能·单片机·嵌入式硬件·物联网·机器学习
嵌入式科普7 小时前
一、为什么RA6T2是数字电源与伺服的理想MCU
单片机·瑞萨·数字电源·ra6t2
余生皆假期-11 小时前
无感观测的锁相环 (PLL) 原理与实现方式
单片机·嵌入式硬件
Menida12 小时前
STM32 加强篇 定时器&PWM波应用实验——用无源蜂鸣器播放音乐/放歌
stm32·单片机·嵌入式硬件·定时器·无源蜂鸣器·pwm波
Struggle to dream12 小时前
STM32中断的种类以及使用注意事项
stm32·单片机·嵌入式硬件
_Ningye12 小时前
STM32 — 1-2 — STM32简介
stm32·单片机·嵌入式硬件
m0_5557629012 小时前
高级定时器
单片机·嵌入式硬件
DLGXY13 小时前
STM32(十八)——IIC通信、MPU6050、IIC外设
stm32·单片机·嵌入式硬件