天天看點

單片機之數位管秒表的動态顯示

基于單片機STC89C52RC,使用定時器1,采用動态掃描的方法,在數位管前三位顯示秒表,精确到0.01秒,比如5.03秒,一直循環。

首先設定顯示重新整理頻率為6ms,每2ms重新整理1個數位管,每10ms計算一次時間。

時間顯示的3位采用結構體方式。

首先是電路結構,采用共陰極數位管,74573鎖存器和138譯碼器。

單片機之數位管秒表的動态顯示
然後是程式代碼
/*********************************
@title:Óö¨Ê±Æ÷1ºÍ¶¯Ì¬É¨Ãè·½·¨£¬ÔÚÊýÂë¹ÜµÄÇ°Èýλ
                ÏÔʾ³öÃë±í£¬¾«È·µ½1%Ã룬¼´ºóÁ½Î»ÏÔʾ1%Ã룬
                Ò»Ö±Ñ­»·
@MCU:STC89C52
@name: Wang Yongxing
@date: 2014.08.18
**********************************/

# include "MacroAndConst.h"
# include <stc89c5xrc.h>
# include <intrins.h>


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;//ÏÔʾСÊýµã

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

繼續閱讀