3. GPIO外部中断按键检测
任务目标
本案例实现按键控制LED:读取按键状态,按下时切换LED亮灭。核心学习点为GD32V的GPIO输入模式配置与轮询读取方式。
硬件连接
- LED:接PA7,阳极经限流电阻接VCC,阴极接PA7(低电平点亮)
- 按键:接PA0,一端接地,另一端经上拉电阻接VCC(按下为低电平)
代码实现
#include "gd32vf103.h"
void gpio_config(void) {
// 使能GPIOA时钟
rcu_periph_clock_enable(RCU_GPIOA);
// PA7推挽输出,50MHz
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
// PA0浮空输入(外部已接上拉电阻)
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
// 初始状态:LED灭(PA7输出高)
gpio_bit_set(GPIOA, GPIO_PIN_7);
}
int main(void) {
gpio_config();
uint8_t last_key_state = 1; // 上一次按键状态,1=未按下
uint8_t led_state = 0; // 0=灭,1=亮
while (1) {
// 读取当前按键状态(PA0)
uint8_t current_key_state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
// 检测下降沿:从未按下(1)变为按下(0)
if (last_key_state == 1 && current_key_state == 0) {
// 切换LED状态
led_state = !led_state;
if (led_state) {
gpio_bit_reset(GPIOA, GPIO_PIN_7); // 输出低,LED亮
} else {
gpio_bit_set(GPIOA, GPIO_PIN_7); // 输出高,LED灭
}
}
last_key_state = current_key_state;
// 简单延时消抖(约10ms)
for (volatile uint32_t i = 0; i < 100000; i++);
}
}
编译与烧录
- 将上述代码保存为
main.c,替换工程模板中的同名文件。 - 在工程目录下执行编译:
make - 使用GD-Link或串口烧录生成的
.hex或.bin文件到开发板。
验证方法
烧录后观察以下现象:
- 上电时LED处于熄灭状态。
- 每次按下按键并释放,LED亮灭状态切换一次。
- 按住按键不放时,LED状态不反复切换(仅下降沿触发一次)。
若满足上述三点,则按键控制LED功能验证通过。
关键说明
- 本代码采用轮询方式读取PA0电平,通过检测下降沿(按下瞬间)实现单次触发,避免按键按住时LED反复切换。
- 延时循环用于简单消抖,实际工程可替换为定时器消抖方案。
- 若按键接法为按下接高电平,需将输入模式改为上拉输入(
GPIO_MODE_IPU)并反转电平判断逻辑。