一、原理总结
- 利用两个寄存器R4和R5来存储两个数码管的显示效果,R4是前一个数码管显示所需,而R5是后一个数码管显示所需,利用左移操作RLC来使之每一位被依次输入到C中,然后将C输入到LED中(当LED每位都有数据时,数码管才会显示),利用停顿函数使数码管上数字停留一段时间。
二、程序分析
- 以下为全部代码,之后会进行具体分析
总体代码
;==================================================================== ; Main.asm file generated by New Project wizard ; ; Created: 周一 九月 19 2022 ; Processor: AT89C51 ; Compiler: ASEM-51 (Proteus) ;==================================================================== $NOMOD51 $INCLUDE (8051.MCU) ;==================================================================== ; DEFINITIONS ;==================================================================== ;==================================================================== ; VARIABLES ;==================================================================== ;==================================================================== ; RESET and INTERRUPT VECTORS ;==================================================================== ; Reset Vector org 0000h jmp Start ;==================================================================== ; CODE SEGMENT ;==================================================================== org 0100h TAB : DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H PAUSE: ;停顿函数 MOV R1,#255;R1是第一层嵌套循环 D1:MOV R2,#255;R2是第二层嵌套循环 D2:DJNZ R2,D2;当R2不为0时跳转,为0时不跳转,执行DJNZ R1,D1使得R1- - DJNZ R1,D1;当R1不为0时跳转,为0时不跳转 RET LED: MOV R0,#8 ;将8赋值给R0,8位左移 MOV A,R5 ;R5代表右边的LED的数 MOVC A,@A+DPTR ;A是偏移地址,是从DPTR中寻址 LOOP1: RLC A ;A左移 CLR P1.4 MOV P1.5,C SETB P1.4 DJNZ R0,LOOP1 MOV R0,#8 MOV A,R4 MOVC A,@A+DPTR LOOP2: RLC A CLR P1.4 MOV P1.5,C SETB P1.4 DJNZ R0,LOOP2 MOV R6,#0 S1:LCALL PAUSE INC R6 CJNE R6,#10,S1 RET START:MOV A,#00H MOV p0,A MOV DPTR,#TAB MOV R4,#0 MOV R5,#0 A1:MOV C,P1.0 JC XUNHUAN MOV C,9 JC FUWEI INC R5 CJNE R5,#15,XUNHUAN MOV R5,#0 INC R4 CJNE R4,#15,XUNHUAN JMP FUWEI XUNHUAN: LCALL LED JMP A1 FUWEI: MOV R4,#0 MOV R5,#0 JMP A1 JMP START ;==================================================================== END
数组存值:
- TAB 是用来存储0-15这16个数据,之后使用A来寻址
TAB : DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
停顿函数:
- R1是第一层嵌套循环,R2是第二层嵌套循环,当R2不为0时跳转,为0时不跳转,执行DJNZ R1,D1使得R1- -,当R1不为0时跳转,为0时不跳转。
PAUSE: ;停顿函数 MOV R1,#255;R1是第一层嵌套循环 D1:MOV R2,#255;R2是第二层嵌套循环 D2:DJNZ R2,D2;当R2不为0时跳转,为0时不跳转,执行DJNZ R1,D1使得R1- - DJNZ R1,D1;当R1不为0时跳转,为0时不跳转 RET
数码管亮灯函数
- LED中的内容:
- 将8赋值给R0,使用R0来实现8位右移
- 将R5赋值给A,而R5代表的是右边的数码管,R5共八位,使用R0来使之每位被传输到数码管中。
- MOVC A,@A+DPTR 是将A在DPTR中寻址,之后回赋值给A。
LED: MOV R0,#8 ;将8赋值给R0,8位右移 MOV A,R5 ;R5代表右边的LED的数 MOVC A,@A+DPTR ;A是偏移地址,是从DPTR中寻址
- LOOP1中的内容:
- RLC 是带进位的循环左移,RLC A 即将A的内容左移一位,将进位位C中的值移到累加器A的最低位,A的最高位移到C里。若有A=01000001,C=1,则执行 RLC的话:A=10000011,C=0(A的最高位移到C,C原值移到A最低位)。
- RL 是带进位的循环左移,RL A 即将A的内容左移一位,将进位位C中的值移到累加器A的最低位,A的最高位不移到C里,若有A=01000001,C=1,则执行RL的话:A=10000010,C=1(A所有位左移一位,最低位补零,C不参加移位操作,保持原值不变)
- RLC之后三行是将数据放入数码管中的操作,不过多赘述
- DJNZ R0,LOOP0 是将 R0– 过后看是否为0,若不为零则跳转,若为0则执行下面的操作
C=1,A=55H,RLC A后则为:C=0 A=ABH,即:1 01010101变为:0 10101011
LOOP1: RLC A ;A左移 CLR P1.4 ;下面三行是对LED进行输入 MOV P1.5,C SETB P1.4 DJNZ R0,LOOP1 MOV R0,#8 MOV A,R4 MOVC A,@A+DPTR
LED: MOV R0,#8 ;将8赋值给R0,8位右移 MOV A,R5 ;R5代表右边的LED的数 MOVC A,@A+DPTR ;A是偏移地址,是从DPTR中寻址 LOOP1: RLC A ;A左移 CLR P1.4 ;下面三行是对LED进行输入 MOV P1.5,C SETB P1.4 DJNZ R0,LOOP1 MOV R0,#8 MOV A,R4 MOVC A,@A+DPTR LOOP2: RLC A CLR P1.4 MOV P1.5,C SETB P1.4 DJNZ R0,LOOP2 MOV R6,#0 S1:LCALL PAUSE INC R6 CJNE R6,#10,S1 RET
START 部分:
- 首先对图中上面的数码管进行归0处理,然后 MOV DPTR,#TAB 将TAB这个数组的首地址给予DPTR,后续寻址使用,将R4 与 R5 进行初始化,赋值为0,
- C中一开始存储的是 p1.0 (其中存储的是开关数值,为1的话进行累加,为0的话保持不变)如C为1则直接执MOV C,9,若C为0的话跳转XUNHUAN,保持当前数字
- 之后C中存储的是9号端口传入的数据,9号段口控制复位(9号端口为1时执行之后指令,为0时执行FUWEI)
- 之后正式执行,R5从0开始累加,累加够16使R4加一,当R5小于等于15时执行数码管显示函数,大于15时执行R4++
START: MOV A,#00H MOV p0,A MOV DPTR,#TAB MOV R4,#0 MOV R5,#0 A1: MOV C,P1.0 JC XUNHUAN MOV C,9 JC FUWEI INC R5 CJNE R5,#15,XUNHUAN MOV R5,#0 INC R4 CJNE R4,#15,XUNHUAN JMP FUWEI
XUNHUAN 和 FUWEI 部分:
- XUNHUAN 使用LED函数,亮数码管,之后跳转A1中。
- FUWEI 给与R4与R5赋值为0,之后跳转到A1中
XUNHUAN: LCALL LED JMP A1 FUWEI: MOV R4,#0 MOV R5,#0 JMP A1