STM32 HAL库开发学习7. GPIO输入与中断配置
一、GPIO输入模式基础
在STM32中,GPIO的输入模式直接影响信号检测的稳定性和可靠性,主要包含以下三种配置:
浮空输入(GPIO_MODE_INPUT_FLOATING)
引脚直接连接内部施密特触发器,无上下拉电阻,适用于外部已有明确电平的场景(如接外部上拉电路)。
上拉输入(GPIO_MODE_INPUT_PULLUP)
内部上拉电阻(约40kΩ)使引脚默认保持高电平,适合检测低电平有效的信号(如按键按下接地)。
下拉输入(GPIO_MODE_INPUT_PULLDOWN)
内部下拉电阻(约40kΩ)使引脚默认保持低电平,适合检测高电平有效的信号(如传感器触发高脉冲)。
关键代码:配置GPIO输入模式
cGPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉输入 GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
1
二、外部中断(EXTI)机制详解
STM32的 EXTI(External Interrupt) 模块可将GPIO信号转换为中断事件,实现实时响应。中断触发分成三种类型:
- 上升沿触发:GPIO从低→高跳变时触发
- 下降沿触发:GPIO从高→低跳变时触发
- 双边沿触发:任意跳变均触发
硬件映射规则
EXTI线与GPIO引脚存在固定映射关系(参考《STM32F4参考手册》表14)。例如:
PA0、PB0、PC0 共享 EXTI0 中断线
需通过 SYSCFG_EXTILineConfig() 函数选择具体引脚源。
三、实战:按键中断控制LED
3.1 CubeMX配置步骤
新建工程,选择开发板对应的芯片,双击型号:
按键引脚设置
我的开发板上 KEY_UP 接了上拉电阻:
使用PA0引脚,设置为GPIO_EXTIx模式:
LED引脚设置
开发板PC0接LED1,设为推挽输出模式:
配置NVIC:
勾选对应的EXTI0中断通道并设置占优先级和子优先级:
项目设置
生成代码并添加用户逻辑,使用Keil打开生成的工程。
3.2 中断代码实现
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == GPIO_PIN_0) {
// 当检测到高电平时点亮LED(按键按下)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0,
HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 引脚状态直接映射到LED
}
}
/* USER CODE END 4 */
123456789
效果是:按下KEY_UP,LED1点亮。
3. 程序执行流程
(1)硬件中断触发
当PA0检测到配置的边沿信号(上升沿/下降沿)时,触发EXTI0中断。
(2)中断服务函数调用
CPU自动跳转到中断向量表,执行CubeMX生成的EXTI0_IRQHandler(位于stm32f1xx_it.c)。
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
12345678910
(3)HAL库处理层
HAL_GPIO_EXTI_IRQHandler 实现如下关键操作:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u) // 检查中断标志
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); // 清除中断标志
HAL_GPIO_EXTI_Callback(GPIO_Pin); // 调用用户回调函数
}
}
12345678
(4)用户回调执行
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
// 用户自定义的中断处理逻辑
}
/* USER CODE END 4 */