在网上论坛经常看到这个新型的按键扫描程序,
新型的按键扫描程序
核心算法:
unsigned char Trg;
unsigned char Release;
unsigned char Cont;
void KeyRead( void )
{
unsigned char ReadData = PINB^0xff; // 1 读键值
Trg = ReadData & (ReadData ^ Cont); // 2 得到按下触发值
Release=(ReadData^Trg^Cont); //3 得到释放触发值
Cont = ReadData; //4 得到所有未释放的键值
}
(1) 没有按键的时候 ReadData = 0x00;Trg = 0x00;Cont = 0x00;
(2) 第一次PB0按下的情况 ReadData = 0x01;Trg = 0x01;Cont = 0x01;
(3) PB0按着不松(长按键)的情况 ReadData = 0x01;Trg = 0x00;Cont = 0x01;
(4) 按键松开的情况 ReadData = 0x00;Trg = 0x00;Cont = 0x00;
数码之家贴子在http://bbs.mydigit.cn/read.php?tid=584859,利用状态机思想扫描按键,感觉很有用,就想移植。但是移植过程中就发现问题了:理论是支持多个按键的扫描,但是我实验时怎么就只能实现一个按键的扫描呢?而且有点诡异现象!
我的实验部分代码:
#define KEY1 =0x01
#define KEY2 =0x02
#define KEY3 =0x04
uchar Trg=0,Cont=0;
uchar num;
void keyscan(){
unsigned char ReadData=(P2|0xf8)^0xff;//~(P2|0xf8);//(P2|0xf8)^0xff;//P2^0,1,2组需要处理,其他屏蔽
Trg=ReadData &(ReadData^Cont);//判断是否点动,异或:不同就1
Cont=ReadData;//判断是否长按
}
void tiem1(void) interrupt 3{
keyscan();
if(Trg&KEY1){
num++;
if(num>15)
num=0;
}
if(Trg&KEY2){
num--;
if(num<1)
num=15;
}
if(Trg&KEY3){
num=0;
}
display();
TH1 = 0x63; //20ms扫描一次
TL1 = 0xc0;
}
我的实验结果:
1、 void tiem1(void) interrupt 3{
keyscan();
if(Trg&KEY1){
num++;
if(num>15)
num=0;
}
if(Trg&KEY2){
num--;
if(num<1)
num=15;
}
if(Trg&KEY3){
num=0;
}
display();
TH1 = 0x63; //20ms扫描一次
TL1 = 0xc0;
}
则只有KEY1起作用,可以短按,长按。其他按键无效。
2、 keyscan();
if(Trg&KEY2){
}
if(Trg&KEY3){
}
if(Trg&KEY1){
}
则只有KEY2起作用,其他按键无效。
3、keyscan();
if(Trg&KEY3){
}
if(Trg&KEY1){
}
if(Trg&KEY2){
}
则只有KEY3起作用,其他按键无效。
结论:谁在前,谁起作用,不能多按键扫描。
这就是上面我所说的诡异了。搞了很久都没搞明白我实在是菜啊
请各位亲指点下迷津
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
//按键检测
unsigned char KeyPressDown=0x00; //键按下
unsigned char KeyRelease=0x00; //键弹起
unsigned char LastKey=0x00;
void KeyScan(void)
{
static unsigned char LastReadKey=0x00;
unsigned char CurrReadKey;
unsigned char CurrKey;
unsigned char KEY_H=0,KEY_L=0;
//读键盘
P2=0x0f; //高四位输出低电平
KEY_H=P2&0x0f; //读低四位
P2=0xf0; //低四位输出低电平
KEY_L=P2&0xf0; //读高四位
CurrReadKey=~(KEY_H | KEY_L); //取反
CurrKey=(CurrReadKey&LastReadKey)|LastKey&(CurrReadKey^LastReadKey);
//记录按键按下及释放
KeyPressDown=(~LastKey)&CurrKey;
KeyRelease=LastKey&(~CurrKey);
LastReadKey=CurrReadKey;
LastKey=CurrKey;
}
void KeyPress(void)
{
switch (KeyPressDown)//根据按下的键散转
case 0x18:
//按键1
break;
case 0x21:
//按键2
.
.
case 0x24:
//按键16
break;
}
一周热门 更多>