在keil编写数码管动态显示的代码的时候,编译没有任何问题,但是在proteus中仿真共阴极数码管时(本人采用的是共阴极数码管,都一样的),出现数码管显示不全或乱码的现象。
我采用的是P0口,P0口接上拉电阻和两个74HC573锁存器。
分两点讲一下,第一个是数码管经管率的原因;在keil编写时代码采用的是先段选后位选的形式,导致数码管的经管率过低;关于经管率大家可以BD一下。代码如下:
void xs()
{
uchar tem=0xfe; //位选信号的初值,低位对应数码管的左端
for(xz=a;xz<z;xz++)
{
switch(xz) //段选
{
case 1:P0=s2[h]; dd=1; dd=0; break;
case 2:P0=s1[h1]; dd=1; dd=0; break;
case 3:P0=s2[fen]; dd=1; dd=0; break;
case 4:P0=s1[fen1]; dd=1; dd=0; break;
case 5:P0=s2[miao]; dd=1; dd=0; break;
case 6:P0=s2[miao1]; dd=1; dd=0; break;
}
P0=tem;wd=1;wd=0; //位选
delay(1); //扫描间隔时间1ms
tem=_crol_(tem,1); //循环左移一位
}
}
仿真效果出现乱码现象,但是在单片机上运行的时候就不会任何问题,就很奇葩;下面是proteus仿真的效果图
第二种就是代码中的控制锁存器使能端的位(高电平开,低电平关),在开、关上与P0的读入存在竞争冒险(说白了就是使能端的开、关和锁存器读入P0的状态这一事件在时间先后上存在不确定关系);常见代码如下:
void xs()
{
uchar tem=0xfe; //位选信号的初值,低位对应数码管的左端
for(xz=a;xz<z;xz++)
{
wd=1;P0=tem;wd=0; //位选
switch(xz) //段选
{
case 1:dd=1;P0=s2[h]; dd=0; break;
case 2:dd=1;P0=s1[h1]; dd=0; break;
case 3:dd=1;P0=s2[fen]; dd=0; break;
case 4:dd=1;P0=s1[fen1]; dd=0; break;
case 5:dd=1;P0=s2[miao]; dd=0; break;
case 6:dd=1;P0=s2[miao1]; dd=0; break;
}
delay(1); //扫描间隔时间
tem=_crol_(tem,1); //循环左移一位
}
}
上面的代码中wd为位选锁存器的使能端,dd为段选锁存器的使能端。流程:wd=1位选打开,P0口的初始状态为0xff此时被读入,然而下一步P0口被赋值0xfe,而后wd=0,锁存器关闭,但是此时无法保证在锁存器关闭之前锁存器读入了0xfe;同理dd=1段选打开,P0为0xfe这时段选的锁存器就被写入了0xfe,你再让P0=s2[h](s2为一个共阴极0~9的数组),这时又到了竞争冒险的时候了,锁存器是先读入s2[h]还是先执行dd=0。仿真结果如下:
最后推荐写法如下:
void xs()
{
uchar tem=0xfe; //位选信号的初值,低位对应数码管的左端
for(xz=a;xz<z;xz++)
{
P0=tem;wd=1;wd=0; //位选
switch(xz) //段选
{
case 1:P0=s2[h]; dd=1; dd=0; break;
case 2:P0=s1[h1]; dd=1; dd=0; break;
case 3:P0=s2[fen]; dd=1; dd=0; break;
case 4:P0=s1[fen1]; dd=1; dd=0; break;
case 5:P0=s2[miao]; dd=1; dd=0; break;
case 6:P0=s2[miao1]; dd=1; dd=0; break;
}
delay(1); //扫描间隔时间
tem=_crol_(tem,1); //循环左移一位
}
}
仿真结果如下图
本人小白,学习ing........