搜索
bottom↓
回复: 109

送给像我这样的初学者,什么叫状态机:按键消抖实例。

[复制链接]

出0入0汤圆

发表于 2011-1-27 21:11:19 | 显示全部楼层 |阅读模式
看了二三十本教程书,从来没有一本讲到过状态机的概念和编程思路,特从别的论坛转贴一篇很好的实例,献给广大初学者。

用状态机做键盘消抖,很好用,不必延时等待键盘稳定,当检测到有键按下或弹起时能发出相应的键盘消息,英文不好,只好用拼音做变量名和函数名,将就看吧 ;-)

设置状态机有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
       }
}
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-1-27 21:48:01 | 显示全部楼层
马克思主义

出0入0汤圆

发表于 2011-1-27 22:14:06 | 显示全部楼层
mark

出0入12汤圆

发表于 2011-1-27 23:40:34 | 显示全部楼层
状态机就看马潮老师的就可以了,经典教程

出0入0汤圆

发表于 2011-1-28 00:02:24 | 显示全部楼层
MARK

出0入0汤圆

 楼主| 发表于 2011-1-28 00:39:42 | 显示全部楼层
回复【3楼】skynet 青青草原
状态机就看马潮老师的就可以了,经典教程
-----------------------------------------------------------------------

马潮老师是哪本教程,还望指点

出0入0汤圆

发表于 2011-1-28 07:31:09 | 显示全部楼层
you can make it a lot simpler:

1) originally at state 0, reset key0;
2) if key pressed when in state 0, go to state 1;
3) if key pressed when in state 0, increment key_count; otherwise, go to state 0;
4) if key_count > a pre-determined number, return the key;

出0入9汤圆

发表于 2011-1-28 08:03:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-28 09:18:04 | 显示全部楼层
remind

出0入0汤圆

发表于 2011-1-28 10:33:40 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-1-28 11:57:00 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-1-28 12:49:04 | 显示全部楼层
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;
2) if key pressed when in state 0, go to state 1;
3) if key pressed when in state 0, increment key_count; otherwise, go to state 0;
4) if key_count > a pre-determined number, return the key;

-----------------------------------------------------------------------

大多数人的E文不好,如果6楼写的是C++、VB、VC那也就算了,否则就有卖弄自己的英文水平多么NB多么高超之嫌!谢谢

出0入0汤圆

发表于 2011-1-28 13:37:38 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-1-29 01:20:44 | 显示全部楼层
额,看一下。

出0入0汤圆

发表于 2011-1-29 09:49:38 | 显示全部楼层
如果E文不好,用google翻译一下6楼的,还是值得的。

出0入0汤圆

发表于 2011-1-29 10:40:16 | 显示全部楼层
马克。

出0入0汤圆

发表于 2011-1-29 10:58:50 | 显示全部楼层
回复【11楼】pxlpxlpxl
-----------------------------------------------------------------------

用软件翻译了   呵呵


你可以把它简单了很多:
  1)原本在状态0,复位的KEY0;
  2)如果在状态0时按下,进入状态1的关键; **%%* *
    3)如果在状态0时按下,增量key_count关键,否则,请转到状态0;
  4)如果key_count>预先确定的号码,返回的关键;

出0入0汤圆

发表于 2011-1-29 13:46:42 | 显示全部楼层
不错 学习中

出0入0汤圆

发表于 2011-1-31 22:08:33 | 显示全部楼层
其实很多公司的电脑是没有中文输入法的,LS要理解呀

出0入0汤圆

发表于 2011-2-1 16:49:54 | 显示全部楼层
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;
2) if key pressed when in state 0, go to state 1;
3) if key pressed when in state 0, increment key_count; otherwise, go to state 0;
4) if key_count > a pre-determined number, return the key;

-----------------------------------------------------------------------

如果你是中国人讲中国话,如果你是外国人请也讲中文,因为你能看懂,

不要到处发英文,英文那么牛B直接做翻译去得了

出0入0汤圆

发表于 2011-2-4 10:38:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-4 12:16:22 | 显示全部楼层
根据硬件的中区别:快速硬件没必要消抖
                  低速的消抖的时间间隔也不一
状态机消抖的方法:每个状态的时间间隔难以控制,不适合初学者!

出0入0汤圆

发表于 2011-2-8 19:34:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-9 09:40:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-20 13:16:57 | 显示全部楼层
回复【6楼】millwood0
-----------------------------------------------------------------------

米木兄,貌似键值计数加一是在状态A2做的吧??

出0入0汤圆

发表于 2011-2-20 14:48:20 | 显示全部楼层
MARK

出75入4汤圆

发表于 2011-2-20 15:32:34 | 显示全部楼层
millwood0 是外国人,看中文也很累,回帖解答问题应该谢谢millwood0才对。
几位看点简单的英文就不要抱怨了

出0入0汤圆

发表于 2011-3-24 00:39:29 | 显示全部楼层
新手的福音!

出0入0汤圆

发表于 2011-4-22 18:54:53 | 显示全部楼层
m

出0入0汤圆

发表于 2011-4-22 20:28:42 | 显示全部楼层
millwood0是一个简单的开关机的状态机的例子
短按开机,长按关机的例子

出0入0汤圆

发表于 2011-4-22 21:30:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-29 21:49:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-29 22:03:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-30 08:34:21 | 显示全部楼层
有一种 记号叫 爪子

出0入0汤圆

发表于 2011-5-30 08:45:44 | 显示全部楼层
这么一点点。。。

出0入0汤圆

发表于 2011-5-30 13:06:24 | 显示全部楼层
millwood0 是外国人,看中文也很累,回帖解答问题应该谢谢millwood0才对。
回复【6楼】millwood0
-----------------------------------------------------------------------
允许我卖弄一下,
I am a freshman,everything is at the beginning.
I am looking fotward to learning more about MCU.
your words are impressive!
Do you have email or something?
my email:81285560@qq.com,thanks for adding me!

出0入0汤圆

发表于 2011-5-30 13:09:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-30 16:09:36 | 显示全部楼层
我是来看英文的

出0入0汤圆

发表于 2011-6-6 07:17:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-6 09:17:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-6 10:27:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-6 11:17:00 | 显示全部楼层
millwood0 :
我就觉得millwood0 是这个论坛难得的牛人,值得我佩服,尊敬!

出0入0汤圆

发表于 2011-6-6 13:37:12 | 显示全部楼层
好资料,谢谢,烟酒烟酒!嘿嘿!

出0入0汤圆

发表于 2011-6-6 15:16:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 12:02:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 23:30:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 23:42:41 | 显示全部楼层
我目前基本用自己搞的方法,代码不多,大概也就这样:没有按下---判断状态位的状态,状态位是1表示按键松开了,状态位是0表示这次扫描没有键按下;有键按下--判断之前状态位,是1,表示键还未松开(这时加上计数值可以支持长按功能)是0,表示按键刚刚按下

出0入0汤圆

发表于 2011-6-10 00:25:20 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-6-10 09:41:15 | 显示全部楼层
只用VHDL编写过状态机  学习了

出0入0汤圆

发表于 2011-6-10 10:55:10 | 显示全部楼层
看到拼音就觉得累~~

出0入0汤圆

发表于 2011-6-10 21:18:37 | 显示全部楼层
回复【5楼】pxlpxlpxl
回复【3楼】skynet 青青草原
状态机就看马潮老师的就可以了,经典教程
-----------------------------------------------------------------------
马潮老师是哪本教程,还望指点
-----------------------------------------------------------------------

出0入0汤圆

发表于 2011-9-21 16:29:54 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-9-21 17:48:37 | 显示全部楼层
不懂状态机。记号先!

出0入0汤圆

发表于 2011-9-21 17:51:45 | 显示全部楼层
记号

出0入0汤圆

发表于 2011-9-21 22:21:02 | 显示全部楼层
回复【50楼】jeasen
回复【5楼】pxlpxlpxl  
回复【3楼】skynet 青青草原  
状态机就看马潮老师的就可以了,经典教程  
-----------------------------------------------------------------------  
马潮老师是哪本教程,还望指点
-----------------------------------------------------------------------

-----------------------------------------------------------------------

要不,给个链接也好撒

出0入0汤圆

发表于 2011-9-21 23:11:37 | 显示全部楼层
AVR单片机嵌入式系统原理与应用实践

出0入0汤圆

发表于 2011-9-22 09:27:13 | 显示全部楼层
学习学习,

出0入0汤圆

发表于 2011-9-22 11:37:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-22 11:42:18 | 显示全部楼层
正在学习中

出0入0汤圆

发表于 2011-9-22 11:54:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-26 21:46:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-26 21:59:25 | 显示全部楼层
马潮老师是那本教程,第9章:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=749020&bbs_page_no=1&bbs_id=1003

出0入0汤圆

发表于 2011-9-27 15:18:37 | 显示全部楼层
留个爪印

出0入0汤圆

发表于 2011-9-27 18:55:56 | 显示全部楼层
马老师的专栏http://www.ourdev.cn/bbs/bbs_list.jsp?bbs_id=1003
状态机的教程http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=741915&bbs_page_no=1&bbs_id=1003
状态机的代码在马老师的<<AVR单片机嵌入式系统原理与应用实践>>276页

出0入0汤圆

发表于 2011-9-27 19:37:48 | 显示全部楼层
这个可以顶 !

出0入0汤圆

发表于 2011-9-29 16:22:15 | 显示全部楼层
其实,直接用中文描述蛮好的,英文描述,拼音描述都要自我翻译下。

正准备用模块做键的处理。

出0入0汤圆

发表于 2011-10-12 22:33:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-12 22:49:01 | 显示全部楼层
觉对新手很有效

出0入0汤圆

发表于 2011-10-15 14:21:23 | 显示全部楼层
学习一下 ,看看能否应用到实践中!

出0入0汤圆

发表于 2011-10-15 16:36:08 | 显示全部楼层
millwood0的  3) if key pressed when in state 0, increment key_count; otherwise, go to state 0;
是否应该是   3) if key pressed when in state 1, increment key_count; otherwise, go to state 0;  

出0入0汤圆

发表于 2011-10-15 21:32:52 | 显示全部楼层
mark,但是也不懂,还是去看看马老师的视频算了

出0入0汤圆

发表于 2011-10-16 08:30:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-23 10:25:12 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-23 11:43:40 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-24 09:50:06 | 显示全部楼层
好 必须顶! 企业好像都是用的这种方法 中国的教育脱离现实啊

出0入4汤圆

发表于 2011-10-24 09:52:12 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-10-24 11:57:34 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2011-10-29 08:13:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-29 09:32:37 | 显示全部楼层
回复【楼主位】pxlpxlpxl
-----------------------------------------------------------------------

好东西

出0入0汤圆

发表于 2011-10-30 08:02:36 | 显示全部楼层
有点看不懂?谢谢楼主!

出0入0汤圆

发表于 2011-12-16 15:07:37 | 显示全部楼层
丁丁~

出0入0汤圆

发表于 2011-12-17 11:00:28 | 显示全部楼层
刚刚开始学的小菜鸟。还没学到这个精度。先马克了。

出90入0汤圆

发表于 2011-12-17 14:06:52 | 显示全部楼层
谢谢楼主分享^_^
学习了~

出0入0汤圆

发表于 2011-12-20 14:29:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-21 23:13:41 | 显示全部楼层
这个很好,值得深入学习

出0入0汤圆

发表于 2011-12-23 03:07:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-31 14:14:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-6-4 08:57:35 | 显示全部楼层
millwood0 发表于 2011-1-28 07:31
you can make it a lot simpler:

1) originally at state 0, reset key0;

搞毛啊 写什么英文

出0入0汤圆

发表于 2012-6-4 08:59:54 | 显示全部楼层
没仔细看 但是思路是用switch case作为状态跳转 这方法很灵活

出0入8汤圆

发表于 2012-6-4 09:18:07 | 显示全部楼层
hepday 发表于 2011-2-1 16:49
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;

有道理!

出0入0汤圆

发表于 2012-6-4 09:26:14 | 显示全部楼层
hepday 发表于 2011-2-1 16:49
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;

别人是认真回复的,是真诚的。不管是什么文。应该感谢回复!!!
其实我们并不了解实际情况,或许别人实际工作语言就是英文,写的时候比较顺手。
可以尝试用工具翻译,了解。
现在很多编程都用到E文,原版规格书也是E文。
学了很多年E文很差,但不能因此抗拒E文。

出0入0汤圆

发表于 2012-6-4 10:02:33 | 显示全部楼层
楼主的拼音不错,老外都能看得懂

出0入0汤圆

发表于 2012-6-20 17:22:39 | 显示全部楼层

老师的状态机在哪里有介绍啊~我很急啊给发个链接好不啊?

出0入0汤圆

发表于 2012-6-26 09:12:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-6-26 10:23:35 | 显示全部楼层
有点看不懂?谢谢楼主!

出0入0汤圆

发表于 2012-8-19 00:20:49 | 显示全部楼层
mark注意

出0入0汤圆

发表于 2012-8-19 10:32:12 来自手机 | 显示全部楼层
pxlpxlpxl 发表于 2011-1-28 12:49  回复【6楼】millwood0  you can make it a lot simpler:  1) originally at state 0, reset key0;

看懂这个,也不是太难吧,这位兄台回答不错啊,别太苛求别人了。

出0入0汤圆

发表于 2012-8-19 12:48:53 来自手机 | 显示全部楼层
pxlpxlpxl 发表于 2011-1-28 12:49
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;

6楼貌似是E国人 回帖都用英语

出0入0汤圆

发表于 2012-8-19 13:25:45 | 显示全部楼层
hepday 发表于 2011-2-1 16:49
回复【6楼】millwood0
you can make it a lot simpler:
1) originally at state 0, reset key0;


有些悲惨的公司没有中文输入法。。。。
再说了,作为写程序的,这点e文至少要看得懂吧。。。。。实在不行,字典翻翻很快就能解决的。。。

出0入0汤圆

发表于 2012-8-19 21:36:12 | 显示全部楼层
学习学习,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 16:26

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

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