3.10 8只数码管滚动显示数字串

本例电路与此前案例电路相同,但运行时不是一次显示8位不同数字,而是仅显示3位不同数码,且实现了3位数字的滚动显示效果。

程序设计调试与实训:

程序将所有待显示的数码10,10,10,10,10,10,10,10,2,9,8存放于Num数组中,其中10表示黑屏,显示时取码过程如下:

当取前8个数显示时为全黑;

取第2个数开始的8个数时,最后一个是2;

取第3个数开始的8个数时,最后两个是2,9;

取第4个数开始的8个数时,最后三个是2,9,8;

取第5个数开始的8个数时,会发现剩下的只有7个。

为解决这个问题,本例将数组Num看做环形队列,从任何一个元素开始取8个元素时,如果后面不足8个数,程序会自动从前面开始继续取得其余元素。代码中(k + j ) % 11即实现了这个功能,它表示从第k个开始取第j个元素,k+j超过最后位置时会自动从第0个元素开始继续取值。

主程序中使用了双重for循环,内层循环用于8位数码管的扫描显示,包括黑屏部分,外层还添加了for循环,这是为了使每次8位数码的扫描显示重复若干遍,形成一组数字串的保持显示效果。

最后一行代码递增取值起点k,因为取值起点在双重循环后递增,也就是在同一组数字刷新显示若干遍,形成一小段延时后递增,从而产生滚动显示效果。

读者可修改代码,尝试改变滚动方向和滚动显示的数字个数。

源程序代码:

        //-----------------------------------------------------------------
        //  名称: 8只数码管滚动显示数字串
        //-----------------------------------------------------------------
        //  说明: 数码管向左滚动显示3个字符构成的数字串。
        //-----------------------------------------------------------------
        #include <reg51.h>
        #include <intrins.h>
        #define uchar unsigned char
        #define uint  unsigned int
        //数字0~9的数码管段码,最后一个为黑屏的段码
        uchar code DSY_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, 0xFF};
        //程序将下面的数组看做环形队列,显示从某个数开始的8个数(10表示黑屏)
        uchar Num[] = {10,10,10,10,10,10,10,10,2,9,8};
        //-----------------------------------------------------------------
        // 延时
        //-----------------------------------------------------------------
        void DelayMS(uint x)
        {
          uchar i;
          while(x--) for(i = 0; i < 120; i++);
        }
        //-----------------------------------------------------------------
        // 主程序
        //-----------------------------------------------------------------
        void main()
        {
          uchar i,j,k,m;
          P0 = 0xFF;
          P2 = 0x00;
          m = 0x80;
          k = 0;
          while(1)
          {
            //刷新若干次,保持一段时间的稳定显示
            for (i = 0;i < 15;i++)
            {
                for(j = 0; j < 8; j++)
                {
                m = _crol_(m,1);
                P2 = m;
                //采用环形取法,从第k个开始取第j个
                P0 = DSY_CODE[ Num[ (k + j) % 11 ] ];
                DelayMS(2);
                }
            }
            //环形队列首指针k递增,Num的下标范围为0~10,因此对11取余
            k = ( k + 1) % 11;
          }
        }