单片机独立键盘与矩阵键盘的问题
#define GPIO_KEY P1 //矩阵键盘的接口
#define GPIO_DIG P0
typedef unsigned char u8;
u8 KEY;
sbit SM = P3^1; //输入密码按键
sbit GM = P3^0; //修改密码按键
sbit OK = P3^2; //确认键
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
void delay_ms(unsigned int x)
{
unsigned int i,j;
for(i = 0;i < x; i++)
for(j = 0; j < 110; j++);
}
u8 Keyscan()
{
char a = 0;
u8 KEY;
GPIO_KEY = 0x0f;
if(GPIO_KEY != 0x0f) //判断按键是否有按下
{
delay_ms(10); //延时去抖
if(GPIO_KEY != 0x0f) //再次判断是否有按下
{
//扫描列
GPIO_KEY = 0x0f;
switch(GPIO_KEY)
{
case(0x07):KEY = 0;break;
case(0x0b):KEY = 1;break;
case(0x0d):KEY = 2;break;
case(0x0e):KEY = 3;break;
}
//扫描行
GPIO_KEY = 0xf0;
switch(GPIO_KEY)
{
case(0x70):KEY = KEY;break;
case(0xb0):KEY = KEY+4;break;
case(0xd0):KEY = KEY+8;break;
case(0xe0):KEY = KEY+12;break;
}
while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
{
delay_ms(10);
a++;
}
return KEY;
}
}
}
void Keyscan_duli()
{
if(GM == 0)
{
delay_ms(10);
if(GM == 0)
{
KEY = 0x0b;
}
while(!GM);
}
else if(SM == 0)
{
delay_ms(10);
if(SM == 0)
{
KEY = 0x0a;
}
while(!SM);
}
else if(OK == 0)
{
delay_ms(10);
if(OK == 0)
{
KEY = 0x0c;
}
while(!OK);
}
}
void main()
{
LSA = 0;
LSB = 0;
LSC = 0;
while(1)
{
Keyscan_duli();
KEY = Keyscan();
GPIO_DIG = smgduan[KEY];
}
}
想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>
#define GPIO_KEY P1 //矩阵键盘的接口
#define GPIO_DIG P0
typedef unsigned char u8;
u8 KEY;
sbit SM = P3^1; //输入密码按键
sbit GM = P3^0; //修改密码按键
sbit OK = P3^2; //确认键
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
void delay_ms(unsigned int x)
{
unsigned int i,j;
for(i = 0;i < x; i++)
for(j = 0; j < 110; j++);
}
void Keyscan()
{
char a = 0;
// u8 KEY;
GPIO_KEY = 0x0f;
if(GPIO_KEY != 0x0f) //判断按键是否有按下
{
delay_ms(10); //延时去抖
if(GPIO_KEY != 0x0f) //再次判断是否有按下
{
//扫描列
GPIO_KEY = 0x0f;
switch(GPIO_KEY)
{
case(0x07):KEY = 0;break;
case(0x0b):KEY = 1;break;
case(0x0d):KEY = 2;break;
case(0x0e):KEY = 3;break;
}
//扫描行
GPIO_KEY = 0xf0;
switch(GPIO_KEY)
{
case(0x70):KEY = KEY;break;
case(0xb0):KEY = KEY+4;break;
case(0xd0):KEY = KEY+8;break;
case(0xe0):KEY = KEY+12;break;
}
while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
{
delay_ms(10);
a++;
}
// return KEY;
}
}
}
void Keyscan_duli()
{
if(GM == 0)
{
delay_ms(10);
if(GM == 0)
{
KEY = 0x0b;
}
while(!GM);
}
else if(SM == 0)
{
delay_ms(10);
if(SM == 0)
{
KEY = 0x0a;
}
while(!SM);
}
else if(OK == 0)
{
delay_ms(10);
if(OK == 0)
{
KEY = 0x0c;
}
while(!OK);
}
}
void main()
{
LSA = 0;
LSB = 0;
LSC = 0;
while(1)
{
Keyscan_duli();
Keyscan();
GPIO_DIG = smgduan[KEY];
}
}
不懂 大神求解
老铁们
Keyscan_duli();
KEY = Keyscan();
这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。
应该用两个不同的变量,或者用不同的按键码值
那显示时不就有两个变量名
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
还是不行
矩阵按键扫描函数错了。
//扫描列
GPIO_KEY = 0x0f;
switch(GPIO_KEY)
{
case(0x07):KEY = 0;break;
case(0x0b):KEY = 1;break;
case(0x0d):KEY = 2;break;
case(0x0e):KEY = 3;break;
}
//扫描行
GPIO_KEY = 0xf0;
switch(GPIO_KEY)
{
case(0x70):KEY = KEY;break;
case(0xb0):KEY = KEY+4;break;
case(0xd0):KEY = KEY+8;break;
case(0xe0):KEY = KEY+12;break;
}
应该是&=吧?你直接赋值,case没有满足的!
单独使用没问题啊
独立没问题就没问题呀,你矩阵错了,调试一下你就知道了
这样吧,你把IO的状态赋给一中间变量,判断这个变量。
先键盘矩阵,然后再是独立键盘之后还不行,是键盘矩阵的显示不对,还是独立键盘的显示不对,测试时键盘矩阵应该避开键值是A,B,C的按键
单片机、ARM、嵌入式相关问题加群羊交流201030910
这样就可以了,这是为啥啊
不管哪个先,都是独立键盘显示不对
这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。
哦,懂了,谢谢
谢谢各位大佬的回答