實現一個24小時制的電子鐘程序,在實驗箱的6個數碼管上顯示時分秒(用定時器0中斷更新計時時間,時間值以壓縮BCD碼形式保存在內部RAM的30H31H和32H單元)。
PC機可通過串行口發送要設置的時間給單片機(發送的時間格式為壓縮BCD碼),單片機接收到設置時間后從該時間繼續計時(此為串口調時功能)。
代碼
;數碼管接到CS0,位選地址8001,段選地址8002
;R7:數碼管位,R6:T0中斷次數,R5R4:演示程序,R3:2位BCD轉十進制暫存,R0:指針ORG 0000HLJMP MAINORG 000BH; T0_INTLJMP T0_INTORG 0023H;串口中斷LJMP S_INTORG 0050H
MAIN:;初始化定時器MOV TMOD, #21HMOV TL0, #40536 MOD 256 ;T0定時50msMOV TH0, #40536 / 256MOV TL1, #232;設置波特率為2400MOV TH1, #232SETB EASETB ET0SETB ESSETB TR0SETB TR1MOV PCON, #80H;波特率倍增MOV SCON, #50HMOV R7, #01H;用于循環左移,選擇某個數碼管,從秒的個位開始MOV R6,#40;T0每中斷20次,更新一次數碼管時間MOV R0,#32H;指針 SJMP $T0_INT:MOV TL0, #40536 MOD 256 ;T0重裝初值MOV TH0, #40536 / 256DJNZ R6,T0LOOP;沒到1s,只刷新顯示MOV R6,#40;重裝計數值
T0LOOP1:MOV A,@R0LCALL TBCD2DCJNE R0,#30H,T0L1CJNE A,#23,JIASJMP T0L2T0L1: CJNE A,#59,JIA
T0L2: MOV @R0, #00H;59+1=0DEC R0;如果溢出,則判斷前一個數CJNE R0,#2FH, T0LOOP1JIA:INC A;如果沒溢出,就+1;然后再恢復成BCD碼LCALL D2TBCDMOV @R0, AMOV R0, #32H;恢復R0的數值,準備刷新數碼管
T0LOOP:MOV A,@R0LCALL SHOWMOV A,@R0SWAP ALCALL SHOWDEC R0CJNE R0, #2FH,T0LOOP;刷新顯示MOV R7, #01HMOV R0,#32HRETIS_INT:;串口中斷服務程序JNB RI,$CLR RIMOV A, SBUFLCALL TBCD2DPUSH ACCCLR CCJNE R0,#30H,s1SUBB A,#24SJMP s2
s1: SUBB A,#60
s2: POP ACCJC storeCLR A
store:LCALL D2TBCDMOV @R0,ADEC R0CJNE R0, #2FH,S_INTMOV R0,#32HRETISHOW:;把A的底4位當作BCD碼,送入數碼管顯示,每調用一次,位選左移一次PUSH ACCMOV A,R7MOV DPTR,#8001HMOVX @DPTR,ARL AMOV R7,APOP ACCANL A,#0FHMOV DPTR,#TABMOVC A,@A+DPTR;獲取字形碼MOV DPTR,#8002HMOVX @DPTR,A;寫入字形碼LCALL DELAYCLR AMOVX @DPTR,A;寫入字形碼RETTBCD2D:;把A的內容當作兩位BCD數據,轉換成對應十進制數,并放回APUSH ACC;保護ACC,等下還要用ANL A,#0FH;MOV R3, APOP ACCSWAP AANL A, #0FHMOV B, #10MUL ABADD A,R3;高4位*10+低4位RETD2TBCD:;把A的內容當作十進制數,轉換成對應兩位BCD數據,并放回AMOV B, #10DIV AB;十位在A,個位在BSWAP AORL A, B;數據合并RETDELAY:;10ms則X=23,Y=204MOV R5,#20
D1: MOV R4,#20DJNZ R4,$DJNZ R5,D1RET
; 0 1 2 3 4 5 6 7 8 9
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FHEND