首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用状态机实现键盘去抖

用状态机实现键盘去抖

用状态机做键盘消抖,很好用,不必延时等待键盘稳定,当检测到有键按下或弹起时能发出相应的键盘消息,设置状态机有4种状态,A0,A1,A2,A3 状态转换图如下:
此主题相关图片如下:state.jpg


      初始时处于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
        }
    }
}

转自 综合技术—单片机
返回列表