密码锁毕设求助 仿真成功 单片机实物键盘最后一行没用
下面是我的键盘扫描程序 是否有问题呢?
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;
}
}
}
而且我在寻找问题的时候换了一种键盘扫描程序,仿真依然没有问题,但是下载到单片机却一个键盘键也用不了
unsigned char zhiScan()
{
zhi=0; // 无键按下时,zhi=0xff;
P1=0x0f; // 在IO口由输出方式变为输入方式时要延迟一个
时钟周期。
P1=0x0f; // 采取写2次的方法延时。
if (P1!=0x0f)
{
delay(10); // 键盘消抖,延时10MS
if (P1!=0x0f) // 有键按下
{
P1=0xef; // 扫描第1行(逐行扫描开
始)
P1=0xef;
switch (P1)
{
case 0xe7:zhi=16;break;
case 0xeb:zhi=15;break;
case 0xed:zhi=14;break;
case 0xee:zhi=13;break;
}
//说明:本switch语句执行结束后会接着执行下面的语句,但由于P1口输出的扫描码
// 发生变化,程序不会进入后面的switch语句,也就不会多次修改zhi值。
P1=0xdf; // 扫描第2行(逐行扫描开
始)
P1=0xdf;
switch (P1)
{
case 0xd7:zhi=12;break;
case 0xdb:zhi=11;break;
case 0xdd:zhi=10;break;
case 0xde:zhi=9;break;
}
P1=0xbf; // 扫描第3行(逐行扫描开
始)
P1=0xbf;
switch (P1)
{
case 0xb7:zhi=8;break;
case 0xbb:zhi=7;break;
case 0xbd:zhi=6;break;
case 0xbe:zhi=5;break;
}
P1=0x7f; // 扫描第4行(逐行扫描开
始)
P1=0x7f;
switch (P1)
{
case 0x77:zhi=4;break;
case 0x7b:zhi=3;break;
case 0x7d:zhi=2;break;
case 0x7e:zhi=1;break;
}
P1=0x0f; // 在IO口由输出方式变为
输入方式时要延迟一个时钟周期。
P1=0x0f; // 采取写2次的方法延时。
while(P1!=0x0f); // 等待按键释放
}
}
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; //防止溢出