单片机之数码管秒表的动态显示

基于单片机STC89C52RC,使用定时器1,采用动态扫描的方法,在数码管前三位显示秒表,精确到0.01秒,比如5.03秒,一直循环。

首先设置显示刷新频率为6ms,每2ms刷新1个数码管,每10ms计算一次时间。

时间显示的3位采用结构体方式。

首先是电路结构,采用共阴极数码管,74573锁存器和138译码器。

单片机之数码管秒表的动态显示_第1张图片

然后是程序代码


/*********************************
@title:Óö¨Ê±Æ÷1ºÍ¶¯Ì¬É¨Ãè·½·¨£¬ÔÚÊýÂë¹ÜµÄÇ°Èýλ
                ÏÔʾ³öÃë±í£¬¾«È·µ½1%Ã룬¼´ºóÁ½Î»ÏÔʾ1%Ã룬
                Ò»Ö±Ñ­»·
@MCU:STC89C52
@name: Wang Yongxing
@date: 2014.08.18
**********************************/

# include "MacroAndConst.h"
# include 
# include 


sbit LE_74573 = P1^0;
sbit LSA_74LS138 = P2^2;
sbit LSB_74LS138 = P2^3;
sbit LSC_74LS138 = P2^4;


//¹²ÒõÊýÂë¹Ü0-F dp-a£º0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
char SegLed[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                                0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void InitTimer1(void);
void SegLedDisplay(void);

struct
{
    char sec0;//Ãë±í×î¸ßλ
    char sec1;//Ãë±íСÊýµãºóµÚһλ
    char sec2;//Ãë±íСÊýµãºóµÚ¶þλ
}sec;

uchar num = 7;
char ms10flag = 0;


int main(void)
{
    
    
    InitTimer1();//¶¨Ê±Æ÷0³õʼ»¯
    EA = 1;//ʹÄÜϵͳ×ÜÖжÏ
    LE_74573 = 1;
    sec.sec0 = 0;
    sec.sec1 = 0;
    sec.sec2 = 0;
    while(1)
    {}    
    return 0;
}

void InitTimer1(void)
{
    TMOD = 0x10;//¶¨Ê±Æ÷0£¬16λ¶¨Ê±Æ÷
    TH1 = 0xF8;//¶¨Ê±Îª2ms£¬50*1000us
    TL1 = 0x2F;
    ET1 = 1;    //ʹÄܶ¨Ê±Æ÷0µÄÖжÏ
    TR1 = 1;//¶¨Ê±Æ÷0¿ªÊ¼ÔËÐÐ
}

void Timer1Isr() interrupt 3 using 1
{
    TH1 = 0xF8;//¶¨Ê±Îª2ms£¬50*1000us
    TL1 = 0x2F;
    ms10flag++;
    if(ms10flag == 5)
    {
        ms10flag = 0;
        P0 = 0X00;//Çå³ýÏÔʾ
            if(++sec.sec2 == 10)//¼ÆËãʱ¼ä
            {
                sec.sec2 = 0;
                if(++sec.sec1 == 10)
                {
                    sec.sec1 = 0;
                    if(++sec.sec0 == 10)
                    {
                        sec.sec0 = 0;
                    }
                }
            }        
    }    
    SegLedDisplay();
}    


void SegLedDisplay(void)
{

    
        switch(num)
        {
    //        case 0:LSC_74LS138 = 0;LSB_74LS138 = 0;LSA_74LS138 = 0;break;
    //        case 1:LSC_74LS138 = 0;LSB_74LS138 = 0;LSA_74LS138 = 1;break;
    //        case 2:LSC_74LS138 = 0;LSB_74LS138 = 1;LSA_74LS138 = 0;break;
    //        case 3:LSC_74LS138 = 0;LSB_74LS138 = 1;LSA_74LS138 = 1;break;
    //        case 4:LSC_74LS138 = 1;LSB_74LS138 = 0;LSA_74LS138 = 0;break;
            case 5:
            {
                LSC_74LS138 = 1;
                LSB_74LS138 = 0;
                LSA_74LS138 = 1;
                P0 = SegLed[sec.sec2];
                break;
            }
            case 6:
            {
                LSC_74LS138 = 1;
                LSB_74LS138 = 1;
                LSA_74LS138 = 0;
                P0 = SegLed[sec.sec1];
                break;
            }
            case 7:
            {
                LSC_74LS138 = 1;
                LSB_74LS138 = 1;
                LSA_74LS138 = 1;    
                P0 = SegLed[sec.sec0];
                P0 |= 0x80;//ÏÔʾСÊýµã
                break;
            }
        }    
        if(--num == 4)
        {
            num = 7;
        }
}



不知怎么回事,keil的代码中文注释全部成了乱码。

中间出现了一个问题,为了显示小数点,最高位显示使用了语句

P0 = 0x80|SegLed[sec.sec0];

最高位显示秒的数码管,在0,6,9时显示不正常,全闪

后来更改了语句为

                P0 = SegLed[sec.sec0];
                P0 |= 0x80;//ÏÔʾСÊýµã

方正常的,但依然不知道是什么原因。不过效果很好了。


你可能感兴趣的:(单片机,数码管,动态扫描)