名称:51单片机之数码管显示实验

/*
名称:51单片机之数码管显示实验
说明:对于数码管来说,其本质上可以理解为按照一定规则组合的多个二极管。其使用只需按照特定规则显示对应的二极管即可。要稍微注意一点的就是多个数码管的显示分为静态显示和动态显示。静态显示就是每个二极管显示的内容是一样的,通过片选信号来决定是哪个二极管该显示。动态数码管,即利用人眼的视觉停留效果,快速扫描,快速显示每个数码管的内容,使得每个数码管看起来好像是一起显示的一样。
本实验编写了几个数码管显示的简单程序。在此不做赘述了。

*/

#include <reg52.h>

#define uchar unsigned char


//共阳极段码(a在高位,dp在低位)
uchar code _data[16] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,
                                                0x11,0xC1,0x63,0x85,0x61,0x71
                                                };

//共阳极段码(a在低位,dp在高位)
uchar code _data1[16] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,
                                                0x83,0xC6,0xA1,0x86,0x8E
                                                };                                              

//延时函数
void delay_ms(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}


//一位数码管循环显示0-F(共阳极)
void OneNixieTube()
{
    uchar i = 0;

    while(1)
    {
            for(i = 0;i<16;++i)
            {
                P2 = _data1[i];         
                delay_ms(1000);
            }



    }
}



//静态数码管循环显示0-8
void StaticNixieTube()
{
    uchar i = 0,temp = 0;
    while(1)
    {
            for(i = 0;i<16;++i)
            {

                //片选部分
                if(i%8 == 0)
                    temp = 0x01;
                else
                    temp = temp<<1;
                P0 = ~temp;                    //P0为片选输出端口,低电平有效
                //显示部分
                P2 = ~_data1[i];           //P2为显示输出端口


                delay_ms(1000);
            }
    }

}


//动态数码管显示(0-7,8-F,8个数码管分两次显示)
void DynamicNixieTube()
{
    uchar i = 0;
    unsigned int delay_time = 0;        //0-7 8-F每段的延时时间

    uchar CS[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};        //片选码

        while(1)
        {

            if(delay_time++ < 250)
            {
                //0-7段显示
                for(i = 0;i < 8;++i)
                {
                    P0 = CS[i];
                    P2 = ~_data1[i];

                    delay_ms(1);        //延时极小的时间间隔,人眼察觉不出来

                }
            }
            else if(delay_time++ < 500 )        //???都是循环250次,为什么0-7段显示的时间长于8-F段显示的时间???
            {
                //8-F段显示
                for(i = 0;i < 8;++i)
                {
                    P0 = CS[i];
                    P2 = ~_data1[i+8];

                    delay_ms(1);        //延时极小的时间间隔,人眼察觉不出来

                }

            }
            else
                delay_time = 0;                 //重新置零

        }
}


//数码管显示指定时间格式为 HH-MM-SS
void DisplayTime(uchar hour,uchar min,uchar sec)
{
    uchar time[8] = {0};
    uchar i = 0,j = 0;
    uchar CS[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};        //片选码


    //获取时间的每位信息
    if(hour >= 0 && hour <=23 )
    {
            time[0] = hour / 10;
            time[1] = hour % 10;

            time[2] = ':';
    }


    if(min >= 0 && min <= 59)
    {
        time[3] = min /10;
        time[4] = min % 10;

        time[5] = ':';

    }

    if(sec >= 0 && sec <= 59)
    {
        time[6] = sec / 10;
        time[7] = sec % 10;
    }


    //显示部分
    for(i = 0;i<7;++i)
    {
            for(i = 0;i < 8;++i)
                {
                    P0 = CS[i];             //片选

                    //显示时间
                    if(i != 2 && i != 5)
                    {
                        j = time[i];
                        P2 =  ~_data1[j];
                    }
                    else                        //显示分隔符‘-’
                    {
                        j = 0xBF;
                        P2 = ~j;
                    }

                    delay_ms(1);        //延时极小的时间间隔,人眼察觉不出来

                }
    }



}


int main()
{
    //  OneNixieTube();
    //  StaticNixieTube();
    //DynamicNixieTube()
        //DisplayTime(12,40,56);




    return 0;
}
相关推荐
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页