51单片机的简单的矩阵键盘松手检测问题(很简单且短的一段代码)

2019-07-15 10:12发布

51单片机P0口接共阳数码管8个引脚,P1反接矩阵键盘8个脚
代码的功能是通过按键控制数码管显示不同数字,但我不知道松手检测这句代码应该在哪个花括号里合适,
代码如下:
#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


功能正常的代码 功能正常的代码
松手检测代码换位后出现按键无响应的代码 松手检测代码换位后出现按键无响应的代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
电人
1楼-- · 2019-07-15 14:45
 精彩回答 2  元偷偷看……
电人
2楼-- · 2019-07-15 16:58
我把他簡化如下:
正常程序:
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);//卡死在這裡

}
}
按鍵抖動
电人
3楼-- · 2019-07-15 17:18
我把他簡化如下:
正常程序:
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);//卡死在這裡

}
}
按鍵抖動
沈廷亨
4楼-- · 2019-07-15 18:14
POKONG123 发表于 2017-7-18 17:14
【波光芯城】电子元器件采购网 POKONG.NET

汇集全网的渠道数据,一次搜索,全部查看。


TechMonk
5楼-- · 2019-07-15 19:06
wulinwl 发表于 2017-7-18 14:56
首先你把while (GPIO_KEY != 0xf0);往下放一行是不妥的
如果按键抖动,第二个 if (GPIO_KEY != 0x0f)不能进入就会直接执行
while (GPIO_KEY != 0xf0);,漏掉执行GPIO_KEY = 0xf0;的机会,那么不死才怪。

有道理,谢谢你了

一周热门 更多>