4. 外部中断
📝本节您将了解中断的基本概念和 MSPM0G3519 的中断系统,学习如何配置 GPIO 外部中断,实现按键触发的事件驱动编程。
🏆本章目标
1️⃣ 理解中断的概念和工作机制
2️⃣ 了解 MSPM0G3519 的中断系统架构
3️⃣ 通过 SysConfig 配置 GPIO 外部中断
4️⃣ 编写中断服务函数实现按键中断控制 LED
4.1 中断概念
在前面的按键实验中,我们使用轮询方式检测按键——CPU 在主循环中不断读取引脚状态。这种方式简单但效率低下:CPU 大部分时间在做无意义的查询,无法同时处理其他任务。
中断(Interrupt) 是一种事件驱动机制:当特定事件发生时(如按键按下、定时器溢出、数据接收完成),硬件自动通知 CPU 暂停当前工作,跳转到预先编写的中断服务函数(ISR)中执行处理,处理完毕后自动返回被中断的位置继续执行。

中断可以分为两种类型:
- 硬件中断:由外部设备的物理事件引发(按键按下、定时器到时、串口数据到达等)。事件发生时,CPU 立即暂停当前任务,跳转到对应的中断服务函数。
- 软件中断:由软件指令引发,通常用于操作系统的系统调用等场景。
对比轮询与中断:
| 方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 轮询 | CPU 主动循环查询 | 实现简单 | 浪费 CPU 资源,响应延迟大 |
| 中断 | 硬件触发,CPU 被动响应 | 实时性好,CPU 利用率高 | 编程稍复杂 |
4.2 外部中断
外部中断是硬件中断的一种,由微控制器外部事件引发。GPIO 引脚可配置为外部中断引脚,当引脚电平发生指定变化时自动触发中断。
MSPM0 系列把 CPU 中断、DMA 触发、外设触发外设统称为事件(Event):
- 事件发布者(Event Publisher):产生事件的源头(如 GPIO 电平变化)
- 事件订阅者(Event Subscriber):响应事件的目标(如 CPU 中断处理、DMA 传输启动)
事件管理器传输的事件类型:
| 事件类型 | 说明 | 示例 |
|---|---|---|
| CPU 中断(静态事件) | 外设事件作为 IRQ 传输到 CPU | GPIO 中断发送到 CPU |
| DMA 触发 | 外设事件触发 DMA 传输 | UART 接收数据触发 DMA 搬运 |
| 外设触发外设(通用事件) | 一个外设事件直接触发另一个外设操作 | 定时器周期事件触发 ADC 采样 |
GPIO 中断触发方式
| 触发方式 | 说明 | 典型应用 |
|---|---|---|
| 下降沿(Falling Edge) | 电平从高到低的瞬间触发 | 按键按下(上拉输入) |
| 上升沿(Rising Edge) | 电平从低到高的瞬间触发 | 按键释放、信号到来 |
| 双边沿(Both Edges) | 任意电平变化均触发 | 编码器计数 |

天巧星的 KEY1(PA24)为上拉输入,按下时电平从高变低,选择下降沿触发。
4.3 MSPM0G3519 中断服务函数列表
GPIO 中断触发后通过 GROUP1 线发布到中断总线。以下是 MSPM0G3519 常用的中断服务函数名称(函数名固定,不可修改):
| 中断函数名 | 中断说明 |
|---|---|
| GROUP0_IRQHandler | GROUP0 中断函数 |
| GROUP1_IRQHandler | GROUP1 中断函数(GPIO 中断在此) |
| TIMG8_IRQHandler | TIMG8 定时器中断 |
| UART0_IRQHandler | UART0 中断 |
| UART1_IRQHandler | UART1 中断 |
| UART3_IRQHandler | UART3 中断 |
| UART4_IRQHandler | UART4 中断 |
| UART5_IRQHandler | UART5 中断 |
| UART6_IRQHandler | UART6 中断 |
| UART7_IRQHandler | UART7 中断 |
| SPI0_IRQHandler | SPI0 中断 |
| SPI1_IRQHandler | SPI1 中断 |
| SPI2_IRQHandler | SPI2 中断 |
| I2C0_IRQHandler | I2C0 中断 |
| I2C1_IRQHandler | I2C1 中断 |
| I2C2_IRQHandler | I2C2 中断 |
| 中断函数名 | 中断说明 |
|---|---|
| TIMG0_IRQHandler | TIMG0 定时器中断 |
| TIMG6_IRQHandler | TIMG6 定时器中断 |
| TIMG7_IRQHandler | TIMG7 定时器中断 |
| TIMG9_IRQHandler | TIMG9 定时器中断 |
| TIMG12_IRQHandler | TIMG12 定时器中断 |
| TIMG14_IRQHandler | TIMG14 定时器中断 |
| TIMA0_IRQHandler | TIMA0 高级定时器中断 |
| TIMA1_IRQHandler | TIMA1 高级定时器中断 |
| ADC0_IRQHandler | ADC0 中断 |
| ADC1_IRQHandler | ADC1 中断 |
| DAC0_IRQHandler | DAC0 中断 |
| CANFD0_IRQHandler | CANFD0 中断 |
| CANFD1_IRQHandler | CANFD1 中断 |
| AESADV_IRQHandler | AES 加密模块中断 |
| DMA_IRQHandler | DMA 中断 |
| LFSS_IRQHandler | LFSS 低频子系统中断(含 RTC) |
| SysTick_Handler | 滴答定时器中断 |
以上为外设中断。Cortex-M0+ 内核还提供了 4 个系统异常:
NMI_Handler(不可屏蔽中断)、HardFault_Handler(硬错误)、SVC_Handler(系统服务调用)、PendSV_Handler(可挂起系统调用),日常开发一般不会用到。
重要
GPIO 的外部中断全部通过 GROUP1_IRQHandler 进入。在该函数内部通过 DL_Interrupt_getPendingGroup() 判断具体是哪个引脚触发的中断。
4.4 SysConfig 配置外部中断
本实验使用 KEY1(PA24)触发中断,控制 LED(PB22)翻转。
4.4.1 配置 LED 引脚(输出)
与第 2 章相同,配置 PB22 为 GPIO 输出模式(详见 GPIO 章节)。

4.4.2 配置按键引脚(输入 + 中断)
在 GPIO 选项卡中 ADD 一组新的 GPIO,按键配置如下:
端口参数:
| 参数 | 设置值 | 说明 |
|---|---|---|
| Name | KEY | 自定义实例名称 |
引脚参数:
| 参数 | 设置值 | 说明 |
|---|---|---|
| Name | A24 | 引脚名称 |
| Direction | Input | 输入模式 |
| Internal Resistor | Pull-Up Resistor | 上拉电阻,默认高电平 |
| Assigned Port | PORTA | PORTA |
| Assigned Pin | 24 | PA24 |
点击查看截图 — 按键引脚(PA24)输入配置

中断参数:
| 参数 | 设置值 | 说明 |
|---|---|---|
| Interrupt Enable | Enable | ✅ 使能中断 |
| Interrupt Edge | Falling Edge | 下降沿触发(按下为低) |
| Interrupt Priority | Default | 默认优先级 |
点击查看截图 — 中断参数配置

保存 .syscfg 文件并编译工程。
SysConfig 自动生成的宏
配置保存后,SysConfig 自动生成以下宏供代码使用:
KEY_INT_IRQN— 中断号,用于NVIC_EnableIRQ()KEY_INT_IIDX— 中断索引,用于switch判断中断来源KEY_PORT— 端口地址KEY_A24_PIN— 引脚掩码
4.5 外部中断实验代码
4.5.1 按键中断翻转 LED
#include "ti_msp_dl_config.h"
int main(void)
{
SYSCFG_DL_init();
// 使能 KEY 按键的 NVIC 中断
NVIC_EnableIRQ(KEY_INT_IRQN);
while (1) {
// 主循环空闲,按键处理在中断中完成
__WFI(); // Wait For Interrupt,CPU 低功耗等待
}
}
// GROUP1 中断服务函数 — GPIO 中断入口
void GROUP1_IRQHandler(void)
{
// 读取 GROUP1 中断寄存器并自动清除中断标志位
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
case KEY_INT_IIDX:
// KEY1 按下(下降沿触发),翻转 LED
DL_GPIO_togglePins(LED_PORT, LED_B22_PIN);
break;
default:
break;
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
代码说明
NVIC_EnableIRQ(KEY_INT_IRQN)
使能 NVIC 中对应的中断。KEY_INT_IRQN 是 SysConfig 生成的中断号宏。SysConfig 在 SYSCFG_DL_init() 中配置了引脚的中断触发条件,但 NVIC 层面的使能需要代码中手动调用。
__WFI()
Wait For Interrupt 指令,让 CPU 进入低功耗等待状态。比空的 while(1){} 更省电——CPU 在没有中断时停止执行,有中断到来时自动唤醒。
DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)
读取 GROUP1 的挂起中断状态并自动清除标志位。返回值为触发中断的具体来源索引。
KEY_INT_IIDX
SysConfig 生成的中断索引值。通过 switch-case 匹配该值,可以确认是 KEY1 引脚触发的中断。
4.5.2 编译与下载
- 在工程文件夹上右键 →
Build Project(s)编译 - 确认编译通过(0 Errors)
- 连接 XDS110 → 右键工程 →
Debug Project下载 - 点击 ▶ 运行程序
运行结果:每按一次 KEY1,LED 状态翻转一次。
4.6 中断消抖
机械按键的抖动在中断模式下更明显——每次电平跳变都触发一次中断,一次按键动作可能产生多次中断。
简单的消抖方案:在中断中加入延时后再次确认引脚状态。
void GROUP1_IRQHandler(void)
{
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
case KEY_INT_IIDX:
// 延时消抖(约20ms)
delay_cycles(640000);
// 再次确认按键仍为按下状态(低电平)
if (DL_GPIO_readPins(KEY_PORT, KEY_A24_PIN) == 0) {
DL_GPIO_togglePins(LED_PORT, LED_B22_PIN);
}
break;
default:
break;
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
注意
在中断服务函数中使用 delay_cycles 进行消抖是简化方案。严格来说,ISR 中不应有长时间阻塞操作。更规范的做法是:
- 中断中设置标志位
- 主循环中检测标志位并延时消抖
- 或配合硬件定时器做精确消抖
本教程为入门演示,采用简化方案。后续定时器章节会介绍更优雅的实现。
4.7 多按键中断
天巧星有多个按键可配置中断。如果同时使用 KEY1(PA24)和 KEY2(PB24),在 SysConfig 中分别添加配置即可。
在中断服务函数中通过 switch-case 区分来源:
void GROUP1_IRQHandler(void)
{
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
case KEY_INT_IIDX:
// KEY1 按下
DL_GPIO_togglePins(LED_PORT, LED_B22_PIN);
break;
case GPIO_KEY2_INT_IIDX:
// KEY2 按下 — 执行其他操作
break;
default:
break;
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
提示
同一 GROUP 内的多个中断源共享一个中断服务函数,通过 DL_Interrupt_getPendingGroup() 的返回值逐一匹配。每个中断源对应一个唯一的 IIDX 宏。
4.8 知识总结
| 概念 | 说明 |
|---|---|
| 中断源 | 触发中断的事件来源(GPIO 电平变化、定时器溢出等) |
| ISR | 中断服务函数,中断发生时硬件自动调用 |
| NVIC | Arm Cortex-M0+ 的中断控制器,管理使能和优先级 |
| GROUP1 | MSPM0 中 GPIO 中断所属的中断组 |
| 触发方式 | 上升沿、下降沿、双边沿 |
| volatile | ISR 中修改的全局变量必须用此关键字修饰 |
| __WFI() | 低功耗等待中断指令,无中断时 CPU 休眠 |
掌握了外部中断后,按键检测不再需要 CPU 持续轮询,系统响应更高效。下一章将学习串口通信,实现天巧星与电脑之间的数据交互。