在学习动态数码管之前,我们要先介绍一个延时函数Dealy的编写
打开STC-ISP

这是一个12MZ的单片机关于1ms的延时函数,当单片机执行这段程序时需要1ms才能执行后面的程序,以达到延时1ms的效果。

其他型号的开发板可以在主板中找以下的元器件,单片机的晶振就是上面的数字
普中A7的12Mhz晶振

将我们得到的delay函数稍加修改

    //延时子函数
void Delay(unsigned int xms)
{
    unsigned char i, j;
    while(xms--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}

这个Delay函数中,不同晶振的i、j数值不同,不要盲目修改成一样的,如果对延时的时间不要求太精准,也可以直接拿来使用。

通过上一篇文章,我们可以在八个数码管中选中一个数码管,让其显示0-9的任意数字。

由于74HC138同一时间只能输出一个0,即只可以选择一个数码管,那么想要让8个数码管都亮起来,我们需要其他的办法去解决这个问题,它就是动态数码管。

我们知道电视的画面是闪烁的,如果用手机的视频模式去拍摄电视,那么会有闪烁的现象。

为什么电视的屏幕显示是间断的,而我们看到的确实流畅的画面?因为余晖效应,即人眼的视觉暂留会让消失的画面还停留在我们的脑海里,然后又有新的画面出现衔接上已经消失的画面,从而产生画面流畅的感觉。

根据这个原理,我们让数码管依次快速点亮,只要切换的速度足够快,那么人眼是无法发现其他数码管是熄灭的,看起来就是8个数码管全部点亮。

使用上一篇文章的void Nixie(unsigned char Location,Number)函数,我们可以在主程序main中这样写

    void main()
    {

        while(1)
        {
                Nixie(1,0);    //在数码管的第1位置显示0
                Nixie(2,1);    //在数码管的第2位置显示1
                Nixie(3,2);    //在数码管的第3位置显示2
                Nixie(4,3);    //在数码管的第4位置显示3
                Nixie(5,4);    //在数码管的第5位置显示4
                Nixie(6,5);    //在数码管的第6位置显示5
                Nixie(7,6);    //在数码管的第7位置显示6
                Nixie(8,7);    //在数码管的第8位置显示7
        }
    }

由于是需要依次循环点亮,所以把执行代码放在了while(1)中,这样代码可以一直在while()里面循环执行。

但是这样的代码是在实际使用时会有问题,以下的实际运行该代码的实物图

这个情况是由于数码管是先位选再段选,当新的位选开始而新段选还没有开始,这段时间新的位选执行在旧的段选上面。

解决办法是在段选后加一点延时。(数码管的消影)

    //数码管显示子函数
void Nixie(unsigned char Location,Number)
{
    switch(Location)        //位码输出
    {
        case 8:P2_4=1;P2_3=1;P2_2=1;break;
        case 7:P2_4=1;P2_3=1;P2_2=0;break;
        case 6:P2_4=1;P2_3=0;P2_2=1;break;
        case 5:P2_4=1;P2_3=0;P2_2=0;break;
        case 4:P2_4=0;P2_3=1;P2_2=1;break;
        case 3:P2_4=0;P2_3=1;P2_2=0;break;
        case 2:P2_4=0;P2_3=0;P2_2=1;break;
        case 1:P2_4=0;P2_3=0;P2_2=0;break;
    }
    P0=NixieTable[Number];    //段码输出
        Delay(1);                //显示一段时间
        P0=0x00;                //段码清0,消影
   }

数码管消影后,即可以得到符合预期的实际效果了

        #include <REGX51.H>

    //数码管段码表
    unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

    //延时子函数
    void Delay(unsigned int xms)
    {
        unsigned char i, j;
        while(xms--)
        {
            i = 2;
            j = 239;
            do
            {
                while (--j);
            } while (--i);
        }
    }

    //数码管显示子函数
    void Nixie(unsigned char Location,Number)
    {
        switch(Location)        //位码输出
        {
            case 8:P2_4=1;P2_3=1;P2_2=1;break;
            case 7:P2_4=1;P2_3=1;P2_2=0;break;
            case 6:P2_4=1;P2_3=0;P2_2=1;break;
            case 5:P2_4=1;P2_3=0;P2_2=0;break;
            case 4:P2_4=0;P2_3=1;P2_2=1;break;
            case 3:P2_4=0;P2_3=1;P2_2=0;break;
            case 2:P2_4=0;P2_3=0;P2_2=1;break;
            case 1:P2_4=0;P2_3=0;P2_2=0;break;
        }
        P0=NixieTable[Number];    //段码输出
        Delay(1);                //显示一段时间
        P0=0x00;                //段码清0,消影
    }

    void main()
    {

        while(1)
        {
                Nixie(1,0);    //在数码管的第1位置显示0
                Nixie(2,1);    //在数码管的第2位置显示1
                Nixie(3,2);    //在数码管的第3位置显示2
                Nixie(4,3);    //在数码管的第4位置显示3
                Nixie(5,4);    //在数码管的第5位置显示4
                Nixie(6,5);    //在数码管的第6位置显示5
                Nixie(7,6);    //在数码管的第7位置显示6
                Nixie(8,7);    //在数码管的第8位置显示7
        }
    }

以上就是动态数码管的编写。

最后修改:2025 年 01 月 09 日