qun453176385 发表于 2011-12-9 14:07:42

一个简单的状态机按键测试,适合初学者。老鸟飘过……

http://cache.amobbs.com/bbs_upload782111/files_48/ourdev_703075EPMA9F.png
(原文件名:QQ截图20111209140229.png)

第一次接触状态机水平很次,希望多指教……

//==========================以下是代码================================
#include <REGX51.H>
#define uchar unsigned char
#define uint unsigned int

#define a 1       // 判断
#define b 2       // 消斗
#define c 3       // 确认
#define d 4       // 释放
ucharK=1;


sbit key1=P1^0;
sbit key2=P1^1;
void keyscan();


void main ()
{
P0=0xff;
P1=0xff;
while(1)
{
    keyscan();
}

}

void keyscan()
{
static uint time1=0;

switch(K)
   {
   case a:               //判断是否右键按下
           if(!key1||!key2)
           {
                   K=b;       //有键按下则跳到 b 即消斗
           }
           else
           K=a;                //没有键按下则返回继续判断
           break;

   case b:               //消斗
           if(++time1>300)
           {       
               time1=0;
                  if(!key1)       //如果按键1处于按下状态则P0_0取反
                  P0_0=~P0_0;
              if(!key2)             //如果按键2处于按下状态则P0_1取反
                  P0_1=~P0_1;
             K=c;                     //如果按键按下则跳转到c,即确认按键按下
           }
           else
             K=a;                     //否则返回a继续判断

           break;
       
       case c:                      //确认按键处于释放状态还是按下状态
                   if((key1)&&(key2))          //按键被释放
                  {
                   K=d;              //跳转到d,即释放状态
                  
                  }
                else           //如果按键没有释放
                  {
                     ;           //如果没有释放就什么都不做(功能太简单了)
                  }
                  
              break;

          case d:                   //按键被释放
                 P1=0xff;          //给按键高电平
             time1=0;          //赋初值
               K=a;          //返回a 继续判断
               break;
               
   default:
          break;
       
   }


}

Ilove51andAVR 发表于 2011-12-10 03:42:26

不容易啊,支持一下!

xuyapple 发表于 2011-12-10 09:24:57

学习了,一直没有用状态机写过程序,从按键扫描学起~

xiaowenshao 发表于 2011-12-10 21:11:55

支持一下

zhanan 发表于 2011-12-10 23:44:01

马老师的帖子:
http://www.ourdev.cn/bbs/bbs_content_all.jsp?bbs_sn=4991902
基本都有了。

把按键计时也当成状态考虑,就是这么简单了:
uchar key_driver(void)   // 读键盘
{
static uchar key_last=0, key_time=2;// 上次键值、按键计时
uchar key_press,key_return=0;// 按键值、返回码

   if(key_input) key_press=0; else key_press=1; // 读引脚:松开0,按下为1。

if(key_press!=key_last) {key_last=key_press; key_time=0;}// 新键值
if(key_time==1) key_return=(key_press==1)?11:1;// 按下键值=11及松开键值=1(消抖一次)
if(key_time==50 && key_press==1) key_return=3;   // 长按键值=3
if(key_time==55 && key_press==1) key_return=4;   // 连按键值=4
if(++key_time>60) key_time=55;// 最长限制(或连按间隔)
return key_return;   // 返回键值
}
上例程序是一个按键的,你是两个按键,把返回键值与实际按键结合一下即可。

zhanan 发表于 2011-12-10 23:49:24

上例程序20mS左右调用一次。

renwocai 发表于 2011-12-11 10:58:05

MARK个。

wxhdzs11 发表于 2011-12-12 21:33:15

咱也来个mark!

wxhdzs11 发表于 2011-12-15 19:27:02

按键扫描一般10ms扫一次吧!

wxhdzs11 发表于 2011-12-15 19:39:57

if(++time1>300)   要是20ms调用一次,前面这句话又是啥意思呢!

金牛AKI 发表于 2013-10-8 11:45:59

顶起 不错的状态机哈哈

zy0818 发表于 2013-10-9 02:49:49

学习,谢谢分享~~~

jz701209李 发表于 2013-10-10 20:26:35

学习一下,谢谢

ZYBing 发表于 2014-8-27 21:57:29

mark,学习!

mafeimafei 发表于 2014-11-23 18:23:49

学习了。

硬件小y 发表于 2014-11-24 09:23:40

写的不错呀
页: [1]
查看完整版本: 一个简单的状态机按键测试,适合初学者。老鸟飘过……