基于單片機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;//ÏÔʾСÊýµã
方正常的,但依然不知道是什麼原因。不過效果很好了。