一、题目
静态LED显示
二、要求
1、画出流程图
2、编写源程序并进行注释
3、记录实验过程
4、记录程序运行结果截图
三、过程及结果记录
按照思路搭建电路图1如下:
编辑
图1:实验电路图
7SEG2 为十位显示数码管,7SEG1 为个位显示数码管,KEY_LOAD:倒计时初值按钮,KEY_START:倒计时启动按钮
功能:KEY_LOAD按钮被按下时,加载倒计时初值(10S);当按下KEY_START按钮时,开始倒计时,每过1S,计数器减1,直到见到“00”为止。减到“00”时,使P3.0引脚上的LED按10Hz频率进行闪烁,直到再次按下KEY_LOAD按钮,才重新加载初值,并熄灭LED;再次按下KEY_START按钮又一次开始倒计时,如此反复
1. 使用Proteus搭建实验电路图如上,并将其保存为staticLED_self.DSN 文件。
2. 编写控制源程序,将其保存为staticLED_self.asm。
3. 程序编译:单击上方工具栏的source,然后build all,将asm文件编译成hex文件。将可执行文件hex写入芯片
4. 执行仿真过程观察秒表程序功能是否正确。实验结果如下图所示:
编辑
图2:装载初值并启动
编辑
图3:减到00,LED灯闪烁
四、流程
实验流程图如下所示:
编辑
图4:实验流程图
1.确定两个锁存器的地址是0FE00H和0FD00H并添加两个显示数码管。按照要求将P1.0作为start的输入,P1.1作为load的输入。
2.实验开始,判断P1.1口是否按下,则载入初值,并让两个数码管显示初值。
3.判断P1.0是否按下,若是按下就开始执行计数;若是没有按下,便返回初始状态,等待P1.1按下。
4.计数完成后,等待载入命令,若无,则停留的等待,若有,就开始下一轮循环。
5.显示数码管的控制命令可以先将其写好,存在内存中,然后使用相对寻址对这段连续地址进行数据访问,赋给锁存器。将数码管的控制信号写在内存中,并且按照1到9的顺序存放。用两个内存单元存放十位与个位的数字,该数字也就对应控制信号表格中的偏移量。即数字为n的时候,偏移n进行查表,将n代表的控制信号交给数码管。
6.开始先判断置数操作,调用初始化10的指令。将个位数字置0,十位数字置1,那么他在表格中的偏移分别是0和1,使用movc指令查表得到相应的控制信号,交给锁存器,也就是数码管。然后判断start信号,若有则开始执行计数,若没有则跳回开始,等待新的指令。当有start信号,则调用显示程序,进行数码显示。
7.调用调整程序计数。将个位的数,即30H内存单元中对应的数减1,然后和-1比较,要是不等于-1,那就说明原来个位还没有到0,不对十位操作。若是为-1,说明原来个位到了0,那便把十位减1,并将个位置9。再比较十位,若是为-1,说明原来是0,那么表明计数器到了00,计数结束。
8.执行完调整之后,先不改变显示,而是调用延时程序等待一段时间之后,在刷新数码管的显示。
五、源代码
ORG 0000H ; 在内存的0地址处就强制转到主程序上去,绕过中断程序 AJMP MAIN ; 无条件的转移到主程序
ORG 0030H
MAIN: ;定义主程序
MOV SP,#60H ;设置栈指针
CLR F0 ; 使用CLR位操作指令将PSW.6用户标志位清零
SETB P3.0 ;设置LED端口,使LED灭
LCALL INITIALIZE0 ; 调用子程序,显示为00
LOOP: ; 定义循环
JB P1.1,GOON ; 位操作指令,判断P1.1口值,若为0,则说明KEY_LOAD按键按下,继续执行下面的程序,否则就是没按下跳转至GOON ,判断是否有start命令
WAIT0: LCALL INITIALIZE ;显示初值为10
CLR F0 ;将用户标志位置零
GOON: JB P1.0,LOOP ; 判断P1.0口值,若为0,则说明KEY_START按下,开始计时,否则便跳回开始重新判断P1.1
NEXT1:
LCALL DISPLAY ; 调用子程序DISPLAY
LCALL DELAY1S ; 调用子程序DELAY1S
LCALL ADJUST ; 调用调整子程序ADJUST
JB F0,SHINING ;若计时器寄存器为0,则调用子程序SHINING,使其闪烁
LJMP NEXT1 ; 当计数器不为零,则继续循环
SHINING:
CLR P3.0 ;将P3.0置零,点亮LED灯
LCALL DELAY50MS ; 调用延时50MS子程序
SETB P3.0 ; 将P3.0置1,此时LED灭
LCALL DELAY50MS ; 调用延时50ms子程序
JB P1.1,SHINING ; 判断KEY_LOAD是否按下
SJMP WAIT0 ; 若按下,则跳转回开始
DELAY50MS: ; 定义延时50MS子程序
MOV R6,#100 ; 外层循环为100次
DL: MOV R5,#250 ; 内层循环为250次
DJNZ R5,$ ;两个时钟周期
DJNZ R6,DL ; 两个时钟周期
RET ;可计算得知共延时(1μs*2*250+2+1)*100+1=50.30ms
DELAY1S:MOV R7,#10 ;延时1S子程序
DL2:MOV R6,#200 ; 第二层循环200次
DL1:MOV R5,#250 ; 第三层循环250次
DJNZ R5,$ ;两个时钟周期
DJNZ R6,DL1 ; 两个时钟周期
DJNZ R7,DL2 ; 两个时钟周期
RET ;可计算得知共延时((1μs*2*250+1+2)*200++2+1)*10+1=1s
ADJUST:
DEC 30H ; 个位减一
MOV A,30H ; 比较个位,若个位不为-1,则返回
CJNE A,#-1,GOTORET ;若个位为-1(原来为0),则置9
MOV 30H,#9 ; 直接寻址操作,直接赋值9
DEC 31H ; 十位减一
MOV A,31H
CJNE A,#-1,GOTORET ; 若十位不为-1,则返回
SETB F0 ;若十位为-1,则说明为00,即计数结束。将计时器寄存器置1
RET
GOTORET:RET
INITIALIZE0:
MOV 30H,#0 ;初始化
MOV 31H,#0
CLR A
MOV DPTR,#TABLE ;将表格的地址交给DPTR
MOVC A,@A+DPTR ;访问片外ROM,所以用movc
MOV DPTR,#0FE00H ;使DPTR指向锁存器
MOVX @DPTR,A ;给锁存器进行赋值
MOV A,#0 ; 清空
MOV DPTR,#TABLE ;给内存器赋值0
MOVC A,@A+DPTR ;将数据付给A寄存器
MOV DPTR,#0FD00H ;给锁存器赋值
MOVX @DPTR,A ;将数付给内存单元
RET
INITIALIZE: ;初始化显示为10子程序
MOV 30H,#0 ;给内存地址30清零
MOV 31H,#1 ;给内存地址31H置1
CLR A
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV DPTR,#0FE00H
MOVX @DPTR,A ;将控制信号送给锁存器
MOV A,#1 ; 偏移地址加1,控制第二个数码管显示1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV DPTR,#0FD00H
MOVX @DPTR,A
RET
DISPLAY: ;刷新子程序
MOV A,30H
MOV DPTR,#TABLE ; 让DPTR指向表格首地址
MOVC A,@A+DPTR ; 读取第一个数字
MOV DPTR,#0FE00H ; 将该控制信号送给锁存器
MOVX @DPTR,A
MOV A,31H
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV DPTR,#0FD00H ; 读取控制信号送给锁存器
MOVX @DPTR,A
RET
TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H ; 定义表格,END
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)