《微机实验》报告实验名称分支程序设计实验专业班级姓名学号序号联系方式一、任务要求熟练掌握KeilC环境下汇编语言程序的调试方法,加深对汇编语言指令、机器码、寻址方式等基本内容的理解,掌握分支程序和简单程序的设计与调试方法,了解并行IO口的使用。1.设有8bits符号数X存于外部RAM单元,按以下方式计算后的结果Y也存于外部RAM单元,请按要求编写程序。240/2204020XXYXXXX当当当2.利用51系列单片机设计一个24小时制电子时钟,电子时钟的时、分、秒数值分别通过P0、P1、P2端口输出(以压缩BCD码的形式)。P3.0为低电平时开始计时,为高电平时停止计时。提高部分(选做):a.实现4位十进制加、减1计数,千位、百位由P1口输出;十位、个位由P2口输出。利用P3.7状态选择加、减计数方式。b.利用P3口低四位状态控制开始和停止计数,控制方式自定。二、设计思路1.分段函数设计对于第一个任务,相当于设计一个分段函数程序,根据变量X的值所处的区间进行相应的计算。由学过的知识知道,可利用比较转移指令CJNE来判断X是否等于临界值20,40,若不等,再根据执行CJNE指令后的进位位CY的值来判断X与临界值的的大小关系,易知CY=0则X大于临界值,CY=1则X小于临界值;如此,再进行相应的计算。另外,除法计算中可能产生余数,商和余数应该分开存储,若乘方运算结果大于255,高八位与低八位应分开存储。2.24小时制时钟程序本程序须可以构建两部分循环。首先构建一个三重循环实现“一秒延时”,循环体利用NOP指令(单字节指令,1µs)经多次循环达到延时一秒的效果。再利用已经构建好的“一秒延时”部分,设计计时系统的三重循环,秒(0-59)、分(0-59)、时(0-23)。需要注意的是,在小时、分、秒达到59时,下一次应该为零。程序运行时修改P3.0的值可以实现暂停和继续的功能。3.加一减一程序先初始化P1和P2,然后当P3低四位均为0作为开始计数的标志,每次计数中插一个延时程序。P3.7为0时进行加1计数:先把低2位从P2中取出至A,对A进行ADD加一计数并进行十进制修正,然后存进P2;再把高2位从P1取出至A,对A进行ADDC的加进位操作并十进行进制修正,然后存进P1。P3.7为1时进行减一计数:只需改用ADD指令加上1的补码即可,高2位在第二位为99时进行同样的操作,最后分别用P1和P2输出高2位和低2位。即可实现所需功能。三、资源分配1.分段函数根据题目的条件,首先,设该8位无符号数为30H,把片外地址4000H分配给它,把片外地址4001H和4002H分配给经分段函数计算得到的结果Y。按位取反计算结果存于4001H单元,而除法计算结果的商与余数和乘方计算中结果的高、低八位分开存储于4001H-4002H单元。用寄存器A,B来存放在乘除运算中所得的中间结果。2.二十四小时制时钟工作寄存器R0、R1、R2分别用于秒、分、时循环次数的设定,R3、R4分别用于分与时的循环计数,R5-R7用于“一秒延时”中三重循环的循环次数设定。秒、分、时数值分别由P2、P1、P0端口输出。3.加、减1计数程序:将十进制数的千位数和百位数存于P1,将十进制数的十位数和个位数存放于P2,P3.0至P3.3为是否进行计数的4个控制位,P3.7为选择加一或减一的计数方式的控制位;R3,R4,R5为计数中的延时程序指定循环次数。四、流程图1.分段函数NYNYNYYN开始X赋值A←X设置数据指针(DPTR)←A存X于片外RAMA≠20Y=/XCY←0CY≠1?(4001H)←AA≠40?CY≠1?Y=X/2Y=X²(4001H)←A(4002H)←B结束2.时钟程序YNYNYNY开始PO←0P1←0P2←0P3←0P3.0=0?延时1s秒钟计数,R0加1A←R0,并转换成BCD码R0=60H?P2←AR0←0P2←0分钟计数,R1加1A←R1,并转换为BCD码R1=60H?R1←0P1←0时钟计数,R2加1A←R2,并转换为BCDR2=24?P0←AR2←0P0←0P1←AN五.源代码1.分段函数ORG0000HLJMPMAINORG0100HMAIN:MOVA,#30H;将8位无符号数赋给AMOVDPTR,#4000H;定义数据指针MOVX@DPTR,A;将X存于片外RAMCLRC;将进位位清零KIND1:CJNEA,#14H,KIND2;将A与14H比较,若不等于14H,跳转至KIND2OUT1:CPLA;对A中内容取反MOVDPTR,#4001H;定义数据指针MOVX@DPTR,A;将计算结果存于片外地址4001HSJMPDONEKIND2:JNCKIND3;判断进位位CY是否为0,若为0,跳转至KIND3SJMPOUT1;否则跳转至OUT1KIND3:CLRC;将进位位清零CJNEA,#28H,KIND4;将A中内容与28H比较,若不等于28H,跳转至KIND4OUT2:MOVB,A;将A中内容赋给BMULAB;计算X的平方,将结果高八位存于B,低八位存于AMOVDPTR,#4001H;定义数据指针MOVX@DPTR,A;将结果低八位存于片外地址4001HINCDPTR;数据指针加一MOVA,B;将B中内容赋给AMOVX@DPTR,A;将结果高八位存于片外地址4002HSJMPDONEKIND4:JNCOUT2;判断进位位是否为0,若为0,跳转至OUT2SJMPOUT3;否则跳转至OUT3OUT3:MOVB,#02HDIVAB;计算X/2,将商存于A,余数存于BMOVDPTR,#4001H;定义数据指针MOVX@DPTR,A;将商存于片外地址4001HINCDPTR;数据指针加1MOVA,BMOVX@DPTR,A;将余数存于片外地址4002HSJMPDONEDONE:SJMP$END2.时钟程序ORG0000HLJMPMAINORG0100HMAIN:MOVR0,#00HMOVP0,#00H;时钟位清零MOVP1,#00H;分钟位清零MOVP2,#00H;秒钟位清零START:JBP3.0,START;P3.0为低电平开始计数,高电平停止计数MOVR2,P2;P2的值存入R2CJNER2,#60H,DEL;秒钟达到60继续,不足60跳转MOVP2,#00H;秒钟清零MOVA,P1ADDA,#01H;分钟位加1DAA;分钟位改为BCD码MOVP1,AMOVR1,P1;P1的值存入寄存器R1CJNER1,#60H,DEL;分钟达到60继续,不足60跳转MOVP1,#00H;分钟清零MOVA,R0ADDA,#01H;时钟位加1DAA;时钟位改为BCD码MOVR0,AMOVP0,ACJNER0,#24H,DEL;时钟达到24继续,不足24跳转MOVP0,#00H;时钟位清零MOVR0,#00HDEL:MOVR7,#24;延时程序LOOP1:MOVR6,#61LOOP2:MOVR5,#170LOOP3:NOPNOPDJNZR5,LOOP3DJNZR6,LOOP2DJNZR7,LOOP1MOVA,P2ADDA,#01H;秒钟位加1DAAMOVP2,ASJMPSTARTEND3.加一减一程序ORG0000HLJMPMAINORG0100HMAIN:MOVP1,#00H;P1端口置零MOVP2,#00H;P2端口置零MOVP3,#7FH;P3端口置#7FHSTART:JBP3.0,STARTJBP3.1,STARTJBP3.2,STARTJBP3.3,START;判断是否开始计时LJMPDELAY;跳转到延时子程序DELAY:MOVR7,#24DEL1:MOVR6,#61DEL2:MOVR5,#170DEL3:NOPNOPDJNZR5,DEL3DJNZR6,DEL2DJNZR7,DEL1;延时1秒JBP3.7,DOWN;P3.7为0时,加1计数;P3.7为1时,减1计数LJMPUPDOWN:MOVA,P2CLRCSUBBA,#01HMOVR1,AANLA,#0FHMOVR7,AMOVA,R1ANLA,#0F0HMOVR1,AMOVA,P1SUBBA,#00HMOVR0,AANLA,#0FHMOVR6,AMOVA,R0ANLA,#0F0HMOVR0,ACJNER7,#0FH,LOOP1MOVR7,#09HLOOP1:CJNER1,#0F0H,LOOP2MOVR1,#90HLOOP2:CJNER6,#0FH,LOOP3MOVR6,#09HLOOP3:CJNER0,#0F0H,LOOP4MOVR0,#90HLOOP4:MOVA,R1ADDA,R7DAAMOVP2,AMOVA,R0ADDA,R6DAAMOVP1,ALJMPDELAY;减1计数子程序UP:MOVA,P2ADDA,#01HDAAMOVP2,AMOVA,P1ADDCA,#00HDAAMOVP1,ALJMPDELAY;加1计数子程序END六、程序测试方法与结果、软件性能分析1.分段函数对于分段函数的问题,可以将X设为某一值,运行程序,观察各个寄存器及有关地址中内容,进行验证。截图如下:(1)X=30H(2)X=0AH(3)X=18H经验证,所有结果正确,且运行程序过程中并未出现任何问题,故源程序正确2.24小时时钟程序附加:思考题1.实现多分支结构程序的主要方法有哪些?举例说明。2.在编程上,十进制加1计数器与十六进制加1计数器的区别是什么?怎样用十进制加法指令实现减1计数?答:1.一是利用条件转移指令实现,如DJNZ,JNC等等例如:例如,判断两个单字节无符号数的大小(分别存于片内RAM的40H和41H单元)并把大数存入42H单元。可以用判断CY的转移指令JNC来实现,程序如下:JUDGE:MOVA,40HCLRCSUBBA,41HJNCLPMOV42H,41HRETLP:MOV42H,40HRET二是利用分支表来实现,如分支地址表、转移指令表、地址偏移量表。例如:根据R3的值控制转向8个分支程序。采用分支地址表实现:MOVDPTR,#BRATAB;取表首地址MOVA,R3ADDA,R3;A←R3×2JNCNADDINCDPH;R3×2进位加到DPHNADD:MOVA,R4;暂存AMOVCA,@A+DPTR;取分支地址高8位XCHA,R4INCAMOVCA,@A+DPTR;取分支地址低8位MOVDPL,A;分支地址低8位送DPLMOVDPH,R4;分支地址高8位送DPHCLRAJMP@A+DPTR;转相应分支程序BRATAB:DWSUBR0;分支地址表DWSUBR•••DWSUBR72.十进制加一后需要在计算结果的基础上进行修正,运用DA指令,而十六进制加一指令所得结果即为最终结果,无需进行修正。用十进制加法指令实现减1计数,可通过以下代码实现:……ADDA,#63HDAA……七、心得与体会本次实验三个任务都是利用分支结构来实现特定的功能,这就要求我们要能够深刻理解分支程序的程序结构,熟练掌握其实现方法并灵活加以运用。通过本次试验,强化了各种指令的应用,并且学会了熟练使用分支程序的方法。在独立完成实验的同时,锻炼了我们保持冷静,独立思考的能力。