微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 单片机求助 矩阵键盘4*4 行在P1口低0-3为行 P3口0-3为列 哪错了

单片机求助 矩阵键盘4*4 行在P1口低0-3为行 P3口0-3为列 哪错了

时间:10-02 整理:3721RD 点击:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit wei=P2^7;
sbit duan=P2^6;
uchar du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar we[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void delay(uint a)
{uint i,j;
for(i=a;i>0;i--)
for(j=110;j>0;j--)
;
}
void display(uchar num)
{
duan=1;
P0=du[num];
duan=0;
}
void keycan()
{uchar key,keyl,keyh,l;
P1=0x00;
P3=0x0f;
keyl=P3;
keyl=keyl&0x0f;
if(keyl!=0x0f)
{delay(10);
if(keyl!=0x0f)
{
keyl=keyl<<4;
keyl=keyl|0x0f;
keyh=P1;
keyh=keyh&0x0f;
keyl=keyl&0xf0;
key=keyl+keyh;
}
switch(key)
{ case 0xee :l=0;break;
case 0xde :l=1;break;
case 0xbe :l=2;break;
case 0x7e :l=3;break;
case 0xed :l=4;break;
case 0xdd :l=5;break;
case 0xbd :l=6;break;
case 0x7d :l=7;break;
case 0xeb :l=8;break;
case 0xdb :l=9;break;
case 0xbb :l=10;break;
case 0x7b :l=11;break;
case 0xe7 :l=12;break;
case 0xd7 :l=13;break;
case 0xb7 :l=14;break;
case 0x77 :l=15;break;
}
display(l);
}
}
void main()
{
wei=1;
P0=0x02;
wei=0;
while(1)
{
keycan();
}
}
数码管上显示对应的按键

我看看

看出哪错了吗

四行扫描没循环起来,

应该怎么改下  那边keyh=P1 这里不是给它行的了吗

很多问题,获取列值的时候正确了,但获取行值的时候错了,记住一点,I/O口高电平跟低电平连在一起的话,高的只会被拉低,低的不会被拉高,就是两个都会变成低。或者你也可以用逐行扫描的方法

你在获取行值之前加上P1=0x0f;    P3=0x00;试试?

太他妈的感谢您了 大神

不过能解释下 为什么这样就可以了吗  大神

你一开始的时候给P1赋值了P1=0x00;
而获取行值的时候你把P1的值赋给keyh,keyh=P1;即keyh=0x00,
所以keyh=keyh&0x0f;这一句执行后keyh的值依然是0x00,说到这,后面的就不用分析了吧!
总结一下:获取行值跟获取列值要分开来算,取列值时:要把所有行置低,列置高,然后再检查列,哪一列低就证明按键在哪一列(I/O口高的会被拉低,低的不会被拉高,前面说过了);同理:取行值时,要把所有列置低,行置高,再检查行,哪一行为低即按键在哪一行!你就是在取行值时没把列置低、行置高所以.还有一种逐行扫描的方法,有兴趣的话百度研究一下

受教不少,真有耐心的解答

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

网站地图

Top