|
发表于 2008-3-25 00:42:46
|
显示全部楼层
我也发一个,下面是其中的一段,我是设定时5ms运行次KeyJudge,结果在key这个变量里,按下放开都有20s按键消抖,消抖和判断的程序有点状态机的思想,以前写的时候也还不知道状态机这东西,要知道就写的好看点了,没这么难看
按键是可以有2个组合键的,当然,单键也可以啦。
初学AVR,程序从以前写的51的程序移植的,菜鸟一个,大家多指教啊
/***************************************************
KEY FOR AVR 2008.3.16 BY CY
***************************************************/
#define uint unsigned int
#define uchar unsigned char
#include <avr/io.h>
//#include "DM12864J_1ForAVRYY.h"
//#include <avr/pgmspace.h>
#define KeyPort PORTC
#define KeyPortDDR DDRC
#define KeyPortPIN PINC
/*==================================================
按键按下放开后
若KeyAllow=1则按键通过
若KeyAllow=0则按键无效
结果在Key中体现
==================================================*/
uchar KeyTimeCon = 0; //定时计数器
uchar Key = 0xff; //Key为确认的按键,体现按下的结果
uchar KeyTemp, KeyState = 0xff; //来存放 还没确认 及 确认 的按键读数,按键为空时为0xff
uchar EffectiveKey = 0xff; //存放有效的按键读数
uchar KeyAllow = 1;
/*===================================================================
直接读取按键当前状态
===================================================================*/
uchar ReadKey(void)
{
uchar i = 0;
uchar a[] = {0, 0, 0};
KeyPortDDR = 0x0f;
KeyPort = 0xfe;
asm("nop");
if(!(KeyPortPIN & (1 << 4)))a[i++] = 1;
if(!(KeyPortPIN & (1 << 5)))a[i++] = 2;
if(!(KeyPortPIN & (1 << 6)))a[i++] = 3;
if(!(KeyPortPIN & (1 << 7)))a[i++] = 4;
KeyPort = 0xfd;
asm("nop");
if(!(KeyPortPIN & (1 << 4)))a[i++] = 5;
if(!(KeyPortPIN & (1 << 5)))a[i++] = 6;
if(!(KeyPortPIN & (1 << 6)))a[i++] = 7;
if(!(KeyPortPIN & (1 << 7)))a[i++] = 8;
KeyPort = 0xfb;
asm("nop");
if(!(KeyPortPIN & (1 << 4)))a[i++] = 9;
if(!(KeyPortPIN & (1 << 5)))a[i++] = 0;
if(!(KeyPortPIN & (1 << 6)))a[i++] = 10;
if(!(KeyPortPIN & (1 << 7)))a[i++] = 11;
KeyPort = 0xf7;
asm("nop");
if(!(KeyPortPIN & (1 << 4)))a[i++] = 12;
if(!(KeyPortPIN & (1 << 5)))a[i++] = 13;
if(!(KeyPortPIN & (1 << 6)))a[i++] = 14; //0x0e
if(!(KeyPortPIN & (1 << 7)))a[i++] = 15; //0x0f
a[1] = a[1] << 4;
if (i == 0)return 0xff;
else return (a[0] + a[1]);
}
/*===================================================================
按键判断,结果体现在Key中,无按键或按键无效则Key=0xff
变化状态后,当前有一个取消键则无效KeyAllow=0
有效的情况为: 1、无取消键且当前为组合键
2、无取消键且当前为单键且上一个状态为放开
===================================================================*/
void KeyJudge(void)
{
if(KeyTimeCon)
{
KeyTimeCon++;
if(KeyTimeCon == 5)
{
KeyTimeCon = 0;
if(KeyTemp == ReadKey()) //确认是否改变了一次状态
{
if(KeyTemp == 0xff) //现在确定的状态为放开
{ //判断刚才的按键是否有用
if(KeyAllow == 1) //按键允许生效
{
Key = EffectiveKey; //结果在Key中体现
EffectiveKey = 0xff;
}
else //按键不允许
{
Key = 0xff;
KeyAllow = 1;
EffectiveKey = 0xff;
}
}
else if((0xf0 == (KeyTemp & 0xf0)) || (0x0f == (KeyTemp & 0x0f)))//现在确定的状态为按下
{ //有取消键
KeyAllow = 0; //则此次按键无效
}
else if((KeyTemp > 0x0f) || (KeyState == 0xff)) //无取消键
{
EffectiveKey = KeyTemp;//除了是单键且前一次是放开以外的情况,都可使按键生效
}
KeyState = KeyTemp; //使用先前的状态判断完毕,可以把确认状态改变
}
}
}
else if(KeyState != ReadKey())
{
KeyTemp = ReadKey();
KeyTimeCon++;
}
} |
|