一、 实验要求
- 熟练掌握循环程序设计的基本方法
- 熟练掌握单片机外部存储空间的访问方法
二、 实验设计
1.整体思路
先初始化一些寄存器和数据存储位置,然后调用两个子程序Procedure1和Procedure2,分别从SRC复制数据到DEST,一个从开头到末尾,另一个从末尾到开头。每个子程序在复制数据时使用循环,直到达到指定的复制次数(由NUM控制)。程序最后通过END标志结束。
2.流程图
3.主要模块设计思路及分析
(1)Procedure1子程序
- Procedure1 负责向起始地址为SRC的片内存储中,顺序写入NUM个单字节数(数值不限),并以$字符(ASCII码)结尾。。
- R0 用于计数,R1 存储 SRC 的地址。
- 使用循环,CJNE 指令检查 R0 是否等于 NUM,如果等于,就跳到 ENGING1,否则继续执行。
- 在循环中,从 SRC 读取数据到寄存器 A,然后使用 MOVX 指令将 A 的值写入到 DPTR 所指向的位置。然后增加计数器 R0 和地址 R1。
- 再次使用 CJNE 指令检查 A 的值是否等于 '$',如果不等于,就回到 Write,否则跳到 ENGING1。
(2)Procedure2子程序
- Procedure2 负责2.从SRC中,向起始地址为DEST的片外存储中,逆序拷贝之前存储的NUM个单字节数,并以$字符结尾。R0 用于计数,R1 存储 SRC 的地址。
- 同样使用循环,CJNE 指令检查 R0 是否等于 NUM,如果等于,就跳到 ENGING2,否则继续执行。
- 在循环中,从 SRC 读取数据到寄存器 A,然后使用 MOVX 指令将 A 的值写入到 DPTR 所指向的位置。然后增加计数器 R0,但是减小地址 R1 以实现逆序复制。
- 再次使用 CJNE 指令检查 A 的值是否等于 '$',如果不等于,就回到 Copy,否则跳到 ENGING2。
三、 实现效果
四、总结
- 在一开始设计程序的时候,我以为给出的代码已经储存了SRC与DEST的地址位置,不需要在额外用寄存器再储存。事实证明,这是个很天真的想法,于是我使用R1与DPTR进行储存了。
- 在写入数据的时候,原先我想直接将R1,也就是记录num的寄存器直接与$比较,后面发现程序不允许。于是增加了中间商DPTR进行操作。
- 通过这次实验更加加深了对循环程序设计的认识,也懂了一些单片机外部储存空间的访问方法。
附录:
ORG 0000HLJMP MAINORG 2000H
MAIN: SRC DATA 30HDEST XDATA 2000HNUM DATA 20HACALL Procedure1ACALL Procedure2SJMP $Procedure1: ; 将数据从 SRC 复制到 DESTMOV R0, #0 ; R0 用于计数MOV R1, #SRC ; R1 存储 SRC 的地址
MOV DPTR,#DEST ; 保存DEST起始地址Procedure1_LOOP:CJNE R0, #NUM, Write ; 检查R0是否等于NUM,如果不等于,则跳转到 Write SJMP ENGING1Write:MOV A, @R1 ; 从 SRC 读取数据到 A 寄存器MOVX @DPTR, A ; 将 A 寄存器的值写入到 DPTR 所指向的位置INC R0 ; 增加计数器 R0INC R1 ; 增加指向下一个字节的地址CJNE A, '$', Write ; 查A的值是否等于'$',如果不等于,则跳转回 WriteSJMP ENGING1ENGING1:RET ; 从子程序返回Procedure2: ; 从 SRC 中,向起始地址为 DEST 的片外存储中,逆序拷贝之前存储的 NUM 个单字节数MOV R0, #0 ; R0 用于计数MOV R1, #SRC ; R1 存储 SRC 的地址Procedure2_LOOP: CJNE R0, #NUM, copy ; 从SRC的末尾开始向 DEST 的末尾复制数据SJMP ENGING2Copy:MOV A, @R1 ; 从 SRC 读取数据到 A 寄存器MOVX @DPTR, A ; 将 A 寄存器的值写入到 DPTR 所指向的位置INC R0 ; 增加计数器 R0DEC R1 ; 减小指向上一个字节的地址CJNE A, '$', Copy ; 检查A的值是否等于'$',如果不等于,则跳转回CopySJMP ENGING2ENGING2:RETEND