3. 按键控制LED
任务说明
本案例基于中微CMS32系列车规级MCU,实现按键控制LED:按键按下时LED点亮,松开时LED熄灭。核心目标是掌握GPIO输入模式配置、按键状态读取及软件消抖方法。使用开发板上的独立按键(连接至PA0)和LED(连接至PB0),按键按下为低电平有效。
硬件连接
- 按键一端接PA0,另一端接GND(按下时PA0读到低电平)
- LED正极经限流电阻接PB0,负极接GND(PB0输出高电平点亮)
软件设计
GPIO输入配置要点:PA0设置为输入模式并使能内部上拉电阻,保证按键未按下时读到确定的高电平。消抖采用软件延时方式,检测到电平变化后延时10ms再次确认,避免机械抖动导致的误触发。主循环中持续读取按键状态,按下(低电平)时置PB0为高电平点亮LED,松开(高电平)时置PB0为低电平熄灭LED。
代码实现
#include "CMS32L051.h"
// 延时函数(约1ms @ 24MHz主频)
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 6000; j++);
}
}
// GPIO初始化
void GPIO_Init(void) {
// 使能GPIO时钟(PA、PB)
SYSREG->CLK_EN1 |= (1 << 0) | (1 << 1); // 根据实际寄存器位定义
// PA0配置为输入模式,使能内部上拉
GPIOA->DIR &= ~(1 << 0); // 方向:输入
GPIOA->PU |= (1 << 0); // 使能上拉电阻
// PB0配置为输出模式,推挽输出
GPIOB->DIR |= (1 << 0); // 方向:输出
GPIOB->OD &= ~(1 << 0); // 推挽模式
GPIOB->DO &= ~(1 << 0); // 初始输出低电平(LED灭)
}
// 读取按键状态(带消抖)
unsigned char Key_Scan(void) {
unsigned char key_val = 0;
if ((GPIOA->DI & (1 << 0)) == 0) { // 检测到低电平
delay_ms(10); // 延时消抖
if ((GPIOA->DI & (1 << 0)) == 0) { // 再次确认
key_val = 1; // 确认按键按下
}
}
return key_val;
}
int main(void) {
GPIO_Init();
while (1) {
if (Key_Scan()) {
GPIOB->DO |= (1 << 0); // 按键按下,LED点亮
} else {
GPIOB->DO &= ~(1 << 0); // 按键松开,LED熄灭
}
}
}
代码说明
上述代码中,GPIO_Init()完成PA0输入上拉和PB0推挽输出的初始化。Key_Scan()实现带10ms消抖的按键检测,返回1表示确认按下。主循环根据按键状态实时控制LED。寄存器操作基于CMS32L051标准外设库定义,实际使用时需根据具体型号头文件调整时钟使能位。
编译与烧录
- 使用中微官方IDE(如CMS-IDE)创建工程,选择对应MCU型号CMS32L051
- 将上述代码复制到main.c中,添加必要的头文件路径
- 编译工程,生成HEX文件
- 通过CMS-ICE仿真器或ISP方式将HEX烧录至目标板
验证方法
烧录后观察以下现象:
- 初始状态:LED处于熄灭状态
- 按下按键不放:LED应点亮
- 松开按键:LED应立即熄灭
- 快速连续按动:LED状态跟随按键,无闪烁或误触发
判定标准:按键按下与LED点亮严格同步,松开后LED熄灭,且快速操作时无抖动导致的异常闪烁,即表示GPIO输入配置和消抖逻辑正确。
关键要点
- GPIO输入必须配置上拉电阻,确保按键未按下时电平确定
- 消抖延时10ms是经验值,实际可根据按键机械特性调整
- 主循环持续扫描方式适合单按键场景,无需中断资源