2. 按键控制LED

任务目标

本案例基于沁恒CH32V307微控制器,实现按键控制LED亮灭的功能。核心目标是掌握GPIO输入模式的配置方法以及通过轮询方式读取按键状态。当按键按下时LED点亮,松开时LED熄灭,形成直观的输入输出闭环。

硬件连接

  • LED:正极经限流电阻接PC0(GPIO输出),负极接地
  • 按键:一端接PA0(GPIO输入),另一端接GND,PA0内部使能上拉电阻

完整代码

#include "ch32v30x.h"

// LED引脚定义 - PC0
#define LED_GPIO_PORT      GPIOC
#define LED_GPIO_PIN       GPIO_Pin_0
#define LED_GPIO_CLK       RCC_APB2Periph_GPIOC

// 按键引脚定义 - PA0
#define KEY_GPIO_PORT      GPIOA
#define KEY_GPIO_PIN       GPIO_Pin_0
#define KEY_GPIO_CLK       RCC_APB2Periph_GPIOA

// 按键按下为低电平(内部上拉,按下接地)
#define KEY_PRESSED        (GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PIN) == RESET)

void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(LED_GPIO_CLK | KEY_GPIO_CLK, ENABLE);

    // 配置LED引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = LED_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);

    // 配置按键引脚为带上拉输入
    GPIO_InitStructure.GPIO_Pin = KEY_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStructure);

    // 初始状态:LED熄灭
    GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, Bit_SET);
}

int main(void)
{
    GPIO_Config();

    while(1)
    {
        // 轮询按键状态
        if(KEY_PRESSED)
        {
            GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, Bit_RESET);  // 点亮LED
        }
        else
        {
            GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, Bit_SET);    // 熄灭LED
        }
    }
}

编译与烧录

  1. 使用MounRiver Studio创建CH32V307工程,将上述代码替换主文件内容
  2. 编译工程生成hex文件(快捷键F7)
  3. 通过WCH-Link连接开发板,点击下载按钮(快捷键F8)烧录程序

验证方法

程序烧录完成后,观察以下现象:

  • 初始状态:LED处于熄灭状态
  • 按下按键(PA0接地):LED应立即点亮
  • 松开按键:LED应立即熄灭

若LED状态与按键动作完全同步,说明GPIO输入模式配置正确,轮询读取逻辑有效,案例通过。

关键说明

  • 按键采用低电平有效方式,内部上拉保证未按下时PA0为高电平
  • 轮询方式通过while循环持续读取引脚状态,无需中断参与
  • 若现象相反(按下熄灭、松开点亮),检查按键是否接至VCC而非GND,或调整判断逻辑