您好,欢迎访问三七文档
第三章习题解答4.在8051片内RAM中,已知(30H)=38H,(38H)=40H,(40H)=48H,(48H)=90H,试分析下段程序中各条指令的作用,说出按顺序执行完指令后的结果:MOVA.40H;(A)=48HMOVR1,A;(R1)=48HMOVP1,#0FOH;(P1)=F0HM0V@R1,30H;(48H)=38HMOVDPTR,#1234H;(DPTR)=1234HMOV40H,38H;(40H)=40HMOVR1,30H;(R1)=38HMOV90H,R1;(90H)=38H,P1的地址为90HMOV48H,#30H;(48H)=30HMOVA,@R1;(A)=40HMOVP2,P1;(P2)=38HF0H错误8.试编程将片外数据存储器80H单元的内容送到片内RAM的2BH单元。MOVDPTR,#0080H或:MOVR0,#80HMOVXA,@DPTRMOVP2,#00HMOV2BH,AMOVXA,@R0MOV2BH,A10.试编程将片内RAM20H单元中的两个BCD数拆开,并变成相应的ASCII码存入片内RAM21H和22H单元。MOVA,20H;20H的内容不变ANLA,#0F0HSWAPA;4次移位RRA也可以ADDA,#30HMOV21H,AMOVA,20HANLA,#0FHADDA,#30HMOV22H,A12.试分析以下两段程序中各条指令的作用,程序执行完后转向何处?(1)MOVP1,#0CAH;(P1)=11001010MOVA,#56H;(A)=01010110JBP1.2,L1JNBACC.3,L2;转向L2L1:…L2:…(2)MOVA,#43H;(A)=01000011JBCACC.2,L2JBCACC.6,L2;转向L2L1:…L2:…18.分析下列程序执行后,(SP)的值。MOVSP,#2FHMOVDPTR,#2000HMOVR7,#50HNEXT:MOVXA,@DPTRPUSHADJNZR7,NEXT;(SP)=2FH+50H2F+2*50错误19.试编写程序,查找在30~50H单元中是否有66H这个数据,若有将F0置1,否则将F0清0。MOVR0,#30HCLRF0;MOVA,#66HL0:CJNE@R0,#66H,L1;SUBBA,@R0错,因为A已发生变化,不能循环SETBF0;JNZL1……SJMPSTP;MOVA,@R0正确L1:INCR0;XRLA,#66HCJNER0,#51H,L0;JNZL1STP:……第四章习题解答4.已知从内部RAMBLOCK单元开始存有一组无符号数,其长度存于LEN单元。试编制程序,将它们按从小到大的顺序排列之后仍存放在原存储区域内。例4-15将给定数据块中的数据排序设:N个数据依次存放在内部RAMLIST地址开始的存储区域中,将N个数比较大小之后,使它们按从小到大(或从大到小)的次序排列,仍存放在原存储区域中。排序是在程序设计中经常使用的一种编程方法。排序的方法有多种,本例采用了较常用的“冒泡”排序法。冒泡排序的基本思路是:从前向后依次将相邻两个单元中的数据进行比较,即第一个数与第二个数比较,第二个数与第三个数比较……,如两数比较的大小次序符合排序顺序,则不改变它们的存放顺序,否则交换两数位置,使其符合排序要求。由于每次冒泡后只是从前向后排定一个大数(对于升序排列),所以在整个排序过程中,执行的内容包含两层:第一层为每一轮内的两两比较,第二层为每当一轮比较之后重新组织下一轮的比较,因此宜采用二重循环结构。源程序如下:ORG8000HMOVR7,#N-1;置外循环计数MOVR7,LENDECR7NEXT:MOVA,R7;置内循环计数MOVR5,AMOVR0,#LIST;置数据指针LIST改为BLOCKMOVRl,#0;清交换标志COMP:MOVA,@R0;取数据Xi,i=o~n-1MOVR3,A;暂存XiINCR0;修改指针CLRC;清进位标志CYSUBBA,@R0;Xi与Xi+1比较JCLESS;Xi<Xi+1,不交换MOVA,R3;Xi>Xi+1,交换XCHA,@R0DECR0MOV@R0,AINCR0;恢复数据指针MOVR1,#1;置交换标志LESS:DJNZR5,COMP;内循环未完,继续DJNZR7,LOOP;外循环未完,查交换标志SJMPSTOPLOOP:CJNER1,#0,NEXT;有交换;继续STOP:END程序中R7为外循环计数器,R5为内循环计数器,R0为数据指针,R1为交换标志,R3为暂存寄存器。对于n个数据的排序,外循环次数需n-1次。内循环次数随着外循环执行次数按递减1规律变化,即第一次内循环次数为n-1,第二次内循环次数n-2,……,依此类推。为了提高排序速度,程序中还设置了数据交换标志R1,当两数比较发生过交换,使其置1,否则清零。在排序过程中,若两数比较没有发生过交换,说明数据顺序已排列就绪,可提前结束循环。7.编程实现将内部RAM中以50H开始的10个字节的压缩BCD数转换成十六进制数,存放在以60H开始的单元中。MOVR7,#10;循环10次MOVR1,#60H;结果存放地址MOVR0,#50HLP:MOVA,@R0ANLA,#0F0H;取高4位SWAPAMOV@R1,AINCR1MOVA,@R0ANLA,#0FH;取低4位MOV@R1,AINCR0INCR1DJNZR7,LPRET8.若晶振频率为6MHz,则下面一段延时子程序可延时多长时间?DELAY:MOVR7,#248;1TNOP;1TDJNZR7,$;2TRET;2T解:T=1/6M*12=2um(4+248*2)T=1ms若把$改为DELAY,则延时时间为:(4*248+2)T=1.988ms15.求函数Y=X!(X=0,1,2,…,7。Y用4位BCD码表示)。方法一:查表法;X放在R3中,结果Y存放在R6、R7中(高2位在R6,低2位在R7)MOVA,R3RLAMOVDPTR,#DATAMOVCA,A+@DPTRMOVR6,AINCDPTRMOVCA,@A+DPTRMOVR7,ADATA:DB00H,01HDB00H,02HDB00H,06HDB00H,24HDB01H,20HDB07H,20HDB50H,40H方法二:;MULAB命令限制了乘数和被乘数的范围,但是结果是216(64K),低位放入A,高位放入B;这里这样来处理:5!=120,所以5之前的都一个算法,如果大于5,从两边同时乘。例如7!=5!*(6*7);X放在R3中,结果放在R6R7中,高位在R6ORG0050HMOVA,R3;判断X的范围JNZL1;MOVR7,#00H;X等于0,直接输出0L1:CLRCSUBBA,#01H;JNZL2;小于5的时候可以直接用循环做,跳到LESS5MOVR7,#01H;X等于1,直接输出1L2:MOVA,R3CLRCSUBBA,#06HJNCL4;大于5的时候用120再乘上6,7MOVA,R3;小于等于5的时候算X!DECR3L3:MOVB,R3MULAB;DJNZR3,L3MOVR7,A;(2~5)的阶乘放入R7ACALLCONVERT;转换为BCD码L4:JNZL5;X=7,转L5MOVA,#120;X=6,X!=120*6MOVB,R3MULAB;L6:MOVR5,B;保存结果MOVR7,AACALLCONVERTEND;L5:MOVA,R3;算6*7DECR3MOVB,R3MULAB;MOVB,#120MULABSJMPL6;;;;;;;;;下面是转化为BCD码CONVERT:MOVA,R7;转换低位MOVB,#64H;B内放100DIVABMOVR6,A;这里是百位MOVA,BMOVB,#0AHDIVAB;A里是十位余数在B中,就是个位RLA;十位左移四位,把个位和十位的BCD码放到一个寄存器里面RLARLARLAADDA,BMOVR7,A;R7里面为个位和十位HCCCC:MOVA,R5;R5中为高位十六进制数JZSTOOOP;如果没有高位就直接结束MOVA,R7;不为0,就加高位数字个256ADDA,#56HDAA;调整,如果有进位的话C会置1MOVR7,AMOVA,R6ADDCA,#02H;这里带进位加DAA;再调整MOVR6,ADJNZR5,HCCCC;循环到高位数字为零STOOOP:RET第6章习题6解答试用中断计数设计一个秒闪电路,其功能是控制发光二极管闪亮,其闪烁频率为50Hz。设fosc=6MHz。解:闪烁周期T=1/50秒=20ms,采用T0定时中断10ms将P1.0取反一次。T0采用方式1定时,初值X=65536-6*10000/12=60536=EC78H程序:ORG0000HLJMPSTARTP1.080C51ORG000BHLJMPPROT0ORG1000HSTART:MOVTMOD#01H;T0方式1,定时MOVTH0,#0ECHMOVTL0,#78HMOVIE,#82H;SETBEASETBET0SETBTR0SJMP$ORG2000HPROT0:MOVTH0,#0ECHMOVTL0,#78HCPLP1.0RETI第7章习题解答串口作业:1、设计一个80C51单片机的双机通信系统,并编写程序将甲机片外RAM8000H-9000H的数据块,通过串行口传送到乙机片外RAM3000H-4000H单元中去解:设fosc=11.0592MHZ,波特率为2400波特。串口采用方式1,T1作波特率发生器,采用模式2,取SMOD=0,则T1计数初值为:X=256-11.0592×106×20/384×2400=244=F4H程序如下:;甲机发送程序MOVTMOD,#20H;T1模式2MOVTL1,#0F4H;T1计数初值MOVTH1,#0F4HSETBTR1;启动T1MOVSCON,#40H;串口方式1MOVPCON,#00H;SMOD=0,波特率不增倍MOVDPTR,#8000HLOOP:MOVXA,@DPTR;取发送的数据MOVSBUF,A;发送数据JNBTI,$CLRTIINCDPTRMOVA,DPHCJNEA,#90H,LOOP;MOVA,DPLCJNEA,#01H,LOOPSJMP$;乙机接受程序MOVTMOD,#20HMOVTL1,#0F4HMOVTH1,0F4HSETBTR1MOVSCON,#50HMOVPCON,#00H;LOOP:JNBRI,$CLRRIMOVA,SBUFMOVDPTR,#3000H;接收数据存储地址MOVX@DPTR,AINCDPTRMOVA,DPHCJNEA,#40H,LOOP;MOVA,DPLCJNEA,#01H,LOOPSJMP$2、利用80c51串行口设计4位静态7段显示器,画出电路并编写程序,要求4位显示器上每隔1s交替地显示“0123”和“4567”图中P3.2改为P1.0,或将164的CLR端接地。解1:算法:采用串行口方式0。用定时器0定时50ms,循环20次,实现1s的定时,设晶振为12MHZ。设立显示两组数据的标志。ORG0600HDISP:MOVR7,#4;设置显示位数MOVSCON,#00H;设串行口方式0CLR(SETB)60H;设置一个位来判断显示哪组数据LL:MOVR2,#00H;地址偏移量JB60H,DTAB1MOVDPTR,#TABSJMPDISP0DTAB1:MOVDPTR,#TABLEDISP0:MOVA,R2MOVCA,@A+DPTR;MOVSBUF,A;启动串行口发送数据JNBTI,$;等待一帧发送结束CLRTI;清串行口中断标志INCR2;指向下一个数据DJNZR7,DISP0;CPL60H;交换显示标志位取反DELAY:MOV50H,#20H;定时1S循环计数MOVTMOD,#01HMOVTL0,#0B0H;计数初值MOVTH0,#3CHSETBTR0;启动定时器0L2:JBCTF0,L1;查询计数溢出否SJMPL2;无条件转移L1:MOVTL0,#0B0HMOVTH0,#3CHDJNZ50H,L2SJMPLLTAB:DB
本文标题:单片机课后题答案
链接地址:https://www.777doc.com/doc-5110715 .html