什么叫状态机:按键消抖实例

luyaoda0 2020-02-17

  • 原创  https://jingyan.baidu.com/article/14bd256e112e25bb6d261211.html
貌似没有教程讲到过状态机的概念和编程思路,特从别的论坛转贴一篇很好的实例,献给广大初学者。用状态机做键盘消抖,很好用,不必延时等待键盘稳定,当检测到有键按下或弹起时能发出相应的键盘消息
步骤/方法
 
  1. 1
    设置状态机有4种状态,A0,A1,A2,A3 
    初始时处于A0状态,当扫描发现有键按下时,转入到A1状态。 
    当处于A1状态时,当扫描发现有键按下并且键值等于A1状态下的键值时,转入到A2状态,否则转入A0状态。 
    当处于A2状态时,当扫描发现有键按下并且键值等于A2状态下的键值时,转入到A3状态,同时发出键按下消息或将按下键的键值入队,否则转入A0状态。 
    当处于A3状态时,当扫描发现无键按下时,转入到A0状态。同时发出键弹起消息或弹起键的键值入队。 
    函数JianSaoMiao()用于键扫描的到即时键值 
    函数JianChuLi()用于按键处理,可放在时钟中断中调用 
    例:在10ms中断中扫描并处理按键只需调用:JianChuLi(JianSaoMiao()); 
    可使调用后完成发出键按下或键弹起的消息,或者将键值送入键值队列供后续处理
  2. 2
    #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 


    }
     

相关推荐

tuniumobile / 0评论 2018-12-26
陶赫Qt开发学习 / 0评论 2018-12-26