搜索
bottom↓
回复: 23

请问傻孩子 按键状态机问题

[复制链接]

出0入0汤圆

发表于 2013-9-17 17:05:23 | 显示全部楼层 |阅读模式
本帖最后由 blueice1108 于 2013-9-17 17:07 编辑

请问傻孩子 按键状态机问题
按键我是参考
http://www.amobbs.com/thread-5484800-1-1.html
功能描述
使用POLLING(20MS)
按下KEY1按键释放后 传送A
按下KEY2按键释放后 传送B
当分开按时没有问题
但当按很快时 有时只会传送一个
或两个都不动作
如何确保按键不会LOSS
扫描频率大概多少
有例子可以参考吗
谢谢

出0入0汤圆

发表于 2013-9-17 17:15:50 | 显示全部楼层
人按按键,一般时间是200ms左右

按的很快的话,可以达到几十ms

你用20ms的时钟,多少次计数作为判定?你可以自己算一下

建议用5ms的polling时钟试试

出0入0汤圆

 楼主| 发表于 2013-9-17 20:39:17 | 显示全部楼层
STM32_Study 发表于 2013-9-17 17:15
人按按键,一般时间是200ms左右

按的很快的话,可以达到几十ms

有改成5MS 好很多
因为想做的功能有点像标定的功能
比方说两个人看LCD  同时(或时间有点落差)按下按钮
把ADC值记录下来 希望不会DELAY太严重
现在前台采状态机实现 后台TIMER计数
状态机内有ADC中断源 也有KEY中断
有推荐的实现架构吗

出0入0汤圆

发表于 2013-9-17 21:34:07 | 显示全部楼层
你用了状态机,那还有什么延时呢?

常规的人机交互功能,按键的获取,不用中断都可以的

直接在大循环里面polling即可

整个按键状态机,只需要系统SysTick作为时间计数即可。

不管是ADC还是矩阵还是独立IO的按键来源,对于状态机本身而言,没有区别的

建议将这个层次区分开来,对于状态机,按键的输入检测(ADC或中断或GPIO)采用一个独立的函数抽象出来

按键事件的处理,也要分离开来,状态机只是输出有效的按键值,具体的处理,在其他地方做(也许又是一个状态机)

出0入0汤圆

发表于 2013-9-17 22:33:01 | 显示全部楼层
http://www.amobbs.com/thread-5542774-1-1.html
为什么不参考这个帖子呢?

出0入0汤圆

 楼主| 发表于 2013-9-17 22:42:25 | 显示全部楼层
STM32_Study 发表于 2013-9-17 21:34
你用了状态机,那还有什么延时呢?

常规的人机交互功能,按键的获取,不用中断都可以的

感谢分享
现在用的架构
WHILE
{
Statemachine();
}

每个STATE大概长得像
If(KEY. Interrupt==1)
{
处理KEY
}
If(ADC.Interrupt==1)
{
……………..
……………..
ADC.Interrupt==0;
}
如果ADC和KEY同时中断
标记的地方是否会有延迟?
ADC中断频率大概200HZ

出0入0汤圆

 楼主| 发表于 2013-9-17 22:43:26 | 显示全部楼层
yiming988 发表于 2013-9-17 22:33
http://www.amobbs.com/thread-5542774-1-1.html
为什么不参考这个帖子呢?

对QUEUE不太熟
会找时间看一下

出0入0汤圆

发表于 2013-9-17 23:03:26 | 显示全部楼层
blueice1108 发表于 2013-9-17 22:42
感谢分享
现在用的架构
WHILE

你这个思路有点错误了。

不管是什么按键类型,ADC或中断或GPIO扫描,对于按键的定义是没有区别的,所以你输入到按键状态机的按键扫描,要统一化,不用去区分是什么类型的按键,只需要每个按键都有一个独立的定义即可。

另外,在人机交互的层面上来说,先处理ADC或先处理中断或GPIO扫描,一般都没有什么关系,实际使用是感受不到区别的。如果有某些情况,一定需要有优先级,那在代码上区分一下即可。

出0入0汤圆

发表于 2013-9-17 23:05:28 | 显示全部楼层
正确的状态机应该是这样的结构:

void KeyTask(void)
{
     uint8_t keyValue;
      KeyValue = GetKeyValue();

      switch(KeyState)
     {
              case  KEY_IDLE:
              break;

              case ……
     }
}

出0入0汤圆

发表于 2013-9-17 23:07:08 | 显示全部楼层
实际使用上,每个人的思路都有所不同,划分状态的方法也不一样,包括状态机的具体实现,有些人喜欢用Switch,有些人喜欢用If,有些人喜欢用函数指针,其实归根结底的思路是一样的

就是 逻辑抽象  和  分时处理

出0入296汤圆

发表于 2013-9-18 10:46:27 | 显示全部楼层
blueice1108 发表于 2013-9-17 22:43
对QUEUE不太熟
会找时间看一下

能解决你问题的就是这个帖子,或者你看马老师的帖子。队列又不用你自己写,你只要关注队列的逻辑接口就行了——就是入队出队。
http://www.amobbs.com/thread-5542774-1-1.html

出0入0汤圆

 楼主| 发表于 2013-9-18 12:23:35 | 显示全部楼层
Gorgon_Meducer 发表于 2013-9-18 10:46
能解决你问题的就是这个帖子,或者你看马老师的帖子。队列又不用你自己写,你只要关注队列的逻辑接口就行 ...

会先看帖子的这个部分 有问题再请教
谢谢

出0入0汤圆

 楼主| 发表于 2013-9-18 12:27:02 | 显示全部楼层
STM32_Study 发表于 2013-9-17 23:03
你这个思路有点错误了。

不管是什么按键类型,ADC或中断或GPIO扫描,对于按键的定义是没有区别的,所以 ...

谢谢
可能我上面只有片段 难以表达太多
我想先把上面推荐按键的帖子看一下
再从新设计状态机架构

出0入0汤圆

 楼主| 发表于 2013-9-18 16:26:36 | 显示全部楼层
本帖最后由 blueice1108 于 2013-9-18 19:21 编辑
blueice1108 发表于 2013-9-18 12:23
会先看帖子的这个部分 有问题再请教
谢谢


看了下帖子
看宏看得我好晕.....

出0入296汤圆

发表于 2013-9-19 10:57:52 | 显示全部楼层
blueice1108 发表于 2013-9-18 16:26
看了下帖子
看宏看得我好晕.....

看宏的时候要忍住,不要看宏的实现,先专注于宏的意思。等你看懂了代码,回头有空了再看具体宏的实现。
宏的作用就是把一些复杂的东西简化,但如果你总是忍不住要去看宏原本想替你掩盖的内容,你就晕了。

出0入0汤圆

 楼主| 发表于 2013-9-23 13:33:55 | 显示全部楼层
简述一下我的功能
比方说两个人看LCD  同时(或时间有点落差 但可能很接近)按下按钮
把LCD上的 ADC值记录下来 希望不会DELAY太严重
我使用了帖子上的
http://www.amobbs.com/thread-5542774-1-1.html
比方说几乎同时按下
放开
只会执行KEY1或KEY2的功能
或都不执行
如何确保按键值不LOSS(还是此架构需要中断 目前使用轮循)
有何适合的裸机架构可参考?
我目前使用的裸机架构
http://www.amobbs.com/forum.php? ... ble&tid=3757688

出0入296汤圆

发表于 2013-9-25 14:43:00 | 显示全部楼层
blueice1108 发表于 2013-9-23 13:33
简述一下我的功能
比方说两个人看LCD  同时(或时间有点落差 但可能很接近)按下按钮
把LCD上的 ADC值记录下 ...

你的问题在于如何编码KEY1和KEY2同时按下的情况。
一般来说,如果你想正确处理KEY1和KEY2同时按下,要用KeyMap技术,而不是帖子中的序列化的按键技术。
序列化的按键技术假设同一时刻不会存在两个键同时按下的情况——CTRL,ALT这种除外——这种是通过专门
的编码来实现的,比如你原本有一个键值0x01对应KEY1,那么当KEY1和CTRL同时按下的时候,你返回的就是
0x81——比如说用最高位来表示CTRL按下了。

在某些场合,的确需要判断两个或两个以上的按键是否同时按下,这种按键处理技术叫做KeyMap技术。这种
技术要求扫描函数有能力返回按键的通码和断码——而不是序列化按键技术简单返回的按键值和KEY_NULL。
通过通码和断码,按键服务程序会在内部维护一个BIT MAP——每一个BIT对应一个KEY——这就能简单的解决
判断多个按键式是否同时按下的情况了。

当然,KeyMap也有他的弱点——首先,扫描函数较为复杂,要求能返回按键的通码和断码,也就是说扫描
函数自己能追踪物理按键的状态边沿——甚至还需要做必要的去抖——这就极大地增加了扫描函数的复杂度;
其次,由于KeyMap同时追踪多个KEY的状态,因此同时提供多个按键的“长按键Long Press”“重复按键Repeat”
甚至是“双击Double Click”就很有困难——因为要为每一个按键都分配对应的资源来更新它的状态。

因此,通常情况下,只要应用并不是特别需要多于两个以上按键同时按下,都可以采用序列化的按键技术——
对于特殊的存在同时按下的情况予以专门的编码即可。

出0入0汤圆

发表于 2013-9-25 15:15:11 | 显示全部楼层
我现在比较佩服电脑键盘的程序~!

出0入0汤圆

 楼主| 发表于 2013-9-26 14:21:43 | 显示全部楼层
Gorgon_Meducer 发表于 2013-9-25 14:43
你的问题在于如何编码KEY1和KEY2同时按下的情况。
一般来说,如果你想正确处理KEY1和KEY2同时按下,要用K ...

傻孩子 真够强阿
不知道有没有KEY MAP的范例
或是谷歌关键词下什么可以找到相关资料

出0入296汤圆

发表于 2013-9-26 17:19:51 | 显示全部楼层
catwill 发表于 2013-9-25 15:15
我现在比较佩服电脑键盘的程序~!

电脑键盘只不过作了一个硬件的支持通码断码输出的扫描接口……
你如果专门做硬件来追踪每一个按键的状态,说实话……一点也不难……

出0入296汤圆

发表于 2013-9-26 17:25:26 | 显示全部楼层
blueice1108 发表于 2013-9-26 14:21
傻孩子 真够强阿
不知道有没有KEY MAP的范例
或是谷歌关键词下什么可以找到相关资料

说句让我觉得惭愧的话……
这种东西是国外大约80年代的技术……现在已经实在没有什么好讨论的……估计你搜索论文也找不到什么……
而且KEY MAP根本就是一个工程名称,在计算机领域,随便起名字是太常见的东西了……同样的技术,不同
人有不同名字非常正常……举例来说Jave Bean……为啥是Bean,完全就是开发人员随便起的……但背后的技术
往往和Bean没有半毛钱关系。

KEY MAP这个名字是我根据技术的特点起的,起源于类似BitMap, MessageMap这一类的命名规则……你搜索
Key Map不一定有什么收获的。

本质上来说Key Map技术就是针对每一个物理按键,在做必要的去抖以后,在一个专门的内存区域内管理一个
对应的BIT,简单说就是如果物理按键按下了,那么这个BIT就会被扫描函数自动置位,反之则清零。
你可以很简单的实现 比如3~4个按键的BITMAP,再多就是苦力活了。

出0入0汤圆

发表于 2013-9-26 21:17:56 来自手机 | 显示全部楼层
Gorgon_Meducer 发表于 2013-9-26 17:19
电脑键盘只不过作了一个硬件的支持通码断码输出的扫描接口……
你如果专门做硬件来追踪每一个按键的状态 ...

就是说键盘里面不是单片机程序?而是专门的处理按键的硬件?

出0入0汤圆

 楼主| 发表于 2013-9-27 09:04:49 | 显示全部楼层
Gorgon_Meducer 发表于 2013-9-26 17:25
说句让我觉得惭愧的话……
这种东西是国外大约80年代的技术……现在已经实在没有什么好讨论的……估计你 ...

不用惭愧阿
国外技术本来就领先很多了
而且技术强度是相对的
看来这问题只好自己搞了

出0入296汤圆

发表于 2013-9-27 11:21:00 | 显示全部楼层
catwill 发表于 2013-9-26 21:17
就是说键盘里面不是单片机程序?而是专门的处理按键的硬件?

也许早期或者某些高档的键盘里面是MCU,但对于大部分廉价的键盘来说,用ASIC才是降低成本的王道。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-3 04:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表