X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
GD32 MCU
[经验分享] 【GD32E231_DIY】-03:按键识别框架
sf116
2019-5-13 17:56
楼主
没有比定时轮询+状态机扫描按键更好的方式。此框架支持短按、短按抬起、长按、长按抬起识别。当然稍作修改还可以添加双击、连击等等各种按键状态识别。
对MCU需求:
1、定时任务:10ms轮询一次。
2、读KEY状态。
大部分MCU都可以采用。
按键扫描部分:
#define KEY_STATE_0 0
#define KEY_STATE_1 1
#define KEY_STATE_2 2
#define KEY_STATE_3 3
#define KEY_STATE_4 4
#define KEY_VALUE_IDLE 0xFE
#define KEY_ENTER 0x20
#define N_KEY KEY_VALUE_IDLE
#define S_KEY_DOWN 1//短按
#define S_KEY_UP 2//短按抬起
#define D_KEY 3//
#define L_KEY_DOWN 4//长按
#define L_KEY_UP 5//长按抬起
U8 KeyRead(void)
{
static U8 ucKeyState = KEY_STATE_0;
static U8 ucKeyTime = 0;
U8 ucKeyPress;
U8 ucKeyValue = N_KEY;
if(SET == gpio_input_bit_get(GPIOA, GPIO_PIN_0))
{
ucKeyPress = 0;//Key Down
}
else
{
ucKeyPress = 1;
}
switch (ucKeyState)
{
case KEY_STATE_0:
if (!ucKeyPress)
{
ucKeyState = KEY_STATE_1;
}
break;
case KEY_STATE_1:
if (!ucKeyPress)
{
ucKeyTime = 0;
ucKeyState = KEY_STATE_2;
}
else
{
ucKeyState = KEY_STATE_0;
}
break;
case KEY_STATE_2:
if(ucKeyPress)
{
ucKeyState = KEY_STATE_0;
}
else
{
ucKeyTime++;
if(ucKeyTime == 1)//10ms消抖
{
ucKeyValue = S_KEY_DOWN|KEY_ENTER;
ucKeyState = KEY_STATE_3;
}
}
break;
case KEY_STATE_3:
if (ucKeyPress)
{
ucKeyValue = S_KEY_UP|KEY_ENTER;
ucKeyState = KEY_STATE_0;
}
else
{
ucKeyTime++;
if(ucKeyTime >= 100)//长按1s
{
ucKeyValue = L_KEY_DOWN|KEY_ENTER;
ucKeyState = KEY_STATE_4;
}
}
break;
case KEY_STATE_4:
if (ucKeyPress)
{
ucKeyValue = L_KEY_UP|KEY_ENTER;
ucKeyState = KEY_STATE_0;
}
}
return ucKeyValue;
}
按键扫描调用:
void Task_10ms(void)
{
U8 ucKeyValue = N_KEY;
ucKeyValue = KeyRead();
if(ucKeyValue == (S_KEY_DOWN|KEY_ENTER))
{
printf("\r\n S_KEY_DOWN ");
}
else if(ucKeyValue == (S_KEY_UP|KEY_ENTER))
{
printf("\r\n S_KEY_UP ");
}
else if(ucKeyValue == (L_KEY_DOWN|KEY_ENTER))
{
printf("\r\n L_KEY_DOWN ");
}
else if(ucKeyValue == (L_KEY_UP|KEY_ENTER))
{
printf("\r\n L_KEY_UP ");
}
}
点赞
回复评论 (2)
沙发
sf116
代码格式上传后有点乱啊,怎么回事
点赞
2019-5-13 18:00
板凳
xld0932
We are a team and we work as a team !
点赞
2019-5-14 10:58
最新活动
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
安世半导体理想二极管与负载开关,保障物联网应用的稳健高效运行
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
PI 电源小课堂|无 DC-DC 变换实现多路高精度输出反激电源
2024 瑞萨电子MCU/MPU工业技术研讨会——深圳、上海站, 火热报名中
随便看看
用PIC单片机实现的IC卡读写器
求M16与光强传感器TSL2561,怎么去设置读写地址
altera Cyclone IV fpga时钟参数
PC机USB驱动求解?
旧物改造+蓝牙收款音箱变无线门铃
TJA1020 LIN 收发器手册
关于各种帖子
分享:国产电源IC替代国外
【一起玩esp8266】板子到货啦
学习单片机看哪一本书好?51单片机教程书籍推荐
关于NRF24L01
lm324能否做到0.05hz的二阶高通滤波器
好消息!Simple Switcher 家族又添新丁!——全新LMZ3闪亮登场!
大神们有CC2541蓝牙模块原理图设计资料吗?
双网卡热备份(双网卡冗余备份)如何设计与实现呢?
求助贴
有关AD的问题
Keystone2芯片内存分配问题???
怎么用jlink给三星的S3C44b下载uboot
遍访高人,江湖救急。==||====〉Wince驱动开发的几个问题
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复