数码管最后一位较亮解决办法

来源:互联网 发布:it男装 编辑:程序博客网 时间:2024/06/05 08:31

相信在单片机入门中,学会点亮数码管是必备的知识,书本上也有详细介绍了使用的方法,然而,在实际的应用中,单片机的代码不仅只有数码管,同时也应会有定时器,I/O口控制等代码,增加代码后数码管的显示就不会变得那么简单,往往会出现最后一位的数码管比其他位的数码管要亮(HC595驱动,动态扫描方式,不讨论其他),下面就让我们来解决这个问题。

一:引起原因

这里先说明原本的数码管代码经过调试可用,排除其他原因(不亮,乱码不讨论),看下面的代码(部分):

if( ((cout==2)&&(pw<=100)&&(pw>=0)) || ((mov==1)&&(cout==0)) ){    Dis_buf[0]=29;    Dis_buf[1]=pw/100%10;    if(Dis_buf[1]==0) Dis_buf[1]=26;    Dis_buf[2]=pw/10%10;    Dis_buf[3]=pw/1%10;     if(regGroup[0]==1)  {Dis_buf[0]=32;}    }else if(pw>100){    Dis_buf[0]=29;    Dis_buf[1]=30;    Dis_buf[2]=30;    Dis_buf[3]=30;    if(regGroup[0]==1)  {Dis_buf[0]=32;}    }Output_595();//这是数码管显示函数

原因:程序执行到Output_595()后,此时数码管应选到最后一位导通,其他位不亮(具体原理参照595驱动方法)。之后程序应继续往下执行或循环,再次到达if代码段时,要计算数值,消耗一定时间,导致程序延迟进入Output_595(),使得最后一位数码管导通时间,比其他位导通时间要长一点,所以会更亮。

//数码管控制码BYTE code SEG7[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};            //0-9的显示控制码,共阳BYTE code Scan_bit[]={0x08,0x04,0x02,0x01};            //4位数码管,有且只有一个亮BYTE Dis_buf[]={0,0,0,0,0};     //显示缓冲区............//数码管显示函数void Output_595(){    BYTE i;    for(i=0;i<4;i++)    {        Input_595(SEG7[Dis_buf[i]]);//显示字符数据        Input_595(Scan_bit[i]);//第i位亮        P_HC595_RCLK=1;        P_HC595_RCLK=0;        Delay595(1);    }    //退出for循环后,此时应为Scan_bit[3],程序继续往下执行,第4位数码管始终选通}

二:解决方法

1)既然从上述知道,最后一位数码管较亮,是程序有一定的延时引起的,在程序中添加延时的方法也不可取。那么我们可以换位思考一下,其他位的数码管亮度是一样的,说明导通时间一样,只要让最后一位导通时间也一样,就可以解决问题了。
2)添加一位数码管:
例如我这里的硬件用的是4位数码管,那么我就用5段数码管的显示程序,即使第5位数码管还是会比其他位要亮,但有什么关系呢?我的硬件实际只有4位数码管,第5位数码管是没有的,但是前面4位数码管亮度都是一样的,这样把第4位数码管更亮的问题转移到不存在的第5位数码管(程序里面有,实际上没有),就可以解决问题了。

BYTE code Scan_bit[]={0x08,0x04,0x02,0x01,0x00};     //5个数码管,显示字符方法同样没变,只需用前面4位,第5位是要用来承担亮度较亮的一位.......for(i=0;i<5;i++){    Input_595(SEG7[Dis_buf[i]]);    Input_595(Scan_bit[i]);    P_HC595_RCLK=1;    P_HC595_RCLK=0;    Delay595(1);}

3)同样,硬件是8位的数码管,在程序中虚拟添加多一位数码管,就可以解决第8位数码管更亮的问题,但要注意的是,按照HC595驱动、动态扫描方式,到第8位数码管亮的时候,传送的数据应是0x01,前面7位数码管应当是灭的状态,接下来应该传送第9位数码管的数据,前面8位数码管应当是灭的状态,但这里一个字节只有8bit控制,所以传送的数据只有0x00才符合要求。

BYTE code Scan_bit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00};.......for(i=0;i<9;i++){    Input_595(SEG7[Dis_buf[i]]);    Input_595(Scan_bit[i]);    P_HC595_RCLK=1;    P_HC595_RCLK=0;    Delay595(1);}

4)注释
1.Scan_bit[]是数码管位选码,即控制其中一个数码管亮/灭。
2.typedef unsigned char BYTE;
3.本例中使用共阳极数码管。

原创粉丝点击