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行。