【C】嵌入式的中断,理解

🚀 嵌入式中断(Interrupt)概念解析

在嵌入式系统中,中断(Interrupt)是一种硬件或软件事件 ,它可以打断 CPU 的正常运行流程,立即执行特定的中断服务程序(ISR,Interrupt Service Routine),以快速响应某些紧急任务或外设事件。


🔹 为什么需要中断?

在嵌入式系统中,CPU 通常需要处理外部事件(例如按键输入、传感器数据、通信数据等)。有两种方式来检测这些事件:

  1. 轮询(Polling)

    • CPU 主动循环检查某个外设状态(如读取按键是否按下)。
    • 缺点:CPU 资源占用高,即使没有事件发生,也会不断执行检查,浪费功耗。
  2. 中断(Interrupt)

    • 事件发生时 ,外设主动通知 CPU,让 CPU 立即执行处理代码。
    • 优势:
      降低 CPU 资源消耗 (无需不断轮询)
      实时性更高(事件发生时立即响应)

🔹 中断的基本流程

  1. 外设或软件触发中断

    • 例如,串口收到一帧数据、定时器超时、按钮被按下。
  2. CPU 保存当前执行状态

    • 保存 PC(程序计数器)、寄存器等状态,以便稍后返回继续执行。
  3. CPU 跳转到中断服务程序(ISR)

    • 执行对应的中断服务函数,处理事件(如读取传感器数据)。
  4. ISR 结束后,恢复 CPU 运行

    • CPU 恢复之前的状态,继续执行被中断的代码。

🔹 硬件中断 vs. 软件中断

类型 触发方式 应用场景
硬件中断 外设(GPIO、定时器、串口)等触发 传感器数据采集、定时任务
软件中断 软件代码手动触发 trigger_interrupt() 任务切换、异常处理

🔹 常见的中断类型

外部中断(GPIO、按键)

  • 通过 外部引脚 触发,如 按键按下、传感器信号变化。
  • 示例:STM32 的 EXTI(外部中断控制器)

定时器中断

  • 设定定时器定期触发 ,用于周期性任务,如 定时 LED 闪烁、定时任务调度
  • 示例:STM32 的 TIMx 计时器

串口中断(UART、SPI、I2C)

  • 当串口收到数据发送完成 时触发。
  • 示例:串口接收中断 USART_RX_IRQHandler()

DMA(直接内存访问)中断

  • 数据传输完成 时触发,如 ADC 采集完数据后通知 CPU 处理
  • 适用于 大数据量传输,减少 CPU 负担

🔹 中断代码示例

① GPIO 外部中断

📌 场景: 按键按下触发中断,点亮 LED

c 复制代码
// 1. 初始化外部中断
void GPIO_EXTI_Init(void)
{
    EXTI->IMR |= (1 << 0);  // 使能外部中断 0 (GPIO0)
    EXTI->RTSR |= (1 << 0); // 触发方式:上升沿--【  指信号 从低电平(0)跳变到高电平(1) 的瞬间
    NVIC_EnableIRQ(EXTI0_IRQn); // 使能 NVIC 中断
}

// 2. 外部中断服务函数
void EXTI0_IRQHandler(void)
{
    if (EXTI->PR & (1 << 0)) // 检测是否是 EXTI0 触发
    {
        LED_Toggle(); // 反转 LED 状态
        EXTI->PR |= (1 << 0); // 清除中断标志位
    }
}

🔹 流程:

  1. 按键按下,GPIO 产生电平变化(上升沿)。
  2. EXTI0_IRQHandler() 被 CPU 调用,执行 LED 反转 逻辑。
  3. 清除中断标志位,等待下一次中断触发。

② 定时器中断

📌 场景: 每 1 秒触发一次定时器中断,控制 LED 闪烁

c 复制代码
// 1. 配置定时器
void Timer_Init(void)
{
    TIM2->PSC = 8000 - 1;   // 预分频,使 1ms 计数一次
    TIM2->ARR = 1000 - 1;   // 自动重装值,1s 触发一次
    TIM2->DIER |= (1 << 0); // 使能中断
    NVIC_EnableIRQ(TIM2_IRQn); // 使能 NVIC 中断
    TIM2->CR1 |= (1 << 0);  // 使能定时器
}

// 2. 定时器中断服务函数
void TIM2_IRQHandler(void)
{
    if (TIM2->SR & (1 << 0)) // 检测中断标志
    {
        LED_Toggle(); // LED 反转
        TIM2->SR &= ~(1 << 0); // 清除中断标志
    }
}

🔹 流程:

  1. 定时器 TIM2 每隔 1 秒触发一次中断。
  2. TIM2_IRQHandler() 处理中断,执行 LED 反转操作。
  3. 清除中断标志,等待下一次定时触发。

🔹 中断的高级用法

1️⃣ 中断嵌套

  • 高优先级中断可以打断低优先级的中断。
  • 例如:定时器中断(低优先级) 执行时,外部 GPIO 按键(高优先级) 依然能触发并中断。

2️⃣ 低功耗模式下的中断唤醒

  • 嵌入式设备在低功耗模式下(如 STOPSLEEP),CPU 处于休眠状态。
  • 外部中断(如 GPIO、串口)可以唤醒系统,减少功耗。
c 复制代码
// 进入低功耗模式
__WFI();  // 等待中断,CPU 休眠

📌 场景: 设备长时间待机,按键唤醒系统。


🔹 小结

概念 说明
中断 事件发生时 CPU 立即响应,执行 ISR 处理
轮询 CPU 不断检查外设状态,效率低
外部中断 例如 按键、GPIO 触发
定时器中断 例如 1 秒触发一次定时任务
串口中断 UART、SPI、I2C 数据接收
DMA 中断 数据传输完成通知 CPU
中断嵌套 高优先级中断可抢占低优先级

📌 嵌入式开发中,中断是 提高系统实时性和效率的重要手段 🎯

相关推荐
qq_257379594 分钟前
python基础-字符串速查笔记
开发语言·笔记·python
一条闲鱼_mytube9 分钟前
golang recover错误
开发语言·后端·golang
Sean_summer10 分钟前
python语言总结(持续更新)
开发语言·python
虽千万人 吾往矣10 分钟前
golang算法快慢指针
开发语言·算法·golang
竹等寒14 分钟前
Go红队开发—web网络编程
开发语言·前端·网络·安全·web安全·golang
界面开发小八哥20 分钟前
数据可视化图表库LightningChart JS 全新发布v7.0——提高视觉质量
开发语言·javascript·信息可视化·图表·lightningchart
蹦蹦跳跳真可爱58922 分钟前
Python----数据可视化(Seaborn二:绘图一)
开发语言·python·信息可视化
点云SLAM25 分钟前
Python 数据可视化
开发语言·python·信息可视化·数据可视化
沐墨专攻技术31 分钟前
C语言操作符详解
c语言·算法
__lost35 分钟前
韦伯望远镜的拉格朗日点计算推导过程,包含MATLAB和python运动轨迹仿真代码
开发语言·python·matlab