2. 按键输入与中断
任务目标
使用STM32的外部中断(EXTI)功能读取按键状态,实现按键按下时翻转LED的亮灭状态。本案例以STM32F103系列为例,按键接入PA0引脚(对应EXTI0中断线),LED接PC13引脚。
硬件连接
- 按键一端接PA0,另一端接GND(按下为低电平)
- LED正极经限流电阻接PC13,负极接GND(低电平点亮)
- PA0需配置为上拉输入,确保按键未按下时引脚为高电平
实现代码
#include "stm32f10x.h"
// 按键中断服务函数
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
// 翻转PC13电平(LED状态取反)
GPIO_WriteBit(GPIOC, GPIO_Pin_13,
(BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
// 按键GPIO与EXTI初始化
void KEY_EXTI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
// PA0上拉输入(按键按下接地)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PC13推挽输出(控制LED)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 将PA0连接到EXTI0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
// 配置EXTI0:下降沿触发(按键按下时产生中断)
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 配置NVIC:使能EXTI0中断通道
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
// 初始化按键中断
KEY_EXTI_Init();
// 初始状态:LED熄灭(PC13输出高电平)
GPIO_SetBits(GPIOC, GPIO_Pin_13);
while (1) {
// 主循环无任务,等待中断触发
}
}
编译与烧录
- 使用Keil MDK或STM32CubeIDE创建工程,芯片选择STM32F103C8T6(或兼容型号)
- 将上述代码复制到main.c中,确保包含标准外设库头文件路径
- 编译工程,通过ST-Link或J-Link烧录到开发板
验证方法
烧录完成后,观察LED状态:
- 上电后LED应处于熄灭状态
- 每次按下按键(PA0接地),LED应立即翻转状态(亮→灭或灭→亮)
- 松开按键后LED保持当前状态不变,等待下一次按下
若按键按下时LED无反应,检查PA0是否配置为上拉输入、EXTI触发边沿是否为下降沿,以及NVIC中断是否已使能。
关键说明
- 本案例使用下降沿触发,对应按键按下瞬间;如需检测松开动作可改为上升沿触发
- 实际应用中按键存在机械抖动,可在硬件上加RC滤波或软件延时消抖;本案例为演示中断机制,未做消抖处理
- 中断服务函数中执行操作应尽量简短,避免在中断中处理耗时任务