一个简单的状态机按键测试,适合初学者。老鸟飘过……
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;
}
} 不容易啊,支持一下! 学习了,一直没有用状态机写过程序,从按键扫描学起~ 支持一下 马老师的帖子:
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; // 返回键值
}
上例程序是一个按键的,你是两个按键,把返回键值与实际按键结合一下即可。 上例程序20mS左右调用一次。 MARK个。 咱也来个mark! 按键扫描一般10ms扫一次吧! if(++time1>300) 要是20ms调用一次,前面这句话又是啥意思呢! 顶起 不错的状态机哈哈 学习,谢谢分享~~~ 学习一下,谢谢 mark,学习! 学习了。 写的不错呀
页:
[1]