一、 实验要求
- 在单片机开发板的LED灯D1~D8上实现跑马灯。
- 单片机芯片选择AT89C51,晶振频率设为12MHz。
- 跑马灯点亮的时间间隔约为1s。
- 用P83的延时子程序实现。
- 实现LED数码管跑马灯。
二、 实验设计
1.整体思路
- 程序入口位于 0000H,跳转到 MAIN 主程序开始执行。
- 在 MAIN 主程序中,首先将A寄存器初始化为 0xFE(1111 1110B),即只有最高位灯亮,然后初始化循环计数器 R2 为 8,用于控制循环次数。
- 进入 LOOP 循环,在循环中通过移位和赋值操作实现LED灯的流水灯效果,并在每次移动后调用延时函数 DELAY 控制延时,同时使用 DJNZ 指令控制循环次数。
- 延时函数 DELAY 使用三个嵌套的循环来实现较长的延时。
2.流程图
3.主要模块设计思路及分析
(1)MAIN 模块:
- 主要负责初始化和控制循环,通过移位和循环控制LED灯的流水灯效果。
- 循环中的 RRC A 和 JNC OFF 部分用于实现LED灯的右移效果,当最低位被移出时,跳过熄灭当前最高位灯的步骤。
- 使用 SETB C 设置进位标志位C,用于判断是否需要熄灭当前最高位灯。
(2)DELAY 模块:
- 用于控制延时,通过嵌套的三个循环实现较长的延时效果。
- 延时函数 DELAY 使用多层嵌套循环来实现较长的延时,其中循环次数通过 R5、R6 和 R7 寄存器进行控制。
三、 实现效果
四、总结
- 本次实验中最难的部分我觉得是在于1s的延迟,最后思考了很久决定使用通过嵌套循环和计数器来实现精确的延时。
- 关于D1~D8的流水灯效果一开始也没有头绪,最后决定参考书上的汇编代码,采用通过移位操作和端口控制实现流水灯的效果。
附录:
ORG 0000H
AJMP MAIN
MAIN:
MOV A, #0FEH ; 初始值为1111 1110B,只有最高位灯亮
MOV R2, #08H ; 初始化循环计数器,用于控制循环次数
LOOP:
MOV P2, A ; 将A寄存器中的值写入P2口(控制LED灯的亮灭)
ACALL DELAY ; 调用延时函数DELAY,控制延迟时长
RRC A ; 右移一位,将当前亮灯位置右移一位
JNC OFF ; 如果最低位被移出,则跳过熄灭当前最高位灯的步骤
SETB C ; 设置进位标志位C
OFF:
DJNZ R2, LOOP ; 循环R2次,控制流水灯循环次数
DELAY:
MOV R5, #100
LOOP1:
MOV R6, #20
LOOP2:
MOV R7, #248
LOOP3:
DJNZ R7, LOOP3
DJNZ R6, LOOP2
DJNZ R5, LOOP1
RET
END