胡乾斌教材部分习题解答.docx
《胡乾斌教材部分习题解答.docx》由会员分享,可在线阅读,更多相关《胡乾斌教材部分习题解答.docx(12页珍藏版)》请在冰豆网上搜索。
胡乾斌教材部分习题解答
第一章
129=B=81H;253=B=FDH;
==
=,1001,1001……B=……H(无限循环小数,根据精度确定需要的位数)
由题得三者均为正数,所以原码、反码、补码相同,故
x1=x2=x3=0101,0111B=57H=87
该题与上题不同在均是负数,故原码、反码、补码相同的情况下,原数并不相同。
第二章
最后一问:
如果CPU使用两组寄存器,一般使用第0与第1组,那么剩下的寄存器组对应的地址单元可作一般缓冲用,第0与第1组已用掉地址:
00H—0FH,故而堆栈SP的初值可设定在0FH或以上。
第三章
(1)A=57H,Cy=1(在符号位产生进位,进位标志位Cy=1),进位的1是丢掉,累加器只能存8位信息。
有同学写成A=157H,Cy=0.
(2)A=3BH,Cy=0
SP=2FH,DPH=01H,DPL=23H,A=20H
注意SP在每次的POP减一,故最终SP=2FH.(30H单元的前一单元不是29H)
堆栈(0AH)=34H,(0BH)=12H,SP=0BH
有的同学仅写DPTR的内容,是不够的,这里是将DPTR的内容压入栈中,但DPTR本身不代表堆栈。
Loop循环完成的是24位的加法,每步将带进位位Cy相加,同时影响进位位。
故经过loop循环后R0指向22H单元,结果送原R0指向的地址单元。
原来:
(22H)=A0H(27H)=76H
(21H)=90H(26H)=6FH
(20H)=80H(25H)=A0H
Loop循环:
(22H)=17HCy=1
(21H)=00HCy=1
(20H)=20HCy=1
之后,R0=23H,R1=28H。
因Cy=1,故(23H)=01H。
所有地址单元只可存八位数,不可(21H)=160H.
3.25A==8CH,执行乘以10的功能,因为A*2+A*2*2*2=A*10
有的同学没有写出是乘以10的功能。
3.26实现的如下逻辑运算[∨∧]∧∨
),其中以用户标志位F0来存储[∨∧]的结果。
第四章
4.5略
有的同学有这样的指令:
MOVR0,#2100H.R0只能存八位,故只能指向低位的地址区。
有的同学逻辑搞反,不为零应该继续循环,故:
DJNZR2,LOOP就可以了,不需要太复杂。
还有的同学传送方向搞反了,程序写成:
MOVXA,@DPTR
MOV@R0,A
计数器初始值应该为21H.
补充习题,有的同学忘做,可以简单回答:
LJMP与LCALL的主要区别是未发生保护现场、恢复现场操作。
采用一种子程序的形式实现:
ORG1000H
MOVDPTR,#3001H
MOVXA,@DPTR
MOVB,A;也可用其它内部存储单元临时存放3001H的内容。
MOVDPTR,#3000H
MOVXA,@DPTR
ACALLSQRSUM
CJNEA,#10,EXE1
SJMPSAVEDATA
EXE1:
JCADD10
SUBBA,#10
SJMPSAVEDATA
ADD10:
ADDA,#10
SAVEDATA:
MOVDPTR,#3002H
MOVX@DPTR,A
DONE:
SJMPDONE
SQRSUM:
ADDA,B;该子程序以寄存器A与B传送参数值
MOVB,A
MULAB
RET
END
该程序没有考虑若a+b>255,以及(a+b)2>255的情况下,实际的角度应该就这两方面进行放弃操作。
但本题未说明出现这种情况如何情况,为简化程序中未写入这些情况的处理。
循环加判断实现
ORG1000H
MOVDPTR,#1000H
MOVR2,#99;本程序循环的地址指针已经从1001H单元开始,故循环次数减1
MOVXA,@DPTR
MOV30H,A;将当前值存入临时的30H单元
LOOP:
INCDPTR
MOVXA,@DPTR
SUBBA,30H
JB,NEXT
ADDA,30H;恢复A中的值,因为最新的值刚才进行了减操作。
MOV30H,A
NEXT:
DJNZR2,LOOP
MOVA,30H
MOVDPTR,#1100H
MOVX@DPTR,A
END
ORG1000H
MOVDPTR,#2100H
MOVR3,#100;总计数器
MOVR0,#00;0计数器
MOVR1,#00;正数计数器
MOVR2,#00;负数计数器
LOOP:
MOVXA,@DPTR
JZCOUNT0;以下是两次分支程序实现多分支程序
JB,CTNEG;转入负数统计程序段
CTPOS:
INCR1
SJMPDONE
CTNEG:
INCR2
SJMPDONE
COUNT0:
INCR0
DONE:
INCDPTR
DJNZR3,LOOP
END
该程序与4.2.7有些类似。
LOOP:
MOVR0,#30H
MOVR7,#100;
LOOP1:
MOVA,@R0;
JZLOOP2
JNB,LOOP2
CPLA
ADDA,#81H
MOV@R0,A;
LOOP2:
INCR0
DJNZR7,LOOP1
RET;
4.20晶振为6MHz,得每个机器周期为12*1/6μs=2μs,可以先行计算对于100ms,需要循环50,000个机器周期;对于1s,需要500,000个机器周期;考虑DJNZ为2个机器周期,故循环次数比刚才的数字减半。
对于100ms
为简单,以25,000个DJNZ实现,可以250*100故,程序为
由程序:
ORG1000H
MOVR2,#250
DELAY2:
MOVR3,#100
DELAY1:
DJNZR3,DELAY1;这句将循环25,000次,执行时间最长。
DJNZR2,DELAY2
该程序执行时间:
1+250*(1+100*2+2)=50751个机器周期=,[算对].
精确的计算,可以将R3的值设为x,求解。
1+250*(1+x*2+2)=50000,故x=,取x=99
程序执行时间:
50251个机器周期=.
对于1s,由于需要500,000个机器周期,以250,000个DJNZ实现已不方便。
因为两个八位数相乘,最大255*255。
故需要NOP指令加长内循环的时间。
ORG1000H
MOVR2,#250
DELAY2:
MOVR3,#DIMS
DELAY1:
NOP
NOP
NOP
NOP
NOP
NOP
DJNZR3,DELAY1;这句将循环62,500次,执行时间最长。
DJNZR2,DELAY2
简便计算:
250*8*DIMS=500,000,故DIMS=250
该程序执行时间:
1+250*(1+250*8+2)=500751个机器周期=,[算对].
第五章
2761
(1)…….0000H—1FFFH
2761
(2)…….2000H—3FFFH
2761(3)…….4000H—5FFFH
2761(4)…….6000H—7FFFH
6264
(1)…….8000H—9FFFH
6264
(2)…….A000H—BFFFH
自测题
2.2764(a)C000H—DFFFH
2764(b)A000H—BFFFH
62646000H--7FFFH
第六章
习题略
第七章
已知8255A的口地址为7FF0~7FF3H,阅读下述程序,回答问题:
执行1~3条指令后,要求A,B,C三个端口各干什么?
答:
通过向控制寄存器送82H的数值,可知,A口将工作于方式0,输出状态;C口上半部将工作于方式0,输出状态;B口将工作方式0,输入状态;C口下半部将工作于方式0,输出状态。
已A口=FFH,B口=78H,C口=7FH,(30H)=32H,执行4~9条指令后,A口、B口、C口,(30H)中的值发生了什么变化
ORG8000H
1MOVDPTR,#7FF3H
2MOVA,#82H
3MOV@DPTR,A
4MOVDPTR,#7FF1H
5MOVXA,@DPTR
6MOV30H,A
7MOVDPTR,#7FF0H
8MOVA,#79H
9MOVX@DPTR,A
答:
执行第4-5条指令,将从B口输入数据至累积器A,执行第6条指令,(30H)=78H;
执行第7-9条指令,将79H数值从A口输出,因此A口=79H,B口=78H,C口=7FH,(30H)=78H
第八章
自测题
(1)定时器0工作于方式1
(2)机器周期1μs,初始值x=0DD0H=3536,定时时间65536-3536=62000个机器周期,即62ms。
(3)由于定时器/计数器溢出后,其中的值已变为0,不再是所需初始值,而方式1不具有自动装载初值的功能,若不重新赋值,必然达不到预期的定时效果,故需重置初值。
补充题
设单片机时钟为12MHz,利用定时器T1,使引脚输出的矩形波,要求占空比为1:
2,试编写程序,要求中断方式,请问采用方式2可以吗?
为什么?
建议采用方式0。
解:
根据输出波的要求,可知可采用高低电平分别为1ms便能满足。
欲满足定时1ms,初始值
从最高位13位开始往后取高位八位,即看成:
所以TH1==E0H,TL1=18H.
若采用方式2最大计数量为256,而定时时间需要的计数量为1000,所以一般情况下不可行。
主程序:
ORG0000H
AJMPMAIN
ORG001BH
AJMPTINT
MAIN:
MOVTMOD,#00H
MOVTH1,#0E0H
MOVTL1,#18H
SETBEA
SETBET1
SETBTR1
SJMP$
中断程序:
TINT:
MOVTH1,#E0H
MOVTL1,#18H
CPL
RETI
第九章串行通信
补充习题:
已知单片机晶振fosc=6MHz。
请编制串行通信数据接收程序,将接收的16个字节的数据送入片内50~5FH单元中。
串行接口设定为工作方式3,要求波特率1200b/s。
(采用中断方式实现)
解:
由晶振fosc=6MHz,得机器周期2μs,
波特率=
,得计数初始值x=256-13=243=F3H
ORG0000H
AJMPMAIN
ORG0023H
AJMPSINT
MAIN:
MOVTMOD,#20H;定时器1工作于方式2
MOVTH1,#0F3H
MOVTL1,#0F3H
MOVSCON,#0D0H;串行口工作于方式3,置接收REN有效
MOVPCON,#00H;设培增位SMOD为0
MOVR0,#50H;存放的目的地址
MOVR7,#10H;存放数据的数量
SETBEA
SETBES1;置串行中断有效
SETBTR1;启动定时器,产生波特率,方式2自动装载初值,故不需要中断子程序重新装载
SJMP$
中断程序:
SINT:
CLRRI
MOVA,SBUF;将接收的数据送入累加器A
JB,ONEE;LOOP1
JBRB8,ERROR;与RB8不一致,转出错处理程序
SJMPRIGHT
ONEE:
JNBRB8,ERROR;另一种不致,转出错处理
RIGHT:
MOV@R0,A
INCR0
DJNZR7,CONTIN
CLRES
SJMPCONTIN
ERROR:
…………
CONTIN:
RETI
第十章D/A和A/D转换
,去掉其中“采样周期为1s”,为避免调用延时子程序。
实际不同通道之间是需要一定延时的。
连线参照书10.3.4
ORG0000H
AJMPMAIN
ORG0013H
AJMPBINT1
ORG0100H
MAIN:
MOVR1,#30H;数据区首地址
MOVR4,#08;8路模拟信号计数器
MOVR2,#0;R2确定哪个通道A/D转换
SETBEA;开中断总允许
SETBEX1;开外部中断1
SETBIT1;外部中断边沿触发
MOVDPTR,#0BFFFH;送ADC0809地址
MOVA,R2
MOVX@DPTR,A;输出有效信号,启动A/D转换
SJMP$;等待中断
ORG0200H
BINT1:
MOVDPTR,#0BFFFH;ADC0809地址
MOVXA,@DPTR;输出有效信号,输入转换结果
MOV@R1,A;A/D转换结果送入R1指向的单元
LCALLDELAY;本题没有延时要求,若有可以在此加上
INCR1;目的单元指针增1
INCR2;修改模拟通道地址
MOVA,R2;下一个模拟通道
MOVX@DPTR,A;由中断子程序启动第1次以后的A/D转换
DJNZR4,LOOP;8路未采集完,准备返回
CLREX1;8路已采集完,通过关中断的形式结束
LOOP:
RETI
END
试进行程序设计,利用DAC0832输出一个锯齿波信号
START:
MOVDPTR,#7FFFH;置DAC0832地址;
LOOP1:
MOVR7,#00H;置初值;
LOOP2:
MOVA,R7;读输出值;
MOVX@DPTR,A;输出
INCR7
CJNER7,#40H,LOOP2;判断是否达到峰值
SJMPLOOP1;进入新的一轮输出
11.2用图11.1.3的动态显示接口电路编写显示Goodby的程序
此题,可以在表中放入“日”字LED显示器可以显示的英文字母,然后在读取表中数据时,给出欲显示的字母的索引值。
但由于“日”字LED显示器并不能顺序的放下所有英文字母,因此,采用表格法不适合以索引值来取段码,不如直接按顺序放下g,o,o,d,b,y的段码。
然后以顺序号1,2,3,4,5,6取便是。
根据此分析,本题将欲显示的这几个英文字母的相应段码,放置在指定表中。
以下程序是关键程序段,未写出如何终止显示等部分。
DIR;MOVR0,#00H;表格顺序号
MOVR3,#01H;扫描位初值
MOVA,R3;扫描位初值先送A
LD0:
MOVDPTR,#7F01H;8155的PA口地址
MOVX@DPTR,A;扫描位送PA口
INCDPTR;8155的PB口地址
MOVA,R0;取显示数据,想想此处为什么不是间接寻址?
ADDA,#0CH;地址偏移量补偿
MOVCA,@A+PC;从表中取待显示的段码
DIR1:
MOVX@DPTR,A;段码送8155PB口
ACALLDL1;显示需要一定延时,否则人眼看不到
INCR0;取的数据单元指针增1
MOVA,R3;
JB,DIR;5位扫描完,再重新开始显示。
RLA;下一扫描位
MOVR3,A
SJMPLD0;返回到显示下一位
SHTAB:
DB3DH,5CH,5CH,5EH,7CH,6EH
DL1:
(略)