微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 密码锁毕设求助 仿真成功 单片机实物键盘最后一行没用

密码锁毕设求助 仿真成功 单片机实物键盘最后一行没用

时间:10-02 整理:3721RD 点击:
求大家解惑,我的密码锁程序下载到单片机里前三行键盘(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;
}
}
}

而且我在寻找问题的时候换了一种键盘扫描程序,仿真依然没有问题,但是下载到单片机却一个键盘键也用不了

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;                                //防止溢出

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

网站地图

Top