2. GPIO输入检测与按键消抖
任务定义
本案例在TI C2000系列MCU(以TMS320F280049C为例)上实现GPIO输入检测与按键消抖功能。目标为:配置一个GPIO引脚作为按键输入,通过软件延时消抖方式识别一次有效按键动作,并翻转一个LED输出引脚的状态。每次有效按键按下,LED状态翻转一次;按键抖动或长按不产生重复触发。
硬件连接
- 按键接GPIO24(对应开发板上的S2按键),按下为低电平,默认上拉输入。
- LED接GPIO23(对应开发板上的LED4),输出高电平点亮。
实现原理
按键消抖采用经典的“检测-延时-再确认”方法:首次检测到按键电平变化后,延时20ms跳过抖动期,再次读取电平状态;若与延时前状态一致,则确认电平变化有效。对于按下动作,仅在检测到电平由高变低且确认有效时,翻转LED状态。松开过程同样经过消抖处理,但不触发LED翻转,从而避免一次按下过程中因抖动产生多次触发。
代码实现
// file: gpio_key_led.c
// 目标平台:TMS320F280049C + TI C2000Ware
// 功能:GPIO按键输入消抖,翻转LED
#include "F28004x_Device.h"
#include "F28004x_Examples.h"
#define KEY_PIN 24 // 按键输入引脚
#define LED_PIN 23 // LED输出引脚
#define DEBOUNCE_MS 20 // 消抖延时(ms)
volatile uint32_t key_state; // 当前确认的按键电平(1:高, 0:低)
volatile uint32_t led_status; // LED状态(1:亮, 0:灭)
// 简单阻塞延时函数,系统时钟90MHz
void delay_ms(uint32_t ms)
{
uint32_t i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 9000; j++);
}
void init_gpio(void)
{
// 配置LED引脚为GPIO输出
GPIO_SetupPinMux(LED_PIN, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LED_PIN, GPIO_OUTPUT, GPIO_PUSH_PULL);
// 配置按键引脚为GPIO输入,使能内部上拉
GPIO_SetupPinMux(KEY_PIN, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(KEY_PIN, GPIO_INPUT, GPIO_PULL_UP);
// 初始状态:LED灭,按键电平读取为高
led_status = 0;
GPIO_WritePin(LED_PIN, led_status);
key_state = GPIO_ReadPin(KEY_PIN);
}
void main(void)
{
// 初始化设备与GPIO
InitSysCtrl();
InitGpio();
init_gpio();
// 关闭中断(本案例不使用中断)
DINT;
while(1)
{
uint32_t raw_level = GPIO_ReadPin(KEY_PIN);
// 检测到电平变化,进入消抖确认
if(raw_level != key_state)
{
delay_ms(DEBOUNCE_MS); // 等待抖动结束
uint32_t confirm_level = GPIO_ReadPin(KEY_PIN);
// 延时后电平与变化方向一致,确认有效
if(confirm_level == raw_level)
{
// 仅在按下沿(高→低)时翻转LED
if(key_state == 1 && confirm_level == 0)
{
led_status ^= 1; // 翻转LED状态
GPIO_WritePin(LED_PIN, led_status);
}
key_state = confirm_level; // 更新确认状态
}
// 若不一致,说明是抖动,不更新key_state
}
}
}
工程配置与编译
- 在CCS中新建工程,芯片选择TMS320F280049C。
- 添加本案例的
gpio_key_led.c文件,并包含C2000Ware驱动库路径。 - 链接
F28004x_Device.h与F28004x_Examples.h对应的头文件目录。 - 编译工程,生成
.out文件。
运行与验证
将编译生成的.out文件通过CCS的Debug功能烧录至开发板并运行。验证步骤如下:
- 观察开发板LED4(GPIO23)初始为熄灭状态。
- 快速按下并松开按键S2(GPIO24),LED4应变为点亮状态。
- 再次快速按下并松开按键,LED4应熄灭。
- 快速连续按动按键(模拟抖动),LED状态应只翻转一次,不会出现多次翻转。
- 长按按键不松开,LED状态只翻转一次,不会重复触发。
判定标准:每次按下并松开按键,LED状态恰好翻转一次;快速抖动或长按不会导致LED状态多次翻转,即消抖逻辑正确。
关键点说明
- 延时消抖时间20ms可根据实际按键机械特性调整,范围通常为10~50ms。
- 本案例采用轮询方式,不占用中断资源,适合教学演示;实际产品中可改用定时器中断实现非阻塞消抖。
- GPIO_SetupPinOptions中GPIO_PULL_UP使能内部上拉,确保按键未按下时引脚为确定高电平。