本文主要是介绍51汇编--数码管时钟,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
实现一个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
这篇关于51汇编--数码管时钟的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!