8路LED的BCD码二进制加法器
申明:本程序绝对原创,请转载本博文注明出处:http://blog.csdn.net/fly928sky/article/details/7672390
1.本程序电路图,请参考http://blog.csdn.net/fly928sky/article/details/7645591
2.本程序的原理是:BCD码显示数加1用DA指令调整及H位、L位分离,然后分别取H位和L位的LED码值相与,最后送入P0进行显示。
注:其他的几种算法和 “8路LED的二进制加法器”的算法差不多。
“8路LED的二进制加法器”的算法请参考:a.http://blog.csdn.net/fly928sky/article/details/7665905 b.http://blog.csdn.net/fly928sky/article/details/7666037
代码如下:
ORG 0000H
LJMP START
;程序开始
START: ACALL INIT
;主程序
Main: ACALL DisplayBCD3
LJMP Main
DisplayBCD:
ACALL NumInit
BCD: MOV R0,#10H ;H/L位DP高位暂存
MOV R1,#00H ;L位DP低位暂存
MOV R2,#13H ;H位DP低位暂存
BCDInit:
ACALL NumHL
BCDMain:
MOV A,1016H ;高位暂存累加器A
CJNE A,#0AH,BCDLoop ;A<10转移到AddLoop,且CY=1;A=0继续向下执行
ACALL NumInit
BCDLoop:
JNC Add3Init ;CY!=0继续向下执行
SETB P1.2
ACALL SetP0
CLR P1.2
ACALL DELAY
MOV A,1015H
ADD A,#01H
DA A ;DA指令只能用在BCD码ADD运算之后调整
MOV 1015H,A
LJMP BCDInit
RET
NumInit: ;初始化
MOV 1015H,#00H ;显示数
MOV 1016H,#00H ;高位
MOV 1017H,#00H ;低位
RET
NumHL: ;显示数分出高位和低位
MOV A,#0xF0 ;存高位到1016H
ANL A,1015H
RR A
RR A
RR A
RR A
MOV 1016H,A
MOV A,#0x0F ;存低位到1016H
ANL A,1015H
MOV 1017H,A
RET
SetP0: ;设置P0端口值
MOV DPH,R0 ;取L位值
MOV A,R1
ADD A,1017H
MOV DPL,A
CLR A
MOVC A,@A+DPTR
MOV R3,A
MOV DPH,R0 ;取H位值
MOV A,R2
ADD A,1016H
MOV B,#0AH
DIV AB
MOV A,B
ADD A,#0AH
MOV DPL,A
CLR A
MOVC A,@A+DPTR
ANL A,R3 ;综合取值送入P0口
MOV P0,A
RET
;初始化函数
INIT: SETB P1.3 ;关闭点阵
MOV P0,#00H
CLR P1.3
SETB P1.1 ;关闭数码管
MOV P0,#0FFH
CLR P1.1
RET
;延时函数
DELAY: MOV R5,#20
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
;数据表
ORG 1000H
Table1: DB 0FFH,07FH,0BFH,03FH,0DFH,05FH,09FH,01FH,0EFH,06FH ;L位,即开发板上面右边4个LED灯的BCD码0~9
Table2: DB 0F7H,0FBH,0F3H,0FDH,0F5H,0F9H,0F1H,0FEH,0F6H,0FFH ;H位,即开发板上面左边4个LED灯的BCD码1~9 0
END ;程序结束
对本程序的思考:
(a)倘若对28行至31行的BCD码数加1调整使用如下代码:
INC 1015H
MOV A,1015H
DA A
MOV 1015H,A
这时的对BCD码的DA调整就会生成乱码,请亲们务必注意。
(b)利用DA指令调整BCD码的好处是,显示数的H位和L位很好分离(用0xF0和0x0F分别与BCD码显示数相与,就可以对应分离出H位和L位)。但是分离出的H位需要移位后方可变成L位的形式。代码见NumHL函数。
(c)此例中Table2也可以修改成Table1一样的从0至9的形式,只需修改R2初值为零,并且能删除程序中的68行至70行。