51单片机的简单的矩阵键盘松手检测问题(很简单且短的一段代码)
代码的功能是通过按键控制数码管显示不同数字,但我不知道松手检测这句代码应该在哪个花括号里合适,
代码如下:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define GPIO_DIG P0
#define GPIO_KEY P1
uchar code smgduan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar KeyValue;
void MatrixKeyScan();
void delayms(uint xms);
void main()
{
while (1)
{
MatrixKeyScan();
GPIO_DIG = ~smgduan[KeyValue];
}
}
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
delayms(10);
if (GPIO_KEY != 0x0f)
{
switch (GPIO_KEY)
{
case 0x07:KeyValue = 0;break;
case 0x0b:KeyValue = 1;break;
case 0x0d:KeyValue = 2;break;
case 0x0e:KeyValue = 3;break;
}
GPIO_KEY = 0xf0;
switch (GPIO_KEY)
{
case 0x70:KeyValue += 0;break;
case 0xb0:KeyValue += 4;break;
case 0xd0:KeyValue += 8;break;
case 0xe0:KeyValue += 12;break;
}
while (GPIO_KEY != 0xf0);
}
}
}
void delayms(uint xms)
{
uint i,j;
for (i = xms;i > 0;i--)
for (j = 110;j > 0;j--);
}
松手检测这句代码 while (GPIO_KEY != 0xf0);倘若在往下放一行,即放到下一个花括号外,即把代码从前图改成后图,就出现了这样的现象:一开始按键数码管随之正确显示,但按几次后就出现了无论如何按键数码管数字都不改变,很明显是因为程序陷入了松手检测的死循环,但我不明白为什么改变松手检测代码的位置,就会使按键按几次就进入了 while (GPIO_KEY != 0xf0)死循环?
所以想问:
(1)松手检测代码位置在哪个花括号里有什么要求?
(2)为何出错的那种情况 必须是按了几次按键才使代码陷入死循环?
file:///C:/Users/zhouw/AppData/Roaming/Tencent/Users/858792539/QQ/WinTemp/RichOle/@VANE%7D~X7JFRCTD4Y%7D)G]4C.png
功能正常的代码
松手检测代码换位后出现按键无响应的代码
首先你把while (GPIO_KEY != 0xf0);往下放一行是不妥的
如果按键抖动,第二个 if (GPIO_KEY != 0x0f)不能进入就会直接执行
while (GPIO_KEY != 0xf0);,漏掉执行GPIO_KEY = 0xf0;的机会,那么不死才怪。
我把他簡化如下:
正常程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f)
{
GPIO_KEY = 0xf0;
while (GPIO_KEY != 0xf0);
}
}
}
出現錯誤的程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f) //如果此時發生抖動,跳過此判斷和GPIO_KEY = 0xf0,則此時GPIO_KEY = 0x0f
{
GPIO_KEY = 0xf0;
}
while (GPIO_KEY != 0xf0);//卡死在這裡
}
}
按鍵抖動
我把他簡化如下:
正常程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f)
{
GPIO_KEY = 0xf0;
while (GPIO_KEY != 0xf0);
}
}
}
出現錯誤的程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f) //如果此時發生抖動,跳過此判斷和GPIO_KEY = 0xf0,則此時GPIO_KEY = 0x0f
{
GPIO_KEY = 0xf0;
}
while (GPIO_KEY != 0xf0);//卡死在這裡
}
}
按鍵抖動
我把他簡化如下:
正常程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f)
{
GPIO_KEY = 0xf0;
while (GPIO_KEY != 0xf0);
}
}
}
出現錯誤的程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f) //如果此時發生抖動,跳過此判斷和GPIO_KEY = 0xf0,則此時GPIO_KEY = 0x0f
{
GPIO_KEY = 0xf0;
}
while (GPIO_KEY != 0xf0);//卡死在這裡
}
}
按鍵抖動
我把他簡化如下:
正常程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f)
{
GPIO_KEY = 0xf0;
while (GPIO_KEY != 0xf0);
}
}
}
出現錯誤的程序:
void MatrixKeyScan()
{
GPIO_KEY = 0x0f;
if (GPIO_KEY != 0x0f)
{
if (GPIO_KEY != 0x0f) //如果此時發生抖動,跳過此判斷和GPIO_KEY = 0xf0,則此時GPIO_KEY = 0x0f
{
GPIO_KEY = 0xf0;
}
while (GPIO_KEY != 0xf0);//卡死在這裡
}
}
按鍵抖動
好
有道理,谢谢你了