效果图:
方法一: 写出所有亮灯可能,然后循环
MAIN:
MOV P2, #11111110B
LCALL DELAY
MOV P2, #11111101B
LCALL DELAY
MOV P2, #11111011B
LCALL DELAY
MOV P2, #11110111B
LCALL DELAY
MOV P2, #11101111B
LCALL DELAY
MOV P2, #11011111B
LCALL DELAY
MOV P2, #10111111B
LCALL DELAY
MOV P2, #01111111B
CALL DELAY
LJMP MAIN
DELAY:
MOV R7, #3 ;@11.0592MHz
D1:
PUSH 30H
PUSH 31H
MOV 30H, #180
MOV 31H, #68
NEXT:
DJNZ 31H, NEXT
DJNZ 30H, NEXT
POP 31H
POP 30H
DJNZ R7, D1
RET
END
这种方式比较好理解一些,修改R7的立即数可以更改流水灯的快慢
方法二:用一个变量接收数据,然后左移,反复循环即可
MOV A,#0FEH
MAIN:
MOV P2,A
LCALL DELAY
RL A ;将A进行左移
SJMP MAIN
DELAY:
MOV R7, #3
D1:
PUSH 30H
PUSH 31H
MOV 30H, #180
MOV 31H, #68
NEXT:
DJNZ 31H, NEXT
DJNZ 30H, NEXT
POP 31H
POP 30H
DJNZ R7, D1
RET
END
相比之下方法二会更加灵活一些,修改变量A的值可以更改流水灯模式,修改R7的值可以控制流水灯快慢
方法三:数组点灯。将所有的亮灯可能转成十六进制放在数组里面,然后依次读取数组里面的十六进制数,将读取到数赋值给P2引脚。
MAIN:
MOV R1,#8 ;等下用来记录循环了次数,因为有个灯,所以赋值为8
MOV R2,#00H ;用来存储偏移量
MOV DPTR,#TAB ;将数组的首地址用DPTR来记录
UP:
MOV A,R2 ;将当前偏移量赋值给变量A
MOVC A,@A+DPTR ;MOVC A,@A+DPTR是读取地址为A+DPTR存储单元的内容。
MOV P2,A ;读取到的数组内容赋值给P2引脚
LCALL DELAY ;LCALL的意思是调用,调用DELAYMS
INC R2 ;inc代表加一(偏移量加一)
DJNZ R1,UP ;将R7减一,非0则跳转到UP,为0则执行下一句(可以执行8次)
SJMP MAIN ;SJMP是跳转的意思,跳转到UP0的位置
DELAY:
MOV R7, #3 ;#3代表延时三百毫秒(晶振是11.0592HZ)
D1:
PUSH 30H
PUSH 31H
MOV 30H, #180
MOV 31H, #68
NEXT:
DJNZ 31H, NEXT
DJNZ 30H, NEXT
POP 31H
POP 30H
DJNZ R7, D1
RET
TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,7FH ;定义了一个数组
END
注:数组一般放在程序的末尾,而不是像c语言那样放在程序的开头。