打印
[疑难问答]

如何消抖

[复制链接]
1203|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
粉色壁纸|  楼主 | 2011-11-12 23:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
貌似没有教程讲到过状态机的概念和编程思路,特从别的论坛转贴一篇很好的实例,献给广大初学者。用状态机做键盘消抖,很好用,不必延时等待键盘稳定,当检测到有键按下或弹起时能发出相应的键盘消息,英文不好,只好用拼音做变量名和函数名,将就看吧 ;-)

设置状态机有4种状态,A0,A1,A2,A3
初始时处于A0状态,当扫描发现有键按下时,转入到A1状态。
当处于A1状态时,当扫描发现有键按下并且键值等于A1状态下的键值时,转入到A2状态,否则转入A0状态。
当处于A2状态时,当扫描发现有键按下并且键值等于A2状态下的键值时,转入到A3状态,同时发出键按下消息或将按下键的键值入队,否则转入A0状态。
当处于A3状态时,当扫描发现无键按下时,转入到A0状态。同时发出键弹起消息或弹起键的键值入队。
函数JianSaoMiao()用于键扫描的到即时键值
函数JianChuLi()用于按键处理,可放在时钟中断中调用
例:在10ms中断中扫描并处理按键只需调用:JianChuLi(JianSaoMiao());
可使调用后完成发出键按下或键弹起的消息,或者将键值送入键值队列供后续处理

  • #define Kong 0x00 //定义无键按下时,键扫描返回的值
  • #define A0 0
  • #define A1 1
  • #define A2 2
  • #define A3 3

  • struct  
  • {
  • unsigned char JianZhi;          //当前键值     
  • unsigned char DangQianZhuangTai;//当前状态
  • } ZTJ;

  • void ZTJ_ChuShiHua(void)         //状态机初始化
  •     {
  •         ZTJ.DangQianZhuangTai=A0; //初始状态A0
  •        ZTJ.JianZhi=Kong;          //键值为Kong
  •     }
  • uchar JianSaoMiao(void) //键值扫描
  • {
  •    uchar JianZhi;
  •    //在此根据实际电路插入键值扫描程序段,键值存放到JianZhi
  •    ......
  •    return(JianZhi);
  • }
  • void JianChuLi(uchar JZ)
  • {
  •    switch(ZTJ.DangQianZhuangTai)  
  •      {
  •         case A0:  
  •           {
  •               if(JZ!=Kong)
  •                {
  •                     ZTJ.DangQianZhuangTai=A1; //有键按下,状态转移
  •                     ZTJ.JianZhi=JZ;       //保存当前键值
  •                 }
  •          } break;
  •         case A1:  
  •            {
  •               if(JZ==ZTJ.JianZhi)
  •                  ZTJ.DangQianZhuangTai=A2; //有键按下,且键值稳定状态转移
  •              else  
  •                     ZTJ_ChuShiHua(); //键值不稳,回到初始状态A0
  •            } break;
  •         case A2:  
  •           {
  •               if(JZ==ZTJ.JianZhi)
  •                 {
  •                     ZTJ.DangQianZhuangTai=A3; //有键按下,且键值稳定状态转移
  •                     //在此发出键按下消息,或将键按下键值入键值队列供后续处理
  •                     ......
  •                 }
  •             else  
  •                     ZTJ_ChuShiHua(); //键值不稳,回到初始状态A0
  •          } break;
  •         case A3:  
  •          {
  •               if(JZ==Kong)
  •                   {
  •                          ZTJ_ChuShiHua();   //键已弹起,回到初始状态A0
  •                             //在此发出键弹起消息,或将键弹起键值入键值队列供后续处理
  •                            ......
  •                     }
  •         } break;
  •    default :
  •         {
  •            ZTJ_ChuShiHua();   //初始状态A0
  •        }
  • }
  • }


沙发
高亮登录| | 2011-11-13 09:39 | 只看该作者
这种消抖的思路不措!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

121

帖子

1

粉丝