微机实验报告实验二汇总
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验名称 实验二 分支与循环程序设计实验 指导教师
专业班级 姓名 学号
联系电话
一、任务要求
1. 设有8bits 符号数X 存于外部RAM 单元,按以下方式计算后的结果Y 也存于外部RAM 单元,请按要求编写程序。
240/22040
20X X Y X X X X ⎧≥⎪=<<⎨⎪≤⎩当当
当
2. 利用51系列单片机设计一个24小时制电子时钟,电子时钟的时、分、秒数值分别通过P0、P1、P2端口输出(以压缩BCD 码的形式)。
P
3.0为低电平时开始计时,为高电平时停止计时。
设计1s 延时子程序(延时误差小于10us ,晶振频率12MHz )。
提高部分(选做):
a. 实现4位十进制加、减1计数,千位、百位由P1口输出;十位、个位由P2口输出。
利用P3.7状态选择加、减计数方式。
b. 利用P3口低四位状态控制开始和停止计数,控制方式自定。
二、设计思路
1.任务一:先判断输入自变量的正负性。
如果是负数则直接归到取反区间;如果是正数,则与20,40进行大小比较,即和20,40分别做减法,然后根据比较结果归到各个区间。
2.任务二:先设置好进位计数器数值,再将R3、R4和P0、P1、P2、P3清零。
开始先判断控制位P
3.0是否为0,当P3.0=1时原地踏步重复判断,当P3.0=0时开始计时。
计时开始,进行秒钟B 计数,计数后R0减一,每次计数完成用BCD 码子程序转换,然后由P2输出秒钟,判断计数后R0值是否为0,若R0的值不为0,就跳转回秒钟继续计数,若R0的值为
0,就把R0和P2进行清零后,开始分钟计数部分。
同理,每次分钟计数完之后用BCD码子程序转换,然后由P1输出分钟,判断计数后R1值是否为0,若R1的值不为0,就跳转回秒钟继续计数,若R1的值为0,就把R1和P1清零后开始时钟计数部分。
时钟计数完后同样用BCD码子程序转换,然后判断计数后的R2的值是否为0,若不为0,就跳转回秒钟计数,若R2为0,就吧R2和P0清零后直接跳出计数部分,从判断P3.0部分再开始.每两次计数输出之间穿插一个1s的延时程序。
就可以达到时钟的功能。
3.加、减1计数程序:将十进制数的千位数和百位数存于P1,将十进制数的十位数和个位数存放于P2,P3.0至P3.3全为低电平则开始计数,否则停止计数。
P3.7为选择加一或减一的计数方式的控制位,P3.7为0时加1计数,P3.7为1时减1计数;R3,R4,R5为计数中的延时程序指定循环次数。
三、资源分配
1.任务一:
2000H: 输入的自变量
2001H:若X≤20,则为取反结果
若20<X<40,则为X除以二的整数部分
若X≥40,则为平方后的低八位
2002H:若20<X<40,则为X除以二的余数部分
若X≥40,则为平方后的高八位
DPTR:数据指针
2.任务二:
R0、R1、R2:秒、分、时进位计数器
B:秒钟计数
R3:分钟计数
R4:时钟计数
P0:时钟输出
P1:分钟输出
P2:秒钟输出
P3:电子钟开关控制
3.加、减1计数程序:
P1:十进制数的千位数和百位数
P2:十进制数的十位数和个位数
P3.0-P3.3:是否进行计数的4个控制位
P3.7:选择加一或减一的计数方式的控制位
R3,R4,R5:计数中的延时程序指定循环次数。
四、流程图
1.任务一:
2.任务二:
3.加、减1计数程序:
五、源代码
1.任务一:
File name: 1.asm
Description: 多分支程序设计
Date: 2014/10/8
Designed by: LXQ
Source used: 2000H: 输入的自变量
2001H:若X≤20,则为取反结果
若20<X<40,则为X除以二的整数部分
若X≥40,则为平方后的低八位
2002H:若20<X<40,则为X除以二的余数部分
若X≥40,则为平方后的高八位
DPTR:数据指针
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV A,#25 ;输入自变量
MOV B,#00H ;B清零
MOV DPTR,#2000H ;设置数据指针
MOVX @DPTR,A ;存入片外RAM
JNB ACC.7,COMP1 ;判断符号位
SJMP LOOP1 ;负数则取反
COMP1: CJNE A,#20,COMP2 ;A≠20H时跳转到COMP2 SJMP LOOP1 ;A=20H时取反
COMP2: JC LOOP1 ;CY=1时取反
CJNE A,#40,COMP3 ;A≠40H时跳转到COMP3
SJMP LOOP3 ;A=40H时平方
COMP3: JC LOOP2 ;CY=1时除以二
SJMP LOOP3 ;CY=0时平方
LOOP1: CPL A ;取反操作
SJMP STORE ;跳转存储指令
LOOP2: MOV B,#02H
DIV AB ;除以二
SJMP STORE ;跳转存储指令
LOOP3: MOV B,A
MUL AB ;平方
SJMP STORE ;跳转存储指令
STORE: INC DPTR ;设置数据指针
MOVX @DPTR,A
INC DPTR
MOV A,B
MOVX @DPTR,A ;高位和低位依次存入片外RAM SJMP $ ;原地踏步
END
2.任务二:
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV R0,#60
MOV R1,#60
MOV R2,#24 ;时针、分针、秒针计数器赋初值
MOV R3,#0H
MOV R4,#0H ;时钟、分钟赋初值
MOV P0,#0H
MOV P1,#0H
MOV P2,#0H
MOV P3,#0H
START: JB P3.0,STOP ;若P3.0为高电平则停止计时
ACALL DLY
MOV A,B
ADD A,#01H
DA A
MOV B,A ;秒钟计时
MOV P2,A ;输出秒钟
DJNZ R0,START ;R0-1,不等于零则跳到START继续循环
MOV B,#0H
MOV P2,#0H
MOV A,R3
ADD A,#01H
DA A
MOV R3,A ;分钟计时
MOV P1,A ;输出分钟
MOV R0,#60 ;计数器归位
DJNZ R1,START ;R1-1,不等于零则跳到START继续循环
MOV B,#0H
MOV R3,#0H
MOV P1,#0H
MOV A,R4
ADD A,#01H
DA A
MOV R4,A ;时钟计时
MOV P0,A ;输出时钟
MOV R1,#60 ;计数器归位
DJNZ R2,START ;R2-1,不等于零则跳到START继续循环
SJMP MAIN
STOP: SJMP $ ;原地踏步DLY: MOV R5,#46 ;延时1s,误差1us ;延时1s,误差1us
DLY:
DELAY: MOV 72H,#100
LOOP3: MOV 71H,#100
LOOP1: MOV 70H,#47
LOOP0: DJNZ 70H,LOOP0
NOP
DJNZ 71H,LOOP1
MOV 70H,#46
LOOP2: DJNZ 70H,LOOP2
NOP
DJNZ 72H,LOOP3
MOV 70H,#48
LOOP4: DJNZ 70H,LOOP4
RET
END
3.加、减1计数程序:
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV P1,#00H ;P1端口置零
MOV P2,#00H ;P2端口置零
MOV P3,#7FH ;P3端口置#7FH
START: JB P3.0,START
JB P3.1,START
JB P3.2,START
JB P3.3,START ;判断是否开始计时
LJMP DELAY ;跳转到延时子程序
DELAY: MOV R7,#24
DEL1: MOV R6,#61
DEL2: MOV R5,#170
DEL3: NOP
NOP
DJNZ R5,DEL3
DJNZ R6,DEL2
DJNZ R7,DEL1 ;延时1秒
JB P3.7 ,DOWN ;P3.7为0时,加1计数;P3.7为1时,减1计数
LJMP UP
DOWN: CLR C
MOV A,P2
SUBB A,#01H
MOV R1,A
ANL A,#0FH
MOV R7,A
MOV A,R1
ANL A,#0F0H
MOV R1,A
MOV A,P1
SUBB A,#00H
MOV R0,A
ANL A,#0FH
MOV R6,A
MOV A,R0
ANL A,#0F0H
MOV R0,A
CJNE R7,#0FH,LOOP1
MOV R7,#09H
LOOP1: CJNE R1,#0F0H,LOOP2
MOV R1,#90H
LOOP2: CJNE R6,#0FH,LOOP3
MOV R6,#09H
LOOP3: CJNE R0,#0F0H,LOOP4
MOV R0,#90H
LOOP4: MOV A,R1
ADD A,R7
DA A
MOV P2,A
MOV A,R0
ADD A,R6
DA A
MOV P1,A
LJMP START ;减1计数子程序UP: MOV A,P2
ADD A,#01H
DA A
MOV P2,A
MOV A,P1
ADDC A,#00H
DA A
MOV P1,A
LJMP START ;加1计数子程序
END
六、程序测试方法与结果
1.任务一:
⑴取X=10,则结果应为F5H,即(2000H)=0AH,(2001H)=F5H,(2002H)=00H。
编译结果如下:
⑵取X=25,则结果应为0CH,即(2000H)=19H,(2001H)=0CH,(2002H)=01H。
编译结果如下:
⑶取X=60,则结果应为3600,即(2000H)=3CH,(2001H)=10H,(2002H)=0EH。
编译结果如下:
综上可得程序功能正确,运行成功。
2.任务二:
P3.0设为低电平,设置断点,开始计数,秒种到60时,分钟进位,秒钟清零:
重新设置断点,开始计数,分种到60时,时钟进位,分钟清零:
重新设置断点,开始计数,时种到24时,全部清零,重新判断P3.0。
P3.0置一则计时停止:
测试完成,程序运行顺利,功能正确。
3.加、减1计数程序:
P3.0至P3.3全为低电平时开始计数,P3.7为0时加1计数(0加1为1):
P3.7为0时减1计数(0减一则为9999):
功能运行正常。
七、心得与体会
通过这次的微机实验,我加深了对于分支程序设计的理解,并通过自己设计程序框图和代码,提高了我的编程和调试代码的能力。
在编程过程中,由于分支众多,我常常遇到思路不清晰的情况,这就要求我们在动手写代码之前一定要先想好代码的整体架构,设计好流程图,再跟着流程图的思路一步步编写代码,才能保持思路清晰,减少错漏。
总之,要学会编写复杂的程序,看书是远远不够的,还需要我们多动手,多实际操作,去解决一些实际遇到的问题,这样才能提高我们的编程水平。
思考题
1.实现多分支结构程序的主要方法有哪些?举例说明。
答:实现多项分支的主要方法是采用分支表法,常用的分支表法的组成有三种形式:
⑴分支地址表:它是由各个分支程序的首地址组成的一个线性表,每个首地址占连续的两个字节。
如:
MOV DPTR,#BRATAB ;取表首地址
MOV A,R3
ADD A,R3 ;A←R3*2
JNC NADD
INC DPH ;R3*2的进位加到DPH
NADD: MOV R4,A ;暂存A
MOVC A,@A+DPTR ;取分支地址高8位
XCH A,R4
INC A
MOVC A,@A+DPTR ;取分支地址低8位
MOV DPL,A ;分支地址低8位送DPL
MOV DPH,R4 ;分支地址高8位送DPH
CLR A
JMP @A+DPTR ;转相应分支程序
BRATAB: DW SUBR0 ;分支地址表
DW SUBR1
┇
DW SUBR7
⑵转移指令表:它是由转移指令组成的一个分支表,其各转移指令的目标地址即为各分支程序的首地址。
若采用短转移指令,则每条指令占两个字节;若采用长转移指令,则每条指令占三个字节。
如:
MOV DPTR,#JMPTAB ;取表首地址
MOV A,R3
ADD A,R3 ;A←R3×2
JNC NADD
INC DPH ;有进位加到DPH
NADD: JMP @A+DPTR ;转相应分支程序
JMPTAB: AJMP SUBR0 ;转移指令表
AJMP SUBR1
┇
AJMP SUBR7
⑶地址偏移量表:各分支程序首地址与地址偏移量表的标号之差(为一个字节)称为地址偏移量,有这些地址偏移量组成地址偏移量表。
如:
MOV DPTR,#DIATAB ;取表首地址
MOV A,R3 ;表的序号数送A
MOVC A,@A+DPTR ;查表
JMP @A+DPTR ;转相应分支程序
DISTAB: DB SUBR0-DISTAB ;地址偏移量表
DB SUBR1-DISTAB
┇
DB SUBR7-DISTAB
SUBR0: ┇
SUBR1: ┇
2.在编程上,十进制加1计数器与十六进制加1计数器的区别是什么?怎样用十进制加法指令实现减1计数?
答:十六进制加1计数器可以直接对计数器进行加1的操作,相当于单字节或者多字节的加法运算,其中被加数为当前计数器值,加数始终为1;但是十进制加1计数器不能直接对计数器直接进行加1操作,而必须在对加1操作后紧跟一条DA A指令对其进行二—十进制修正才能实现。
用十进制加法进行减1计数时,应讲计数器当前值与1的十进制补码99H进行想加,然后用DA A指令进行二—十进制修正,从而实现十进制减1计数功能。