一、实验目的
1.学习P1口的使用方法。
2.学习延时子程序的设计方法。
3.学习移位指令的用法。
二、实验设备
预装了keil及proteus的PC机。
三、实验内容
八个发光二极管L1-L8分别接在单片机的P1.0-P1.7接口上,输出“0”时,发光二极管亮,发光顺序P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0 亮,循环5次熄灭,程序结束。
电路原理图如下图所示:
四、实验要求
根据实验任务要求,编写源程序。
五、实验源程序及关键步骤
使用keil编辑程序,生成hex文件,打开DSN文件,把hex文件加入到单片机中,观察二极管的闪烁情况是否符合实验要求。
源程序
ORG 0000H ; 起始地址
MOV R3,#5 ; R3 初始化为 5,用来循环计数
START: ; 主程序开始
MOV A,#0FEH ; 把 0FEH 数据放到累加寄存器 A 中
SETB C ; 进位标志位 C 置位
LOOP:
MOV P1,A ; 累加寄存器 A 中的数据放到 P1 端口
LCALL DELAY ; 调用延迟子程序 DELAY
RLC A ; 把累加寄存器 A 左移一位
DJNZ R2,LOOP ; R2 不为零,就跳转到 LOOP 处执行循环
MOV A,#8 ; 将 R2 寄存器的值直接加载到累加寄存器 A 中
RRC A ; 把累加寄存器 A 右移一位(带符号)
LOOP1: ; 第二个循环开始
MOV P1,A ; 把累加寄存器 A 中的数据输出到 P1 端口
LCALL DELAY ; 调用延迟子程序 DELAY
RRC A ; 把累加寄存器 A 右移一位(带符号)
DJNZ R2,LOOP1 ; R2 不为零,跳转到 LOOP1 执行循环
DJNZ R3,START ; R3 不为零,跳转到 START 执行循环
MOV P1,#0FFH ; 输出全高电平信号
LJMP $ ; 程序结束
DELAY: ; 延迟子程序开始
MOV R5,#20 ; R5 寄存器初始化为 20,循环计数
D1: ; 第一个嵌套循环开始
MOV R6,#20 ; R6 寄存器初始化为 20,来循环计数
D2: ; 第二个嵌套循环开始
MOV R7,#248 ; R7 寄存器初始化为 248,用来循环计数
DJNZ R7,$ ; 若R7 不为零,就跳转到 $ 执行循环
DJNZ R6,D2 ; R6 不为零,就跳转到 D2 执行循环
DJNZ R5,D1 ; R5 不为零,跳转到 D1 处执行循环
RET ; 延迟子程序结束
END ; 结束
六、运行结果
七、思考
修改程序,使发光二极管闪亮移位方向改变。
答:使用 RR 指令将累加寄存器 A 右移一位(不带符号的),并使用 RL 指令将累加寄存器 A 左移一位,来改变发光二极管闪亮的移位方向。
ORG 0000H
MOV R3,#5
START:
MOV A,#0FEH
SETB C
LOOP:
MOV P1,A
LCALL DELAY
RR A ; 把累加寄存器 A 右移一位(不带符号的)
DJNZ R2,LOOP ; 如果 R2 不为零,则跳转到 LOOP 标号处继续执行循环
MOV A,#8 ; 把 8 数据移动到累加寄存器 A 中
RL A ; 把累加寄存器 A 左移一位
LOOP1:
MOV P1,A
LCALL DELAY
RL A ; 把累加寄存器 A 左移一位(不带符号的)
DJNZ R2,LOOP1
DJNZ R3,START
MOV P1,#0FFH
LJMP $
DELAY:
MOV R5,#20
D1:
MOV R6,#20
D2:
MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
END
七、实验总结
通过这次广告灯设计与实现的实验,我学到了如何使用 P1 口来控制发光二极管的亮灭,我了解到当 P1 口输出“0”时,对应的发光二极管会亮起,而当 P1 口输出“1”时,对应的发光二极管会熄灭,我需要实现发光二极管按照指定顺序亮起并循环闪烁5次后熄灭,为了实现这个功能,我使用延时子程序来控制发光二极管的亮灭时间,并使用移位指令来改变发光二极管的亮灭顺序。
在编写程序时,我遇到了一些错误,我忘记初始化 R2 寄存器的值,导致循环指令无法正常执行,还有我在移位指令上出现了错误,导致发光二极管的亮灭顺序不正确,经过仔细检查和调试,我找到了错误的原因并进行了改正。我在程序中添加了正确的 R2 寄存器初始化指令,并使用 RR 和 RL 指令分别将累加寄存器 A 右移一位和左移一位,成功改变了发光二极管的亮灭顺序。
这次实验使我更加掌握如何使用 P1 口、延时子程序和移位指令来控制发光二极管的亮灭,也意识到在编写程序时要仔细检查和调试。