单片机8051缓存显示

COMPUTERZZZ 2010-04-21 08:30:24
功能:把键盘输入的数据存入显示缓存区 displaybuf ,然后显示缓存区的内容,
调试的结果不对,显示很乱~

不知道什么原因?


#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit ledk=P2^5; //锁存口
sbit d0=P1^0; //锁存口
sbit wela=P2^7; //使能口
sbit dula=P2^6; //使能口
uchar count;
uchar displaybufpoint; //当前显示位
uchar displaybuf []={0xff,0xff,0xff,0xff,0xff,0xff};//显示缓存区


void display_smg(uchar we,uchar du);


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

}


//判断是否有键按下
uchar key_press()
{
uchar key;
P3=0xf0;
key=P3;
key=key&0xf0;
if(key==0xf0)
{
return 0;
}
else
{
return 1; //有键被按下
}

}



//键盘扫描
uchar key_scan()
{
uchar key;
if(key_press()) //是否有键按下
{
P3=0xfe;
key=P3;
switch (key)
{
case 0xee:return 0;break;
case 0xde:return 1;break;
case 0xbe:return 2;break;
case 0x7e:return 3;break;
}


P3=0xfd;
key=P3;
switch (key)
{
case 0xed:return 4;break;
case 0xdd:return 5;break;
case 0xbd:return 6;break;
case 0x7d:return 7;break;
}


P3=0xfb;
key=P3;
switch (key)
{
case 0xeb:return 8;break;
case 0xdb:return 9;break;
case 0xbb:return 10;break;
case 0x7b:return 11;break;
}


P3=0xf7;
key=P3;
switch (key)
{
case 0xe7:return 12;break;
case 0xd7:return 13;break;
case 0xb7:return 14;break;
case 0x77:return 15;break;
}



} //if end

}



//写显存
void write_dispalybuf(uchar x)
{
if (displaybufpoint==6) return; //6个数码管

displaybufpoint++;
displaybuf[displaybufpoint]=x;

}



void display()
{
uint i;
uchar du;
for(i=1;i<= displaybufpoint;i++)
{
du=displaybuf[i];
display_smg(i,du);

}
}




void display_smg(uchar we,uchar du)
{

uchar code tablewe []={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位 0xfe 第1个数码
uchar code tabledu []={0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d ,
0x7d , 0x07 , 0x7f , 0x6f , 0x77 ,
0x7c , 0x39 , 0x5e , 0x79 , 0x71 };
wela=1;
P0=tablewe[we];
wela=0;
P0=0x00;
dula=1;
P0=tabledu[du];
dula=0;
delay(2);
P0=0xff;


}

void main()
{
uchar key;
ledk=0;
displaybufpoint=0;
while(1)
{
if( key_press() )
{
key=key_scan();
write_dispalybuf(key); //写显存
display();
}
}
}
...全文
344 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
chutianya 2010-04-26
  • 打赏
  • 举报
回复
呵呵 是啊 不过你那个小东西不还是要用个门电路芯片么,我说的也就是外接一块芯片。。。。。
COMPUTERZZZ 2010-04-24
  • 打赏
  • 举报
回复
就一个小应用,不必要用很多东西


chutianya 2010-04-22
  • 打赏
  • 举报
回复
如果可以的话,用一个外围可编程芯片,来控制键盘中断和数码管显示,这样lz可以省去自己扫描键盘的过程,当然这里用的是中断方式,lz用的是扫描方式,扫描方式占用cpu,效率低,单片机外连接一个外围芯片如:CH451或者8279芯片,程序会简单很多很多。。。。。。你这个真够长的。。。。
COMPUTERZZZ 2010-04-22
  • 打赏
  • 举报
回复
有什么好的输入与显示的方法呢,你们?
chutianya 2010-04-21
  • 打赏
  • 举报
回复
在罗嗦一下,我感觉键盘中断扫描行和接受列最好不要用同一个寄存器为好。。。。。(在端口够用的情况下)
chutianya 2010-04-21
  • 打赏
  • 举报
回复
而且你这句sbit d0=P1^0; //锁存口 不知道硬件是连在哪里了。。。下面没用到。。。
chutianya 2010-04-21
  • 打赏
  • 举报
回复
额。。。。洋洋洒洒写了这么多看起来还真麻烦,你这种显示方式我感觉就挺麻烦的,大体了解了你的硬件电路是怎么连的,我仔细看了下,你的问题可能是:

1、你用的P3做键盘的扫描行和接受列,但是你没有把key_press()函数中的P3口设置为输入端 也就是函数开头缺了一句 P3=0xff;
2.你那个displaybufpoint在函数中有点小问题 ,具体修改如下
//写显存
void write_dispalybuf(uchar x)
{

if (displaybufpoint==6) return; //6个数码管

//顺序应该这样,否则第0个数码管没法显示,直接跳到第1个了,数组是从第0位开始的,下面的显示也要进行相应的修改,否则
//是 displaybufpoint++的值

displaybuf[displaybufpoint]=x;
displaybufpoint++;

}



void display()
{
uint i;
uchar du;
//这里进行了修改
for(i=0;i<=(displaybufpoint-1);i++)
{
du=displaybuf[i];
display_smg(i,du);

}
}
3.
switch (key)
{
case 0xee:return 0;break;
case 0xde:return 1;break;
case 0xbe:return 2;break;
case 0x7e:return 3;break;
}
这里的break 是没有必要的,因为执行return后函数uchar key_scan()就已经返回了,因此break可以不写

以前建议仅供参考,希望有所帮助。O(∩_∩)O~

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧