用c51单片机按下4*4矩阵按键,数码管显示0-F,能正常显示,只是0号和7号有时会出错,请高手帮忙,

人为将7号键弄到时断时续的时候,有时数码管会显示一个乱码,再按一下又会正常 ,是按键消抖还不够好吗?或其它问题?如何排除?

#include <reg52.h>
#define uchar unsigned char
uchar key;
uchar code seg7[16]= {0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,
0x20,0x60,0x30,0x25,0xa9,0x26,0xa1,0xb1};//数码管代码
uchar key_jiang(void);

//--------------------------------------------------

void delay(uchar k)
{
uchar a,b;
for(a=k;a>0;a--)
for(b=120;b>0;b--);
}

//--------------------------------------------------

void key_sm(void)
{
uchar a,b,c;
P1=0XF0;
if(P1!=0XF0)
{
a=P1;
delay(10);
if(P1!=0XF0)
{
b=P1;
delay(5);
if(P1!=0XF0)
{
c=P1;
delay(5);
if((a&b)==c)
{
key_jiang();
key=key_jiang();
P0=seg7[key];
P2=0XFE;
for(;P1!=0XF0;);
delay(5);
for(;P1!=0XF0;);
}
}
}
}
}

//-------------------------------------------------

uchar key_jiang(void)
{
uchar a,b,c;
P1=0x0f; //------------------------低四位置1,高四位置0,
a=P1; //------------------------读P0口,
a=~(a|0xf0); //---P0口数据和高四位1相或,再取反,得按下行为1,
if(a==1) //--------------------如果第一位为1;
b=0;
else if(a==2) //--------------------如果第二位为1;
b=1;
else if(a==4) //--------------------如果第三位为1,
b=2;
else if(a==8) //--------------------如果第四位为1,
b=3;

P1=0XF0;
a=P1;
a=~((a>>4)|0xf0);
if(a==1)
c=b+0;
else if(a==2)
c=b+4;
else if(a==4)
c=b+8;
else if(a==8)
c=b+12;
else c=16;
return (c);

}

//-----------------------------------------------------------

void main (void)

{
while(1)
{
key_sm();
}
}

/************************************************************
类型:矩阵键盘。
现象:按下键盘后,数码管显示相应的数字0-F
【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!
************************************************************/
#include<reg52.h> //52单片机头文件,一般不要改动,里面包含特殊功能寄存器的定义
#define uchar unsigned char //将unsigned char定义为uchar,简化输写。提高编程速度
#define uint unsigned int //将unsigned char定义为uint,简化输写。提高编程速度
sbit H1=P0^4; //高四位分别对应P04-P07
sbit H2=P0^5;
sbit H3=P0^6;
sbit H4=P0^7;

void main()
{
P2=0x00; //关数码管,数码管不显示
while(1)
{
P0=0xfe;
if(H1==0){P2=0x3f;} //按键盘S1,显示"0"
if(H2==0){P2=0x06;} //按键盘S2,显示"1"
if(H3==0){P2=0x5b;} //按键盘S3,显示"2"
if(H4==0){P2=0x4f;} //按键盘S4,显示"3"
P0=0xfd;
if(H1==0){P2=0x66;} //按键盘S5,显示"4"
if(H2==0){P2=0x6d;} //按键盘S6,显示"5"
if(H3==0){P2=0x7d;} //按键盘S7,显示"6"
if(H4==0){P2=0x07;} //按键盘S8,显示"7"
P0=0xfb;
if(H1==0){P2=0x7f;} //按键盘S9,显示"8"
if(H2==0){P2=0x6f;} //按键盘S10,显示"9"
if(H3==0){P2=0x77;} //按键盘S11,显示"A"
if(H4==0){P2=0x7c;} //按键盘S12,显示"b"
P0=0xf7;
if(H1==0){P2=0x39;} //按键盘S13,显示"c"
if(H2==0){P2=0x5e;} //按键盘S14,显示"d"
if(H3==0){P2=0x79;} //按键盘S15,显示"E"
if(H4==0){P2=0x71;} //按键盘S16,显示"F"
}
}
一定要给分啊,我要下东西,程序一定没问题!!
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-10-23
一般读写操作都是先送地址,再送数据,所以你可以试试将P0=seg7[key];
P2=0XFE;
这两句掉换一下位置。即先赋值P2,再赋值P0。
第2个回答  2011-10-23
试试看:
#include <reg52.h>
#define uchar unsigned char
uchar key;
uchar code seg7[16] = {
0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,
0x20,0x60,0x30,0x25,0xa9,0x26,0xa1,0xb1};//数码管代码
//--------------------------------------------------
void delay(uchar k)
{
uchar a, b;
for(a = k; a > 0; a--) for(b = 120; b > 0; b--);
}
//-------------------------------------------------
uchar key_jiang(void)
{
uchar a, b, c;
P1 = 0x0f; //------------高四位置0, 低四位置1
a = P1; //------------读P0口,
a = ~(a | 0xf0); //-P0口数据,得按下行为1,
if (a == 1) b = 0;//-如果第一位为1;
else if(a == 2) b = 1;//-如果第二位为1;
else if(a == 4) b = 2;//-如果第三位为1,
else if(a == 8) b = 3;//-如果第四位为1,
else return (16);

P1 = 0xf0;
a = P1;
a = ~((a >> 4) | 0xf0);
if (a == 1) c = b + 0;
else if(a == 2) c = b + 4;
else if(a == 4) c = b + 8;
else if(a == 8) c = b + 12;
else c = 16;
return (c);
}
//--------------------------------------------------
void key_sm(void)
{
uchar a, b;
P1 = 0xf0;
a = P1;
if(a != 0xf0) {
delay(10);
b = P1;
if(a == b) {
key = key_jiang();
P0 = seg7[key];
P2 = 0xfe;
for(;P1 != 0xf0;);
}
}
}
//-----------------------------------------------------------
void main (void)
{
while(1) {
key_sm();
}
}追问

三楼的朋友 ,按你修过的写进去后,还是会出现同样的情况,而且更频繁,还有就是出现乱码后按任何按键都没有反应,只有复位单片机才能正常再按,能再帮忙分析下可能是什么原因吗?我怀疑是检测完行但还没有检测列的时候刚好松开了按键?

追答

上述程序,可以正常、稳定运行,仿真图可见下面。
上述程序,是仿照你的程序修改的,在按键消抖部分,含有硬伤。
你的程序中,是在确认了按键按下后,才去执行读入按键的函数,这样就晚了,出现的抖动,还是不可避免的。
当你用硬件运行时,就会暴露出来问题。
良好的消抖程序,可以参考:
http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/ef086222268d4f4eac34de59.html

本回答被提问者采纳
相似回答