分支程序设计实验.docx
《分支程序设计实验.docx》由会员分享,可在线阅读,更多相关《分支程序设计实验.docx(12页珍藏版)》请在冰点文库上搜索。
分支程序设计实验
《微机实验》报告
实验名称分支程序设计实验
专业班级xxxxx姓名xxxxx学号xxxxxx
联系方式xxxxxxxxxxxxxxxxxxxxxxx
一、任务要求
1.设有8bits符号数X存于外部RAM单元,按以下方式计算后的结果Y也存于外部RAM单元,请按要求编写程序。
X2当X≥40
Y=X/2当20〈X〈40
/X当X≤20
2.利用51系列单片机设计一个24小时制电子时钟,电子时钟的时、分、秒数值分别通过P0、P1、P2端口输出(以压缩BCD码的形式)。
P3.0为低电平时开始计时,为高电平时停止计时。
提高部分(选做):
a.实现4位十进制加、减1计数,千位、百位由P1口输出;十位、个位由P2口输出。
利用P3.7状态选择加、减计数方式。
b.利用P3口低四位状态控制开始和停止计数,控制方式自定。
二、设计思路
任务1:
机器内存入的数默认为无符号数,所以应该先判断正负性。
如果是负数则直接归到取反区间;如果是正数,则与20,40进行大小比较,即和20,40分别做减法,然后根据比较结果归到各个区间。
任务2:
先将R0~R2和P0~P2清零,开始先判断控制位P3.0是否为0,当P3.0=1时原地踏步重复判断,当P3.0=0时开始计时。
计时开始,进行秒钟R0计数,每次计数完成用BCD码子程序转换,然后判断计数后R0值是否到60,若R0的值不足60,就直接输出给P2,若R0的值为60,就把R0和P2进行清零后,开始分钟计数部分。
同理,每次分钟计数完之后用BCD码子程序转换,然后判断计数后R1的值是否为60,若不为60,就直接输出给P1,若R1的值为60,就把R1和P1清零后开始时钟计数部分。
时钟计数完后同样用BCD码子程序转换,然后判断计数后的R2的值是否为24,若不为24,就直接输出给P0,若R2为24,就吧R2和P0清零后直接跳出计数部分,从判断P3.0部分再开始.每两次计数输出之间穿插一个1s的延时程序。
就可以达到时钟的功能。
三、资源分配
1.分支程序:
数据指针DPTR:
对片外RAM进行读写操作
2000H:
存放8bits符号数X
2010H:
存放结果Y(取反后的数,或者平方后的高8位,或者除法后的商)
2011H:
存放结果Y(平方后的低8位,或者除法后的余数)
2.时钟程序:
R0、R1、R2:
分别进行秒钟,分钟,时钟的计数
P2、P1、P0:
分别输出秒钟,分钟,时钟
P3.0:
是否计数的控制位
R3、R4、R5:
为1s延时程序指定循环次数
B:
BCD码转换子程序的操作数
四、流程图
1,分支程序设计
2,时钟程序
五、源代码(含文件头说明、资源使用说明、语句行注释)
任务一:
Filename:
first.asm
Description:
多向分支程序设计
Date:
2013.10.15
Designedby:
陈欣雨
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVDPTR,#2000H
MOVA,#10
MOVX@DPTR,A;存数
MOVB,0;寄存器B清零
MOVXA,@DPTR;从R0中取出数x
JNBACC.7,COMP1;判断符号位,符号位为0时转到COMP1
LP3:
CPLA;对x取反
SJMPSTORE
COMP1:
CJNEA,#20,COMP2;A≠20时,转到COMP2
SJMPLP3;A=20时,转到LP3取反
COMP2:
JCLP3;C=1,A<20,转到LP3取反
CJNEA,#40,COMP3;C=0,A>20.当A≠40时,转到COMP3
LP1:
MOVB,A;A=40时,给B赋值为A
MULAB;计算x平方
SJMPSTORE
COMP3:
JNCLP1;C=0,A>40,转到LP1计算x平方
MOVB,#02H;C=1,A<40,赋值B=2
DIVAB;计算x除以2
STORE:
MOVDPTR,#2010H
MOVX@DPTR,A;存数:
INCDPTR;对于平方,高位在前地位在后
MOVA,B;对于除法,商在前余数在后
MOVX@DPTR,A
SJMP$
END
任务二:
ORG0000H
SJMPSTART
ORG0030H
START:
MOVSP,#40H
MOVP1,#0
MOVR3,#0;设定R3初值为0,用R3保存分钟数
MOVR4,#0;设定R4初值为0,用R4保存小时数
MOVR0,#60;设定内循环次数为60
MOVR1,#60;设定中循环次数为60
MOVR2,#24;设定外循环次数为24
CLRA
NEXT:
JNBP3.0,DONE;如果P3.0等于0,则结束计数
ADDA,#1;BCD码加1计数
DAA;对A进行修正
MOVP2,A;显示计数
DJNZR0,NEXT;R0<----R0-1,R0不等于零,跳到NEXT继续循环
MOVA,R3;将分钟数赋给A
ADDA,#1;分钟数加1
DAA
MOVR3,A;分钟数用R3保存
MOVP1,A;显示计数
CLRA
MOVR0,#60;重置内循环次数为60
DJNZR1,NEXT;R1减一,若R1不为0,跳到最内层循环入口处继续循环
MOVR3,#0;分钟数满六十,小时开始计数,同时将分钟数R3清零
MOVA,R4;将小时数赋给A
ADDA,#1;小时数加一
DAA
MOVR4,A;用R4保存小时数
MOVP0,A
MOVR0,#60;重置内循环数为六十
MOVR1,#60;重置次循环数为六十
DJNZR2,NEXT;R2减一,若R2不为0,跳到最内层循环入口处继续循环
DONE:
SJMP$
END
程序测试方法与结果、软件性能分析
实验一:
(1)取X=5,则最后结果应为FA。
编译结果如下图:
(2)取X=36,则最后结果应为12。
编译结果如下图:
(3)取X=60,则最后结果应为3600,即(2010H)=10H,(2011H)=0EH。
编译结果如下图:
实验二:
(1)P3.0设为低电平,开始计时,达60秒时,分从0变为1
分增加1,秒清零
P3.0置1则计数停止
六、心得与体会
做分支程序的设计一定需要一个清醒的头脑,必须在开始写程序之前想好在什么地方进行跳转,什么时候跳转回来等等。
在做第二个实验时,则需要很清楚循环的次数以及数据的存储,不能混淆。
总而言之,在写完这两个程序之后,我觉得,写复杂一点的程序必须有足够的经验,这也就要求我们多锻炼,多写程序,才能够有一个清晰的思路,不至于在编写过程中陷入混乱。
七、思考题
1.实现多分支结构程序的主要方法有哪些?
举例说明。
答:
⑴当分支比较少的时候,可以直接采用条件转移指令,例如:
JBP3.7,SUBJS;P3.7为1时,跳到SUBJS进行减1计数;P3.7为0时,进行ADDJS加1计数
ADDJS:
MOVA,P2
┇
┇
SUBJS:
CLRC
┇
┇
⑵当分支比较多的时候,可以采用分支表法,常用的分支表法有三种:
分支地址表,转移指令表,分支偏移量表。
①分支地址表法:
MOVDPTR,#BRATAB;取表首地址
MOVA,R3
ADDA,R3;A←R3*2
JNCNADD
INCDPH;R3*2的进位加到DPH
NADD:
MOVR4,A;暂存A
MOVCA,@A+DPTR;取分支地址高8位
XCHA,R4
INCA
MOVCA,@A+DPTR;取分支地址低8位
MOVDPL,A;分支地址低8位送DPL
MOVDPH,R4;分支地址高8位送DPH
CLRA
JMP@A+DPTR;转相应分支程序
BRATAB:
DWSUBR0;分支地址表
DWSUBR1
┇
DWSUBR7
②转移指令表法:
MOVDPTR,#JMPTAB;取表首地址
MOVA,R3
ADDA,R3;A←R3×2
JNCNADD
INCDPH;有进位加到DPH
NADD:
JMP@A+DPTR;转相应分支程序
JMPTAB:
AJMPSUBR0;转移指令表
AJMPSUBR1
┇
AJMPSUBR7
③地址偏移量表法:
MOVDPTR,#DIATAB;取表首地址
MOVA,R3;表的序号数送A
MOVCA,@A+DPTR;查表
JMP@A+DPTR;转相应分支程序
DISTAB:
DBSUBR0-DISTAB;地址偏移量表
DBSUBR1-DISTAB
┇
DBSUBR7-DISTAB
SUBR0:
┇
SUBR1:
┇
2.在编程上,十进制加1计数器与十六进制加1计数器的区别是什么?
怎样用十进制加法指令实现减1计数?
答:
十六进制加1计数器可以直接对计数器进行加1的操作,相当于单字节或者多字节的加法运算,其中被加数为当前计数器值,加数始终为1;但是十进制加1计数器不能直接对计数器直接进行加1操作,而必须在对加1操作后紧跟一条DAA指令对其进行二—十进制修正才能实现。
用十进制加法进行减1计数时,应讲计数器当前值与1的十进制补码99H进行想加,然后用DAA指令进行二—十进制修正,从而实现十进制减1计数功能。