微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 初学者适合,什么叫状态机:按键消抖实例

初学者适合,什么叫状态机:按键消抖实例

时间:10-02 整理:3721RD 点击:
貌似没有教程讲到过状态机的概念和编程思路,特从别的论坛转贴一篇很好的实例,献给广大初学者。用状态机做键盘消抖,很好用,不必延时等待键盘稳定,当检测到有键按下或弹起时能发出相应的键盘消息,英文不好,只好用拼音做变量名和函数名,将就看吧 ;-)
设置状态机有4种状态,A0,A1,A2,A3
初始时处于A0状态,当扫描发现有键按下时,转入到A1状态。
当处于A1状态时,当扫描发现有键按下并且键值等于A1状态下的键值时,转入到A2状态,否则转入A0状态。
当处于A2状态时,当扫描发现有键按下并且键值等于A2状态下的键值时,转入到A3状态,同时发出键按下消息或将按下键的键值入队,否则转入A0状态。
当处于A3状态时,当扫描发现无键按下时,转入到A0状态。同时发出键弹起消息或弹起键的键值入队。
函数JianSaoMiao()用于键扫描的到即时键值
函数JianChuLi()用于按键处理,可放在时钟中断中调用
例:在10ms中断中扫描并处理按键只需调用:JianChuLi(JianSaoMiao());
可使调用后完成发出键按下或键弹起的消息,或者将键值送入键值队列供后续处理

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

  6. struct  
  7. {
  8. unsigned char JianZhi;          //当前键值     
  9. unsigned char DangQianZhuangTai;//当前状态
  10. } ZTJ;

  11. void ZTJ_ChuShiHua(void)         //状态机初始化
  12.     {
  13.         ZTJ.DangQianZhuangTai=A0; //初始状态A0
  14.        ZTJ.JianZhi=Kong;          //键值为Kong
  15.     }
  16. uchar JianSaoMiao(void) //键值扫描
  17. {
  18.    uchar JianZhi;
  19.    //在此根据实际电路插入键值扫描程序段,键值存放到JianZhi
  20.    ......
  21.    return(JianZhi);
  22. }
  23. void JianChuLi(uchar JZ)
  24. {
  25.    switch(ZTJ.DangQianZhuangTai)  
  26.      {
  27.         case A0:  
  28.           {
  29.               if(JZ!=Kong)
  30.                {
  31.                     ZTJ.DangQianZhuangTai=A1; //有键按下,状态转移
  32.                     ZTJ.JianZhi=JZ;       //保存当前键值
  33.                 }
  34.          } break;
  35.         case A1:  
  36.            {
  37.               if(JZ==ZTJ.JianZhi)
  38.                  ZTJ.DangQianZhuangTai=A2; //有键按下,且键值稳定状态转移
  39.              else  
  40.                     ZTJ_ChuShiHua(); //键值不稳,回到初始状态A0
  41.            } break;
  42.         case A2:  
  43.           {
  44.               if(JZ==ZTJ.JianZhi)
  45.                 {
  46.                     ZTJ.DangQianZhuangTai=A3; //有键按下,且键值稳定状态转移
  47.                     //在此发出键按下消息,或将键按下键值入键值队列供后续处理
  48.                     ......
  49.                 }
  50.             else  
  51.                     ZTJ_ChuShiHua(); //键值不稳,回到初始状态A0
  52.          } break;
  53.         case A3:  
  54.          {
  55.               if(JZ==Kong)
  56.                   {
  57.                          ZTJ_ChuShiHua();   //键已弹起,回到初始状态A0
  58.                             //在此发出键弹起消息,或将键弹起键值入键值队列供后续处理
  59.                            ......
  60.                     }
  61.         } break;
  62.    default :
  63.         {
  64.            ZTJ_ChuShiHua();   //初始状态A0
  65.        }
  66. }
  67. }

复制代码



挺合适的,学习了。

学习了

学习了

我是初学者,谢谢了!

状态机实现按键扫描的思路很不错

学习学习

学习学习

学习
学习

必须学这样写!慎用延时!不要让处理器处在等待状态!

跟传统的行列扫描法不太一样,值得学习!

学习了

学习了

好吧~~好好学习,之前没接触过

嗯,嗯~~~很有道理嘛~~~

   学习了,顶一个

学习!

学习了~~~

在哪里嫩

马克

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top