关于51单片机矩阵键盘移位输入的疑问,为什么我这样写在低四位数码管显示的都是同一个按下的对应数字??

作者&投稿:连有 (若有异议请与网页底部的电邮联系)
4*4矩阵键盘控制四位数码管显示单片机C语言程序:如果输入少于4位 则全部显示,如果多余4位 则显示最后4位~

这个问题的最大关键不在显示,而是在输入,你输入必须要设置输入缓存区,和输入保存的区域,还有显示的缓存区,当你的输入小于4位的时候,将输入保存里的数据转入显示缓存,当输入大于4位的时候,你讲保存的数据后四位转入显示缓存,这样就可以了。你不能再显示里面解决这个问题,因为你一个单片机,4个数码管,明显只能用动态显示,再来判断的我话,任务就很乱了,所以你只有在输入的时候将要现实的数据准备好,这样显示函数就只负责显示就可以了,速度又快,又不会出错,关键是你在将输入保存区的数据转入显示缓存的时候不要出错。祝你进步。

#include
#define uchar unsigned char
#define ROWP P3
#define LINP P2
void Delay(uchar i) {
uchar j;
for(;i>0;i--)
for(j=0;j<112;j++)
_nop_();
}
uchar Keyscan(){
uchar i,j,RLP,num;
for(i=0;i<4;i++){
LINP=(LINP|0xf0)&(~(0x10<<i));
Delay(1);
for(j=0;j<5;j++){
RLP=(ROWP|0x1f)&(~(0x10>>j));
if(ROWP==RLP){
Delay(2);
if(ROWP==RLP)
num=i*5+j+1;
}
}
}
return num;
}
5*4的,稍微修改,就是4*4的

你的位选送入是同样的数据,那当然是显示同样的数,你要分清楚位选,是怎么样位选,这样你就可以想那个显示什么数字都可以了。
你的P2口,你想要用独立按键或是矩阵按键,都要写捡测是否有键按下,这个你应该是知道的了,在这里,你的P2口打开,你这样写不是很好,你写的格式,要分好点,不然到你检查的时候就很难检查得到,还有你这里没有去抖,当按键按下时,会出错,
P2 = TestKeyCode;
if(!P23)
{
ScanKeyCode = 4*i + 1;
break;
}
else if(!P22)
{
ScanKeyCode = 4*i + 2;
break;
}
else if(!P21)
{
ScanKeyCode = 4*i + 3;
break;
}
else if(!P20)
{
ScanKeyCode = 4*i + 4;
break;
}

1.位定义最好用有意义的英文(哪怕拼音也好),方便检查和阅读
2.矩阵键盘的扫描有这么几种:行列扫描,反转扫描,中断扫描;按下时要去抖,功能实现一般要等键按完(弹起来)后才去实现功能
3.数码管的动态扫描的程序设计你没有掌握,而且动态扫描还要注意消影
4.数码管的动态扫描配合键盘时,要注意闪烁问题,解决闪烁有两个方法:
第一个方法:键盘消抖不用延时函数,而用数码管动态扫描函数
第二个方法:用中断的方法每2ms调用一次数码管动态扫描函数,因为中断不受按键影响
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define DataPort P0
#define KeyPort P3
sbit dula=P2^2;//段选
sbit wela=P2^1;//位选
uchar tempData[8];
uchar code DuanMa[]= //段码
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar code WeiMa[]= //位码
{
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f
};

void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void display(uchar firstBit,uchar disCount)
{
static uchar i;
wela=1;//为了消影
DataPort=0xff;
wela=0;

dula=1;
DataPort=tempData[i];
dula=0;
DataPort=0xff;//为了消影
wela=1;
DataPort=WeiMa[i+firstBit];
wela=0;
i++;
if(i==disCount)
i=0;
}

uchar keyscan()
{
uchar value;
KeyPort=0xfe;//采用行列扫描
if((KeyPort&0xf0)!=0xf0)
{
delay(10);//消抖
if((KeyPort&0xf0)!=0xf0)
{
value=KeyPort;
while((KeyPort&0xf0)!=0xf0);
return value;
}
}

KeyPort=0xfd;
if((KeyPort&0xf0)!=0xf0)
{
delay(10);
if((KeyPort&0xf0)!=0xf0)
{
value=KeyPort;
while((KeyPort&0xf0)!=0xf0);
return value;
}
}

KeyPort=0xfb;
if((KeyPort&0xf0)!=0xf0)
{
delay(10);
if((KeyPort&0xf0)!=0xf0)
{
value=KeyPort;
while((KeyPort&0xf0)!=0xf0);
return value;
}
}

KeyPort=0xf7;
if((KeyPort&0xf0)!=0xf0)
{
delay(10);
if((KeyPort&0xf0)!=0xf0)
{
value=KeyPort;
while((KeyPort&0xf0)!=0xf0);
return value;
}
}
return 0xff;
}

unsigned char KeyPro(void)
{
switch(keyscan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}

void init()
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}

void main()
{
uchar num,i,j;
init();
while(1)
{
num=KeyPro();
if(num!=0xff)
{
if(i<8)
{
tempData[i]=DuanMa[num];
i++;
}
else
{
i=0;
for(j=0;j<8;j++)
tempData[j]=0;
}
}
}
}

void timer0(void) interrupt 1
{
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
display(0,8); // 调用数码管扫描
}

在每一次段选显示数字之后 位选开了,一定要关闭,再送下一个数据。段选和位选要分开啊


51单片机矩阵按键程序
下述为程序: #include reg51.h#define Keyvalue P1 \/\/按下的键的代号#define Digvalue P0 \/\/用宏定义来定义一下数码管的发送数据端口typedef unsigned int ut;typedef unsigned char uc;ut k;sbit LSA=P2^2; \/\/定义三八译码器的三个输入端口sbit LSB=P2^3;sbit LSC=P2^4; ut smgduan[]=...

51单片机如何用矩阵键盘输入数值,最后赋值到一个变量上
你做矩阵键盘检测的时候,会触发相关的IO口的状态,通过分析IO口,就能知道那个键按下;定义一个变量,将按下的键值赋给变量就行了

C 51单片机 矩阵按键
首先记住,你的是矩阵键盘,就是说一个按键A的一端接单片机的一个脚(假设P00),另一个也接一个脚(假设P07),GPIO_KEY=0x0f; 当没有按下的话,GPIO_KEY还是等于0x0f的,假设按下A按键,由于按键两边一个接高电平,一个接低电平,按下后,高电平被低电平拉成低电平,也就是说按键A两侧都...

51单片机如何把矩阵键盘控制数码管和独立键盘控制蜂鸣器共同实现_百度...
对于矩阵键盘常用的扫描方法为线反转查询法。具体的思路是:首先使行作为输入,使用单片机内部电阻上拉为高电平,列输出低电平,读行的状态。如果行有一个IO口是低,说明有键按下,进行下一步,否则退出扫描。如果有键按下,置列为输入,行输出低电平,读列的状态。最后根据 行列的状态查表就可以知道...

51单片机,4*4矩阵键盘,八位数码管
51单片机,4*4矩阵键盘,八位数码管,仿真实例可以参考一下。include<reg51.h> define uchar unsigned char uchar temp;int key1,key,disbuf;\/\/ 此表为 LED 的字模 0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x...

51单片机做矩阵键盘检测是否有按键输入的时候为什么是与0xf0做比较呢...
temp = temp & 0xf0; 清楚低四位的扫描信号,保留高四位的按键状态 while (temp != 0xf0) 如果有按键按下,高四位会有一位变0,进入循环,直到按键放开,高四位 全变为1,才跳出循环;如果没有按键按下,循环不会执行 为什么是与0xf0比较呢 由于高四位是读入按键状态的,在输入之前为了...

关于51单片机矩阵键盘的问题。
(2)4X4 矩阵键盘的8根线直接连在IO上,而独立按键有一根线固定是接地的,这就意味着必须采取扫面或者线反转的方法。比如其中一根行线赋0,相当于这一行的四个按键变成了四个独立按键,在读取列线的值就知道了究竟哪个按键被按下了。 此时P3口就出现了特定的电平组合,相当于特征码了,然后再...

51单片机 c语言编程 4*4矩阵键盘如何实现等待按键松开功能?
1、在程序检测到按键后,加个延时去抖,不要加松手检测。然后执行第一个按键相对应的程序。然后继续按键扫描。注意这里说的是继续,也就是继续往下检测。否则的程序就只能执行第一个按键所对应的程序了。这样,就能检测到第二次按键的键值了。2、例程:uchar shaomiao(){uchar l,h;P1=0xf0;\/\/获取...

51单片机,怎么用矩阵键盘中的两个按键控制外部中断0和1,在按按键的时...
让 P3.7 始终为 0,然后就是按 S12 触发外部中断 0,按 S16 触发外部中断 1。

为什么51单片机的矩阵键盘不可以让单片机对整个p3进行扫描,例如判断p...
矩阵键盘,也就是行列式键盘。因为列线是共用的,行线也是共用。所以,只能逐行(或逐列)的检测。不能一次性全部读出。

贡井区15212775363: 单片机用矩阵键盘控制数码管怎么数据移位 -
端建必瑞: 弄个数组存放输入的密码,每次输入则将数组做移位,然后每次显示都把数组中所有的字符显示一次就达到移位显示了..参考程序发给你了

贡井区15212775363: 51单片机矩阵键盘问题 -
端建必瑞: 这问题问得还是可以,scan1&0xf0 就是为了防止其他因素干扰了P1的低四位,用你说的scan1!=0xf0 程序就会认为有按键按下,实际则没有.只不过在不严格要求下用 scan1!=0xf0 也是可以的.顺便提醒你一下,程序改了,实践下就知道了

贡井区15212775363: 关于51单片机矩阵键盘的问题. -
端建必瑞: 单片机矩阵键盘,如上述是 4x4 的矩阵键盘, P3=0xfe; //比如这里 1111 1110 这是扫描第一组 4 个键,按下 4 个键 读到的数据为 1110 1110 (0xee)、1101 1110 (0xde)、1011 1110 (0xbe)、0111 1110 (0x7e) P3=0xfd; //比如这里 1111 1101 ...

贡井区15212775363: 51单片机矩阵键盘检测方面的问题 -
端建必瑞: 第一个问题,应该是考虑如果先开锁存器,在那一时刻,P0的值还是上一次给P0赋的值,下在一条语句才将这次的值给P0,这样会造成数码管的余辉,静态显示的时候,因为太快看不到,动态显示时,就会比较明显了.第二个问题他的程序应该检测的是高四位,是否被拉低,因为temp和0xf0与,低四位不管是什么,都是0,只有高四位的值从1,变为0,0xf0才会发生改变.

贡井区15212775363: AT89c51系列单片机IO的疑问,我在做矩阵键盘的时候发现的问题,当我将列线都上拉10K电阻到+5V -
端建必瑞: 按你这样说,电路应该是没有问题的.还有就是你在51单片机上..除了用P0口要上啦电阻外,都可以不用接上拉电阻..除非你要用到较大的电流驱动,. 还有就是你最后一个问题..使用电位器是有可以由底变高的,单片机吸收的电流小于供给的电流的时候,,就会变为高平了...

贡井区15212775363: 51单片机做矩阵键盘检测是否有按键输入的时候为什么是与0xf0做比较呢? -
端建必瑞: P3 = 0xfd; 高四位设置为输入状态,低四位输出扫描信号,扫描P3.1所在的行 temp = P3; 读入按键状态,无按键按下时为0xfd,有按键按下时高四位会有一位变0 temp = temp & 0xf0; 清楚低四位的扫描信号,保留高四位的按键状态 while (...

贡井区15212775363: C 51单片机 矩阵按键 -
端建必瑞: 首先记住,你的是矩阵键盘,就是说一个按键A的一端接单片机的一个脚(假设P00),另一个也接一个脚(假设P07), GPIO_KEY=0x0f; 当没有按下的话,GPIO_KEY还是等于0x0f的,假设按下A按键,由于按键两边一个接高电平,一个接低电平,按下后,高电平被低电平拉成低电平,也就是说按键A两侧都是0,此时不就可以判定了嘛

贡井区15212775363: 求教!51单片机,利用矩阵键盘和数码管. -
端建必瑞: 要加到几百几千的,就要用几位数码管了,显示到百位,要有3位数码管,显示到千位,要有4位数码管. 计数时,用一个变量,就正常计数呗,按一次键变量加1,关键是分别取出个十百千位,分别送到每一位数码管显示就行了,很简单的吗.

贡井区15212775363: 单片机4*4矩阵键盘接反了,大家有没遇过这种情况. -
端建必瑞: LZ小白接反了你不会改程序嘛,我们搞单片机的就是根据硬件写程序的,人家怎么接是人家的事,一点不会变通搞个球啊,LS矩阵键盘没有位定义的OK??人家已经连接好了IO..你要好好看看程序,主要是判断P3口的电平而判断是哪个按键所以说跟硬件怎么接有直接关系,但主要是软件的灵活变通,你还没有理解矩阵建键盘的意思..

贡井区15212775363: 51单片机矩阵键盘程序问题求解? -
端建必瑞: 这个是一个状态逻辑的问题...刚开始知编程时,最好先画副状态图,即先确定哪个状态会响应哪个按键,然后再根据状态分别处理各种按键...如你道举例说明的..你应该存在三个状态,假设为1.2,3及两个按键专1,2初始状态为1,按键1后就会进入2态,如果这个时候再按键2就进入三态,进行相应的处理逻辑..所在你要在每个状态对所有按键处理情况都要分析属清楚..

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网