3. 按键控制LED

按键控制LED 学习卡片

任务说明

本案例基于中微CMS32系列车规MCU,实现按键控制LED的功能。核心任务是将一个GPIO引脚配置为输入模式(连接按键),另一个GPIO引脚配置为推挽输出(连接LED),通过轮询方式读取按键电平状态,当按键按下时点亮LED,松开时熄灭LED。代码采用寄存器直接操作方式,不依赖厂商库函数,便于理解底层GPIO工作原理。

硬件连接

  • 按键:一端接PB0引脚,另一端接GND(按下为低电平)
  • LED:正极经限流电阻(约330Ω)接PB1引脚,负极接GND
  • MCU:CMS32L051(中微车规级MCU)

GPIO寄存器配置说明

CMS32L051的GPIO相关寄存器包括:端口模式控制寄存器(PMC)、端口输出寄存器(P)、端口输入寄存器(PI)、端口驱动能力寄存器(PDR)等。PB0和PB1属于端口B,其控制寄存器基地址为0x4004_0000。配置流程为:先将PMC寄存器对应位清零设为端口模式,再通过PDR寄存器配置输入/输出方向,最后通过P寄存器输出或PI寄存器读取状态。

代码实现

// main.c
#include "CMS32L051.h"

// 寄存器地址定义(基于CMS32L051用户手册)
#define PB_BASE         0x40040000UL
#define PB_PMC          (*(volatile unsigned int *)(PB_BASE + 0x00))
#define PB_PDR          (*(volatile unsigned int *)(PB_BASE + 0x04))
#define PB_P            (*(volatile unsigned int *)(PB_BASE + 0x08))
#define PB_PI           (*(volatile unsigned int *)(PB_BASE + 0x0C))

// 引脚位定义
#define KEY_PIN         (1U << 0)   // PB0 - 按键输入
#define LED_PIN         (1U << 1)   // PB1 - LED输出

// 系统时钟初始化(内部RC 8MHz)
static void SystemClock_Init(void)
{
    // 使用默认内部高速时钟,无需额外配置
}

// GPIO初始化
static void GPIO_Init(void)
{
    // 1. 将PB0和PB1设为端口模式(PMC=0)
    PB_PMC &= ~(KEY_PIN | LED_PIN);
    
    // 2. 配置方向:PB0输入(PDR=0),PB1输出(PDR=1)
    PB_PDR &= ~KEY_PIN;          // PB0设为输入
    PB_PDR |= LED_PIN;           // PB1设为输出
    
    // 3. 初始状态:LED熄灭(输出高电平,LED负极接GND)
    PB_P |= LED_PIN;
}

// 主函数
int main(void)
{
    unsigned int key_state;
    
    SystemClock_Init();
    GPIO_Init();
    
    while (1)
    {
        // 读取按键状态(按下为低电平)
        key_state = (PB_PI & KEY_PIN) ? 1 : 0;
        
        if (key_state == 0)  // 按键按下
        {
            PB_P &= ~LED_PIN;   // 输出低电平,LED点亮
        }
        else                 // 按键松开
        {
            PB_P |= LED_PIN;    // 输出高电平,LED熄灭
        }
    }
}

代码说明

代码首先定义了端口B相关寄存器的地址映射,通过指针方式直接访问。GPIO_Init函数完成端口模式、方向配置,并设置LED初始熄灭状态。主循环中持续读取PB0引脚电平,当检测到低电平时(按键按下),将PB1输出低电平点亮LED;否则输出高电平熄灭LED。由于按键按下时引脚被拉低,松开时通过内部上拉恢复高电平,因此无需额外配置上拉电阻。

编译与烧录

  1. 使用IAR Embedded Workbench或Keil MDK创建工程,芯片选择CMS32L051;
  2. 将上述代码保存为main.c并加入工程;
  3. 编译工程生成HEX文件;
  4. 使用中微提供的CMS-ICE仿真器或CMS32Prog烧录工具,将HEX文件下载至MCU。

验证方法

完成烧录后,按下按键并观察LED状态。判定标准:

  • 按键按下时,LED应立即点亮;
  • 松开按键后,LED应立即熄灭;
  • 反复按下/松开按键,LED状态跟随按键动作稳定切换,无闪烁或延迟。

若LED状态与按键动作相反,检查按键连接是否接至GND而非VCC;若LED始终不亮,检查限流电阻及LED极性连接。

CMS32L051 车规MCU PB0 PB1 按键 GND LED 330Ω 按下=低电平 输出低=点亮 连接说明 按键 → PB0 LED → PB1 GND 按键按下→PB0=0

关键寄存器映射

寄存器地址功能
PMC0x4004_0000端口模式控制(0=端口,1=复用)
PDR0x4004_0004端口方向(0=输入,1=输出)
P0x4004_0008输出数据寄存器
PI0x4004_000C输入电平寄存器

本案例通过轮询方式读取按键状态,适用于按键数量少、实时性要求不高的场景。若需多按键或中断响应,可在此基础上扩展为外部中断或定时扫描方式。