3. GPIO外部中断按键检测

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++);
    }
}

编译与烧录

  1. 将上述代码保存为main.c,替换工程模板中的同名文件。
  2. 在工程目录下执行编译:make
  3. 使用GD-Link或串口烧录生成的.hex或.bin文件到开发板。

验证方法

烧录后观察以下现象:

  • 上电时LED处于熄灭状态。
  • 每次按下按键并释放,LED亮灭状态切换一次。
  • 按住按键不放时,LED状态不反复切换(仅下降沿触发一次)。

若满足上述三点,则按键控制LED功能验证通过。

关键说明

  • 本代码采用轮询方式读取PA0电平,通过检测下降沿(按下瞬间)实现单次触发,避免按键按住时LED反复切换。
  • 延时循环用于简单消抖,实际工程可替换为定时器消抖方案。
  • 若按键接法为按下接高电平,需将输入模式改为上拉输入(GPIO_MODE_IPU)并反转电平判断逻辑。