微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机的简单的矩阵键盘松手检测问题(很简单且短的一段代码)

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

时间:10-02 整理:3721RD 点击:
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

功能正常的代码


松手检测代码换位后出现按键无响应的代码


首先你把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);//卡死在這裡
}
}
按鍵抖動


有道理,谢谢你了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top