注册
登录
电子工程世界-论坛
返回首页
EEWORLD首页
频道
EE大学堂
下载中心
Datasheet
专题
单片机
物联网
汽车电子
嵌入式
手机/便携
模拟电子
家用电子
网络通信
电源管理
工业控制
测试测量
半导体设计/制造
安防电子
传感器
医疗电子
sf116的个人空间
https://home.eeworld.com.cn/space-uid-475983.html
[收藏]
[复制]
[分享]
[RSS]
空间首页
动态
记录
日志
相册
主题
分享
留言板
个人资料
借用开发板
论坛
淘帖
Collection
查看新帖
最新回复
社区活动
联系管理员
我的空间
帖子
日志
收藏
好友
勋章
积分
安全验证
请完成以下验证码
日志
【GE32E231_DIY】-03:按键识别框架
已有 171 次阅读
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)
{
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)
{
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 ");
}
}
复制代码
本文来自论坛,点击查看完整帖子内容。
收藏
邀请
举报
评论 (
0
个评论)
涂鸦板
您需要登录后才可以评论
登录
|
注册
评论
sf116
加为好友
给我留言
打个招呼
发送消息
热门文章
头条资讯
科普三分钟:USB Type-C到底是什么?
把薪助火!恩智浦助力浦东打造现代化建设引领区
“Smarter&Together”,Marvell“站台”BroadLink&京东发布会
三星教父李健熙去世!被与乔布斯相提并论,把一个韩国山寨家电厂打造为全球电子巨头
首例基因编辑干细胞治疗艾滋病:北大邓宏魁参与,达到最佳治疗效果
7年合约:Global Foundries将为美国生产间谍卫星和导弹芯片
新增数据手册
MS27471Y-21E-16SD
7103J3W5BE31
ABL-70.0000MHZ-10-K4-L2-TRAY
MMA0204-150.1%VG03BL147
AR06CBCV8R20N
RP73D2H52R3ATG
热搜器件
RLZ5.6A
RSC144D1100
MSMCJLCE15AE3/TR
0603Y1000470GAT
VS-12TQ040-M3
IXDF604
推荐下载
继电保护—论述题
电力远程抄表系统的设计与实现
物理隔离网闸的设计与实现
直流开关电源基本原理.pdf
TI_仿真入门
ATMEL AVR 单片机 ni-mh 电池充电控制原代码
推荐关注
数字隔离器如何解决智能电表中的电气隔离需求?
Jetson 利用 Ollama + Anything LLM 部署 Deepseek、LLama3
高集成度无电感离线式线性稳压器,小家电电源新选择!
锂电池充电管理电路方案可定制化
Profinet 通讯网关:解锁 Modbus TCP从站变身主站的密码
BEV感知技术:多相机数据采集与高精度时间同步方案