实验设计图(proteus 7.8仿真):
七段数码管有四个引脚 从左到右分别记为 a b c d 引脚输入电平与显示的数字对应关系为:
a b c d 显示
0 0 0 0 0
0 0 0 1 1
0 0 1 0 2
0 1 0 0 3
1 0 0 0 4
......
其实就是把四个引脚看成16进制数的一位显示出来,如果按照图中所画,想要改变数码管的显示数字,只需把一个16进制数移到P0口
MOV P0,#044H ;数码管显示44
MOV P0, #0ABH ;数码管显示AB 注意:汇编语言中16进制数如果以字母开头必须在前面再加一个0
此处顺便说一下,P0口想要输出电平,必须外接上拉电阻,上拉电阻就是一个电源串联一个电阻。
关于代码,我们重点放在与书上不同的地方。
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP abc0 ;书上用的标号是INT0 但是proteus7.8不能用那个标号 可能是命名上的冲突吧
ORG 0013H
LJMP abc1
ORG 0030H
MAIN: SETB PX0
MOV TCON,#00H
MOV IE,#85H
LOOP: MOV P1,#0F3H
MOV R1,#44 ;我循环次数改为了原来的一办 下面的也都是
AP1: LCALL DELAY ;既然循环改为一办,那么延时程序就应该为原来的2倍
MOV A,R1 ;把R1的数字显示到数码管上即可 ,先移到A中
LCALL SHOW ;SHOW函数实现将A中的数字显示到数码管上
DJNZ R1,AP1
MOV R1,#3
AP2: CPL P1.2
LCALL DELAY
MOV A,R1
LCALL SHOW
DJNZ R1,AP2
MOV P1,#0F5H
MOV R1,#3
AP3: LCALL DELAY
MOV A,R1
LCALL SHOW
DJNZ R1,AP3
MOV P1,#0DEH
MOV R1,#24
BP1: LCALL DELAY
MOV A,R1
LCALL SHOW
DJNZ R1,BP1
MOV R1,#3
BP2: CPL P1.5
LCALL DELAY
MOV A,R1
LCALL SHOW
DJNZ R1,BP2
MOV P1,#0EEH
MOV R1,#3
BP3: LCALL DELAY
MOV A,R1
LCALL SHOW
DJNZ R1,BP3
SJMP LOOP
ORG 0200H
abc0: ;中断1
PUSH P1
PUSH 04H ;注意这块与书上不同 必须保存R4 R5 R6的值 也就是04H 05H 06H
PUSH 05H ;不写PUSH R5是因为压栈指令只能加直接地址
PUSH 06H
MOV P1,#0F6H
MOV R2,#15
DELAY0:
LCALL DELAY
MOV A,R2
LCALL SHOW
DJNZ R2,DELAY0
POP 06H
POP 05H
POP 04H
POP 07H ;这里也和书上不一样 POP P1不能把 数据弹到P1 所以先弹到07H 里面
MOV P1,07H
RETI
ORG 0300H
abc1: CLR EA ;中断2
PUSH P1
PUSH 04H
PUSH 05H
PUSH 06H
SETB EA
JNB P3.0,AP0
MOV P1,#0F3H
SJMP DEL1
AP0: JNB P3.1,EXIT
MOV P1,#0DEH
DEL1: MOV R3,#15
NEXT: LCALL DELAY
MOV A,R3
LCALL SHOW
DJNZ R3,NEXT
EXIT: CLR EA
POP 06H
POP 05H
POP 04H
POP 07H
MOV P1,07H
SETB EA
RETI ;中断返回
ORG 0350H
DELAY: MOV R4,#20 ;循环次数改为了原来的2倍
LP1: MOV R5,#50
LP2: MOV R6,#248
NOP
LP3: DJNZ R6,LP3
DJNZ R5,LP2
DJNZ R4,LP1
RET
;A中的数字是16进制的 红绿灯倒计时可没有1A 应变为26
SHOW: MOV B,#10 ;变10进制要除以10 商为第低位 余数为第高位
DIV AB ;A/B 商放到A中 余数放到B中
MOV R7,B
SWAP A ;A的高四位与低四位交换
ADD A,R7 ;商与余数合起来就是所求数
MOV P0,A ;显示到数码管上
RET ;子程序返回
END ;汇编语言结束标志
老铁点个赞~~~