目录
3.3 静态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
初学单片机,可能存在错误之处,还请各位不吝赐教。
受于文本原因,本文相关实验工程无法展示出来,现已将资源上传,可自行下载。