1.1 外部中断的定义。外部中断(EXTI,External Interrupt/Event Controller)是单片机的一种中断机制。当 GPIO 引脚的电平发生变化,产生上升沿或下降沿时,外部中断控制器检测到该变化并向 CPU 发出中断请求,CPU 暂停当前正在执行的程序,跳转到对应的中断服务函数中处理,处理完毕后再返回主程序继续执行。与轮询查询引脚状态的方式相比,外部中断不需要 CPU 持续读取引脚,响应及时,也不占用多余的 CPU 时间。
1.2 外部中断线与 GPIO 引脚的关系。在 STM32 中,几乎每个 GPIO 引脚都可以作为外部中断输入,但每条外部中断线同一时刻只能连接一个引脚。以 PC13 为例,它对应的外部中断线是 EXTI13。需要说明的是,中断线的编号必须与引脚编号一致,例如编号为 13 的 PC13、PB13、PA13 等引脚,只能选择其中一个接入 EXTI13,具体由引脚复用配置决定。
1.3 外部中断线的分组与中断服务函数。STM32 的外部中断服务函数按组划分:外部中断线 0 到 4 各自拥有独立的中断服务函数 EXTI0_IRQHandler 至 EXTI4_IRQHandler;外部中断线 5 到 9 共享中断服务函数 EXTI9_5_IRQHandler;外部中断线 10 到 15 共享中断服务函数 EXTI15_10_IRQHandler。PC13 对应外部中断线 13,属于 10 到 15 这一组,因此进入的是 EXTI15_10_IRQHandler。同一组内多个中断线共用一个服务函数,需要在处理时判断具体是哪条中断线触发的中断。
1.4 外部中断的触发方式。外部中断支持上升沿触发、下降沿触发和上升下降双沿触发三种方式。上升沿触发指引脚电平由低变高的瞬间产生中断,下降沿触发指引脚电平由高变低的瞬间产生中断,双沿触发则两个方向的跳变都会产生中断。具体选择哪种方式取决于外部电路:按键按下时引脚变为高电平,就应该使用上升沿;按键按下时引脚变为低电平,就应该使用下降沿。
1.5 外部中断与 NVIC 的关系。外部中断控制器检测到跳变后只是将中断标志位置位,CPU 是否响应还取决于嵌套向量中断控制器 NVIC。只有使能了 NVIC 中对应的中断通道,例如 EXTI15_10_IRQn,并正确设置其优先级,中断标志位才能驱动 CPU 进入对应的中断服务函数。
1.6 外部中断在 HAL 库中的处理流程。使用 HAL 库时,外部中断被封装为固定的流程:跳变沿到来后 CPU 进入中断服务函数,中断服务函数调用 HAL 库提供的中断处理函数,由它清除中断标志位并调用用户编写的回调函数,用户在回调函数中填写自己希望执行的业务逻辑。因此开发人员通常只需要编写回调函数,不必直接修改中断服务函数。
1.7 STM32C542RC 与开发板的硬件特点。STM32C542RC 属于 STM32C5 系列,采用 Arm Cortex-M33 内核,最高主频 144MHz,内置 256KB Flash 和 64KB RAM。NUCLEO-C542RC 开发板的用户按键 B1 连接在 PC13 引脚,按键未按下时 PC13 为低电平,按下后连接到 3.3V 变为高电平,因此按键检测应使用上升沿触发;开发板用户 LED 连接在 PA5 引脚,PA5 输出高电平时 LED 点亮,输出低电平时熄灭。
二、STM32CubeMX2 的配置过程2.1 认识 STM32CubeMX2。STM32CubeMX2 是意法半导体推出的新一代图形化配置工具,从 STM32C5 系列开始,所有新推出的微控制器系列都只能使用 STM32CubeMX2 进行配置,老版本的 STM32CubeMX 无法配置 STM32C5 系列。使用前需要从意法半导体官网下载并安装最新版本的 STM32CubeMX2,安装过程中保持网络畅通,以便工具自动下载 STM32C5 系列对应的器件支持包和 HAL 驱动包。
2.2 新建工程并选择芯片或开发板。打开 STM32CubeMX2,在起始页面点击新建工程,在 MCU 名称搜索框中输入 STM32C542RC,即可看到对应的芯片与开发板。可以直接选择 NUCLEO-C542RC 开发板,工具会自动加载开发板的默认资源定义,例如用户按键 B1 对应 PC13、用户 LED 对应 PA5;也可以选择 STM32C542RCT6 芯片后手动配置引脚。随后填写工程名称与保存路径,点击自动下载、安装并创建工程,创建完成后启动工程。
2.3 配置系统时钟。进入工程后,在时钟配置页面查看并修改系统时钟。开发板上带有 24MHz 高速外部晶振,配置时将 HSE 高速外部时钟作为时钟源,经过锁相环 PLL 倍频后使系统主频达到 144MHz。外部中断功能本身不依赖专门的时钟,只要系统时钟配置正常、外设时钟开启,外部中断即可正常工作。
2.4 配置 LED 引脚 PA5。在引脚配置页面找到 PA5 引脚,将其功能设置为输出模式 GPIO_Output。在 GPIO 配置面板中,将初始电平设置为 Low,即上电后 LED 默认熄灭;输出类型选择推挽输出 Push pull,用于驱动 LED 点亮;输出速度选择 Low 即可满足要求。若希望上电后 LED 默认点亮,可将初始电平改为 High。
2.5 配置按键引脚 PC13 的外部中断。找到 PC13 引脚,将其模式设置为输入模式 Input。在 EXTI 配置区中确认外部中断线为 EXTI13,将触发检测方式 Trigger Detection 设置为上升沿 Rising edge,因为本开发板按键按下时 PC13 变为高电平,上升沿即表示按键按下。由于板上已有下拉电阻保证按键未按下时引脚为低电平,上下拉选项可以保持不使能,也可以选择内部下拉。随后在中断配置 Interruption 区域,勾选使能中断 Enabled interruption 和生成中断服务函数 IRQ Handler Generation,工具会自动将 EXTI15_10_IRQHandler 加入中断向量表。
2.6 配置 NVIC 中断优先级。PC13 的外部中断线属于中断线 10 到 15 这一组,对应的 NVIC 中断通道为 EXTI15_10_IRQn。在 NVIC 配置页面中勾选使能该中断通道,并设置抢占优先级和子优先级,数值越小优先级越高。如果系统中只有按键中断和时基中断,使用默认优先级即可;如果存在多个实时性要求不同的中断,需要按需求合理分配。
2.7 使能 HAL 外部中断的回调注册功能。在工程设置 Project settings 中,进入全局服务 Global services 下的 HAL 公共定义 HAL common definitions,找到 HAL EXTI 配置项,将使用寄存器回调 Use register callback 和用户数据 User data 两个选项都设为使能。启用后,生成的代码会包含外部中断的句柄以及回调注册接口,用户才能在 main 函数中注册自己编写的回调函数。
2.8 生成工程代码。完成上述配置后,点击生成代码。生成前可选择目标集成开发环境,例如 STM32CubeIDE,或 Visual Studio Code 配合 STM32Cube 扩展。生成完成后,CubeMX2 会创建完整的工程目录,包含系统初始化、外设初始化、HAL 库文件以及中断服务函数等代码,使用所选开发环境打开工程即可继续编写应用程序。
三、按键 PC13 外部中断点亮 LED 的软件编写步骤
3.1 打开工程并了解代码结构。使用 STM32CubeIDE 或 Visual Studio Code 打开 CubeMX2 生成的工程。STM32C5 系列采用新一代 HAL2 框架,各外设的中断服务函数被组织在各自独立的文件中,外部中断 EXTI13 对应一个以 mx_gpio_default_exti13 命名的句柄。开发时只需要在 main 函数和用户代码区中添加自己的逻辑,不要修改生成的初始化文件,否则重新生成代码时修改会被覆盖。
3.2 编写外部中断回调函数。在 main.c 的用户代码区中编写回调函数,函数签名必须与 HAL2 库的接口一致,例如:
void UserDetectedExtiCallback(hal_exti_handle_t *hexti, hal_exti_trigger_t trigger)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
}函数体中使用 HAL_GPIO_WritePin 将 PA5 引脚输出高电平,从而点亮 LED。由于 PC13 配置为上升沿触发,按键按下产生上升沿后,CPU 进入中断服务函数,最终调用该回调函数,LED 即被点亮。
3.3 在主函数中注册回调并使能中断。在 main 函数中,完成系统初始化之后注册回调函数,并初始化 NVIC、使能外部中断,代码如下:HAL_EXTI_RegisterTriggerCallback(mx_gpio_default_exti13_gethandle(), &UserDetectedExtiCallback); mx_cortex_nvic_init(); HAL_EXTI_Enable(mx_gpio_default_exti13_gethandle(), HAL_EXTI_MODE_INTERRUPT);
注册完成后,PC13 的上升沿即可触发中断并进入回调函数。如果想实现按一下点亮、再按一下熄灭的效果,可以把回调函数中的 HAL_GPIO_WritePin 改为 HAL_GPIO_TogglePin,每次按键都会翻转一次 LED 状态。
3.4 添加按键消抖处理。机械按键在按下和松开的瞬间存在触点抖动,引脚电平会在几毫秒内多次跳变,导致一次按键触发多次中断。可以在回调函数中先延时十几到二十毫秒,再重新读取一次 PC13 的电平,确认按键确实处于按下状态后再执行点亮 LED 的操作,从而滤除抖动引起的误触发。
3.5 编译并下载程序。在开发环境中点击编译,确认没有错误和警告后,通过板上 ST-LINK 仿真器将程序下载到开发板。下载完成后复位运行,按下开发板上的用户按键 B1,LED 应点亮。若使用 STM32CubeProgrammer 下载,注意器件型号选择 STM32C542RCT6,连接方式选择 ST-LINK。
3.6 验证与扩展。调试时可以在回调函数中设置断点,观察按键按下时程序是否正确进入回调函数。在此基础上可以继续扩展:根据回调参数 trigger 区分上升沿和下降沿,实现按下点亮、松开熄灭;或者把按键事件写入一个标志变量,在主循环中读取标志执行更复杂的业务逻辑,保证中断服务函数足够短小。
四、使用过程中的注意事项
4.1 PC13 引脚严禁配置为输出模式。NUCLEO-C542RC 开发板的按键 B1 与 PC13 直接相连,按键按下时引脚直接接触 3.3V 电源。如果错误地将 PC13 配置为推挽输出并输出高电平,按下按键时会形成电源到地的短路,可能损坏引脚甚至芯片。因此 PC13 只能作为输入或外部中断使用,这一点务必牢记。
4.2 触发沿选择必须与电路匹配。本开发板的按键按下时 PC13 为高电平,应使用上升沿触发;而许多其他型号的 Nucleo 开发板按键按下时引脚接地,需要使用下降沿触发。如果直接照搬其他开发板的工程,会出现按下无反应、松开才触发或一次按键多次触发的问题。判断依据是查看开发板原理图或用户手册中按键的连接方式。
4.3 必须处理按键抖动。机械按键抖动客观存在,不做消抖会导致一次按下触发多次中断,表现为 LED 闪烁或按键逻辑错乱。消抖可采用软件延时加电平重读的方式,也可采用定时器定时采样;延时消抖的时间通常十几毫秒即可,时间过长会影响按键响应速度。
五、外部中断的应用场景
5.1 按键与简单人机交互。外部中断最常见的应用就是按键检测。按键按下和松开会产生电平跳变,通过上升沿或下降沿触发中断,实现单击、双击、长按等交互,相比主循环轮询,外部中断不占用额外 CPU 时间,响应也更加及时。矩阵键盘、拨码开关等输入设备同样可以通过外部中断检测状态变化。
5.2 传感器信号触发报警。很多传感器输出数字电平信号,例如人体红外感应模块、门窗磁簧开关、烟雾报警器、限位开关等,检测到目标时输出电平跳变。把这类信号接入外部中断引脚,跳变瞬间立即触发中断,实现即时报警或联动控制,不需要 CPU 反复读取传感器状态,既节省资源又不会漏掉短脉冲信号。
5.3 旋转编码器与位置测量。旋转编码器输出两路正交脉冲,霍尔开关、光电开关、流量计等设备也输出脉冲信号。将脉冲引脚配置为外部中断,每个脉冲触发一次中断并进行计数,就可以测量转速、位置、流量等参数,是一种简单且成本低的测量方案。
我要赚赏金
