求大家解惑,我的密码锁程序下载到
单片机里前三行键盘(4*4)可用,最后一行没用。如果1、4行线换接,最后一行变成第1行,键可用,第一行仍然不可用,且用别人的单片机也这样(是否排除硬件问题?)。
下面是我的键盘扫描程序 是否有问题呢?
uchar keyscan(void) //键盘扫描
{
uchar temp,zhi;
P1=0x7f;
temp=P1&0x7f;
if(temp!=0x7f)
{
delay(10);
P1=0x7f;
temp=P1&0x7f;
if(temp!=0x7f)
{
P1=0x7f;
temp=P1&0x7f;
switch (temp)
{
case 0x7e:zhi=1;break;
case 0x7d:zhi=2;break;
case 0x7b:zhi=3;break;
case 0x77:zhi=4;break;
}
while(temp!=0x7f)
{
P1=0x7f;
temp=P1&0x7f;
}
return zhi;
}
}
P1=0xbf;
temp=P1&0xbf;
if(temp!=0xbf)
{
delay(10);
P1=0xbf;
temp=P1&0xbf;
if(temp!=0xbf)
{
P1=0xbf;
temp=P1&0xbf;
switch (temp)
{
case 0xbe:zhi=5;break;
case 0xbd:zhi=6;break;
case 0xbb:zhi=7;break;
case 0xb7:zhi=8;break;
}
while(temp!=0xbf)
{
P1=0xbf;
temp=P1&0xbf;
}
return zhi;
}
}
P1=0xdf;
temp=P1&0xdf;
if(temp!=0xdf)
{
delay(10);
P1=0xdf;
temp=P1&0xdf;
if(temp!=0xdf)
{
P1=0xdf;
temp=P1&0xdf;
switch (temp)
{
case 0xde:zhi=9;break;
case 0xdd:zhi=10;break;
case 0xdb:zhi=11;break;
case 0xd7:zhi=12;break;
}
while(temp!=0xdf)
{
P1=0xdf;
temp=P1&0xdf;
}
return zhi;
}
}
P1=0xef;
temp=P1&0xef;
if(temp!=0xef)
{
delay(10);
P1=0xef;
temp=P1&0xef;
if(temp!=0xef)
{
P1=0xef;
temp=P1&0xef;
switch (temp)
{
case 0xee:zhi=13;break;
case 0xed:zhi=14;break;
case 0xeb:zhi=15;break;
case 0xe7:zhi=16;break;
}
while(temp!=0xef)
{
P1=0xef;
temp=P1&0xef;
}
return zhi;
}
else
{
zhi=0;
return zhi;
}
}
}
开发板上的I/O口往往都是重复接了外部设备,要看原理图或说明有无冲突。
推荐一款精巧的51单片机4*4矩阵键盘扫描程序,有自锁功能,利用主循环计数消抖,
应用中可根据主循环任务耗时调整消抖计数值。
#include <reg52.h> //头文件
#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
uchar key=0; //键值变量
void key_scan() //矩阵键盘扫描函数
{
uchar temp1,temp2,temp3; //临时变量
static bit sign=0; //按键自锁标志
static uchar count=0; //消抖计数变量
P1=0xf0; //先给P1赋一个初值
if(P1!=0xf0) //判断P1不等于所赋初值,说明有健按下
{
if(sign==0) //如果按键自锁标志=0
{
if(count>=100) //消抖计数值>=100
{
count=100; //防止溢出
sign=1; //按键自锁标志置1,键不抬起,按其他键无效
temp1=P1; //temp1反映高4位变化
P1=0x0f; //再给P1赋值0x0f
temp2=P1; //temp2反映低4位变化
temp3=temp2|temp1; //temp3=高4位+低4位
switch(temp3)
{
case 0xee: key= 1; break;
case 0xde: key= 2; break;
case 0xbe: key= 3; break;
case 0x7e: key= 4; break;
case 0xed: key= 5; break;
case 0xdd: key= 6; break;
case 0xbd: key= 7; break;
case 0x7d: key= 8; break;
case 0xeb: key= 9; break;
case 0xdb: key=10; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}
}
}
}
else //按键抬起
{
sign=0; //按键自锁标志清0
count=0; //消抖计数清0
}
}
void main()
{
while(1)
{
key_scan(); //扫描键盘
// 由不同键值控制的其他应用程序
}
}
补充内容 (2017-5-2 06:21):
在这里加一条:count++;,原程序是放在中断里的
if(P3!=0xf0) //判断P3不等于所赋初值,说明有健按下
{
if(sign==0) //如果按键自锁标志=0
{
count++;
if(count>=100) //消抖计数自>=100
{
count=100; //防止溢出
一周热门 更多>