单片微型计算机原理与接口技术 髙锋版 课后答案第4章.docx
《单片微型计算机原理与接口技术 髙锋版 课后答案第4章.docx》由会员分享,可在线阅读,更多相关《单片微型计算机原理与接口技术 髙锋版 课后答案第4章.docx(31页珍藏版)》请在冰豆网上搜索。
单片微型计算机原理与接口技术髙锋版课后答案第4章
第4章【单片机的程序设计】
思考与练习题解析
【4—1】简述下列基本概念:
程序、程序设计、机器语言、汇编语言及高级语言。
【答】各基本概念如下。
·程序:
为计算某一算式或完成某一工作的若干指令的有序集合。
·程序设计:
单片机的全部工作概括起来,就是执行程序的过程。
为单片机准备这一程序,即编制程序的工作过程。
’
·机器语言:
用二进制代码表示的指令系统称为“机器语言系统”,简称为“机器语言”。
·汇编语言:
用英文字符来代替机器语言,这些英文字符称为“助记符’’。
用这种助记符表示指令系统的语言称为“汇编语言”或“符号语言”。
·高级语言:
参照数学语言而设计的、近似于人们日常用语的语言。
它是面向问题或者面向过程的语言。
这种语言不仅直观、易学、易懂,而且通用性强,易于移植到不同类型的机器中。
【4—2】在单片机领域,目前最广泛使用的是哪几种语言?
有哪些优越性?
单片机能否直接执行这几种语言?
【答】在单片机领域,目前最广泛使用的是汇编语言和高级语言。
汇编语言编写的程序效率高,占用存储空间小,运行速度快,而且能反映单片机的实际运行情况。
但编程比使用高级语言困难,通用性差。
单片机不能直接执行汇编语言程序,必须通过人工(或机器)汇编把汇编语言程序转换为机器语言程序。
高级语言不受具体机器的限制,而且使用了许多数学公式和习惯用语,从而简化了程序设计的过程,通用性强,易于移植到不同类型的单片机中。
单片机不能直接识别和执行高级语言,需要将其转换为机器语言程序才能识别和执行。
对于高级语言,这一转换工作通常称为“编译”或者“解释”。
进行编译或者解释的专用程序称为“编译程序”或者“解释程序”。
【4—3】什么叫伪指令?
8OC51单片机程序设计中主要有哪些伪指令语句?
【答】伪指令又称为“汇编程序控制译码指令”。
“伪”体现在汇编时不产生机器指令代码,不影响程序的执行,仅指明在汇编时执行一些特殊的操作。
例如.为程序指定一个存储区,将一些数据、表格常数存放在指定的存储单元,说明源程序开始或结束等.。
不同的单片机开发装置所定义的伪指令不全相同。
80C51单片机程序设计中主要有伪指令语句如下。
1.ORG(Origin)一汇编起始地址伪指令,
指令格式为:
ORG<表达式>’
其含义是向汇编程序说明,下述程序段的起始地址由表达式指明。
表达式通常为十六进制地址码。
2.END(END0fAssembly)一汇编结束伪指令。
其含义是通知汇编程序,该程序段汇编至此结束。
3.EQU(EQUate)—赋值伪指令。
指令格式为:
<标号>EQU<表达式>
其含义是把表达式赋值于标号,这里的标号和表达式是必不可少的。
用EQU语句给一个标号赋值以后,在整个源程序中该标号的值是固定的,不能更改。
4.DL--定义标号值伪指令
指令格式为:
<标号>DL<表达式>
其含义也是说明标号等值于表达式。
同样,标号和表达式是必不可少的。
用DL语句在同一源程序中给同一标号赋予不同的值,即可更改已定义的标号值。
5.DB(DefineByte)—定义字节伪指令
指令格式为:
<标号>DB<表达式或表达式表>
其含义是将表达式或表达式表所表示的数据或数据串存入从标号开始的连续存储单元中。
标号为可选项,它表示数据存储单元地址。
表达式或表达式表是指一个字节或用逗号分开的字节数据。
可以是用引号括起来的字符串,字符串中的字符按ASCII码存于连续的ROM中。
6.DW(DefineWord)---定义字伪指令
指令格式为:
<标号>DW<表达式或表达式表>
其含义是把字或字串值存人由标号开始的连续存储单元中,并且把字的高字节数存人低地址单元,低字节数存入高地址单元。
按顺序连续存放。
7.DS(DefineStonage)—定义存储区伪指令
指令格式为:
<标号>DS<表达式>
·其含义是通知汇编程序,在目标代码中,以标号为首地址保留表达式值的若干存储单元以备源程序使用。
汇编时,对这些单元不赋值。
注意:
对于80C51单片机,DB、DW和DS等伪指令只能应用于程序存储器,而不能应用于数据存储器。
8.BIT—位定义伪指令
用于给字符名称赋予位地址。
命令格式为:
<字符名称>BIT<位地址>
其中,位地址可以是绝对地址,也可以是符号地址。
【4—4】什么是结构化程序设计?
它包含哪些基’本结构程序?
【答】程序设计有时可能是一件很复杂的工作,但往往有些程序结构是很典型的。
采用结构化程序编程时,规律性极强,简单清晰,易读/写,具有调试方便、生成周期短、可靠性高等特点。
根据结构化程序设计的观点,功能复杂的程序结构一般采用三种基本控制结构,即顺序结构、分支结构和循环结构,再加上子程序结构及中断服务子程序结构,共包含五种基本程序结构。
【4—5】顺序结构程序的特点是什么?
试用顺序结构编写三字节无符号数的加法程序段,最高字节的进位存入用户标志F0中。
【答】顺序结构是按照逻辑操作顺序,从某一条指令开始逐条顺序执行,直至某一条指令为止。
比如数据的传送与交换、简单的运算、查表等程序的设计。
顺序结构是所有程序设计中最基本、最单纯的程序结构形式,因而是一种最简单、应用最普遍的程序结构。
在顺序结构程序中没有分支,也没有子程序,但它是组成复杂程序的基础和主干。
例如:
三字节无符号数的加法程序段,最高字节的进位存人用户标志FO中。
假设加数存放在内存20H、21H和22H中,被加数存放在内存3OH、31H和32H中,和存放在内存40H、41H和42H中。
数据存放次序为低字节在前。
MOVA,30H;取被加数低字节数
ADDA,20H;求和
M0740H,A;和存入
MOVA,31H
ADDCA,21H;带进位求和
MOV41H,A
MOVA,32H
ADDCA,22H;带进位求和
MOV42H.A,
MOVF0,C;最高字节的进位存入用户标志F0中
【4—6】80C51单片机有哪些查表指令?
它们有何本质区别?
请编写按序号i值查找Di(16位长度)的方法。
设值i存放在R7中,将查找到的数据存放于片内RAM的30H、31H单元中。
请画出程序流程图,编写查表程序段,加上必要的伪指令,并对源程序加以注释。
【答】80c51有两种查表指令,即近程查表指令“MOVCA,@A+PC”和远程查表指令“MOVCA,@AA+DPTR"这两条指令的功能均是从程序存储器中读取数据(如表格、常数等),执行过程相同,其差别是基址不同,因此,适用范围也不同。
累加器A为变址寄存器,而PC、DPTR为基址寄存器。
DPTR为基址寄存器时,允许数表存放在程序存储器的任意单元,称为“远程查表”,编程比较直观;而PC为基址寄存器时,数表只能放在该指令单元往下的256个单元中,称为“近程查表”。
编程时需要计算累加器A中的值与数表首址的偏移量。
例如,按序号i值查找Di(16位长度)的源程序如下所示:
ORGXXXXH
MOVDPTR,#TABLE指向表首址
MOVA,R7;取值i
RLA;Di为二个字节
MOVR7,A;ix2
MOVCA,@A+DPTR;查表获得Di的高字节
MOV30H.A
MOVA,R7
INCA指向表的下一个地址
MOVCA,@A+DPTR;{表获得Di的低字节
MOV31H,A
TABLE:
Dw……;表(Dw为双字节,高字节在前)
RET
查表程序流程图如图4-1所示。
【4—7】根据运算结果给出的数据到指定的
数据表中查找对应的数据字。
运算结果给出的
数据在片内RAM的40H单元中,给出的数据大
小在00~0FH之间,数据表存放在20H开始的
片内存储器中。
查表所得数据字为双字节(高字
节在后),高字节存于42H、低字节存于41H单
元。
其对应关系为:
给出数据:
00H01H02H…0DH0EH0FH
对应数据:
00A0H7DC2HFF09H…3456H89ABH5678H
请编制查表程序段,加上必要的伪指令,并加以注释。
【答】程序如下:
ORG0000H
AJMPMAIN,
0RG0020H
TAB:
DBOAOH,OOH,0C2H,7DH,09H,OFFH,...,56H,34H,0.ABH,89H,DB78H,56H;数据字表
ORG0050H
MAIN:
MOVA,40H;运算结果给出的数据放在40H中
MOVDPTR,#TAB;指向数据字表首地址
RLA;由于是双字节,所以A左移1位(乘2)
MOV40H,A;结果放在40H’
MOVCA,@A+DPTR;查表,找出对应的值
MOV41H,A;查找出的数据值低字节放入41H
MOVA.40H
ADDA,#01H;查找数据的高位字节
MOVDPTR,#TAB
MOVCA,@A+DPTR
MOV42H,A。
;查找出的数据值高字节放入42H
SJMP$
注意:
数据表存放在20H开始的片内存储器中,该存储器应为内部程序存储器,因为查表指令MOVC的功能是从程序存储器中读数据。
【4—8】什么是分支结构程序?
8OC1的哪些指令可用于分支结构程序编程?
有哪些多分支转移指令?
由累加器A中的动态运行结果值进行选择分支程序,分支转移指令选用LJMP,请编写散转程序段和画出程序流程图,加上必要的伪指令,并加以注释。
【答】分支结构程序的主要特点是程序执行流程中必然包含有条件判断指令。
符合条件要求和不符合条件要求的有不同的处理路径。
编程的主要方法和技术是合理选用具有逻辑判断功能的指令。
在程序设计时,往往借助程序框图(判断框)来指明程序的走向。
一般情况下,每个分支均需要单独执行一段程序,对分支程序的起始地址赋予一个地址标号,以便当条件满足时转向指定地址单元去执行程序,条件不满足时仍顺序往下执行程序。
80C51的条件判跳指令极其丰富,功能极强,特别是位处理判跳指令,对复杂问题的编程提供了极大方便。
程序中每增加一条条件判跳指令,就应增加一条分支。
分支结构程序的形式有单分支结构和多分支结构两种。
①在80C51指令系统中·可实现单分支程序转移的指令有位条件转移指令,如JC、JNC、
JB、JNB和JBC等,还有一些条件转移指令,如JZ、JNZ和DJNZ等。
.
②80C51设有两条多分支选择指令。
(a)散转指令:
JMP@A+DPTR
散转指令由数据指针DPTR决定多分支转移程序的首地址,由累加器A中内容动态地选择对应的分支程序。
因此,可以从多达256个分支中选择一个分支散转。
(b)比较指令:
CJNEA,direct,rel(共有4条)
比较两个数的大小,必然存在大于、等于、小于三种情况,这时就需要从三个分支中选择一个分支执行程序。
例如:
由累加器A中的动态运行结果值进行选择分支程序,分支转移指令选用LJMP。
ORGXXXXH
MOVDPTR,#JPTAB;分支转移表首地址
CLRC
MOVB,A
RLCA
JNCTAB
INCDPTR
TAB:
ADDA,B;(A)*3
JNCTABLE
INCDPTR
TABLE:
JMP@A+DPTR;多分支转移
JPTAB:
LTMPLOOPl;长转移指令为3个字节
LJMPLOOP2
注意:
长转移指令为3字节,因此,A中内容应乘以3。
若大于一个字节,则DPH要加1。
分支程序流程图如图4-2所示。
【4-9】循环结构程序有何特点?
80C51的循环转移指令有什么特点?
何谓循环嵌套?
编程时应注意什么?
【答】循环是强制CPU重复多次地执行一串指令的基本程序结构。
从本质上看,循环程序结构只是分支程序中的一个特殊形式。
循环程序由4个部分构成,即循环初始化、循环体、循环控制和结束部分。
循环次数已知情况下,采用计数循环程序,其特点是必须在初始化部分设定计数的初值,循环控制部分依据计数器的值决定循环次数。
根据控制循环结束的条件,决定是否继续循环程序的执行。
所谓的结束条件可以是搜索到某个关键字(比如回车符CR),也可以是发生的某种变化(如故障引起电路电平变化)等,什么时候结束循环是不可预知的。
80C51设有功能强的循环转移指令:
DJNZRn,rel..;以工作寄存器作为控制计数器
DJNZdirect,rel.;以直接寻址单元作为控制计数器
CJNEA,direct,rel;比较不相等转移
这几条基本指令可派生出很多条不同控制计数器的循环转移指令,大大扩充了应用范围和多重循环层次。
循环嵌套就是在循环内套用循环的结构形式,也称“多重循环”。
循环的执行过程是从内向外逐层展开的。
内层执行完全部循环后,外层则完成一次循环,逐次类推。
层次必须分明,层次之间不能有交叉,否则将产生错误。
编程时要注意循环的正确退出,要防止出现“死循环”。
【4-10】什么是子程序?
它的结构特点是什么?
什么是子程序嵌套?
【答】在编制应用程序时,往往将需要多次应用但完成的运算或操作相同的程序段,编制成一个子程序,并尽量使其标准化,存放于某存储区域。
调用子程序的程序称为“主程序”或“调用程序”。
子程序是由专门的子程序调用指令CALL调用,而以子程序返回指令RET结束的程序
段。
子程序的第一条指令地址,通常称为“子程序首地址”或“人口地址”,往往采用标号(可用助记符)加以表示,调用(转子)指令的下一条指令地址,通常称为“返回地址”或“断点”。
在子程序中调用子程序的现象通常称为子程序嵌套。
【4-11】手工汇编下列程序:
KEYEQU20H
ORG2000H
MOVRO,#30H;数据区首址
MOVRl,#16;数据区长度
MOV20H,#KEY;关键字送20H单元
CLRF0;清用户标志位
MOV21H,#0l;序号置l
LP:
MOVA,@R0;取数
CJNEA,20H,LP1.
SJMPHERE;找到关键字,结束.
LPI:
INC21H;序号加1
INCR0;数据区地址指针加1
DJNZR1,LP;继续
SETBF0;未搜索到关键字,则置位用户标志
HERE:
SJMPHERE
【答】根据指令查指令表得到机器码,手工汇编结果如下:
KEYEQU20H
ORG2000H
20007830MOVR0,#30H;数据区首址
20027910MOVR1,#16;数据区长度
2004752020MOV20H,#KEY;关键字送20H单元
2007C2D5CLRF0;清用户标志位
2009752101MOV21H,#01;序号置1
200CE6LP:
MOVA,@R0;取数
200DB52002CJNEA,20H,LPI
20108007SJMPHERE;找到关键字,结束
20120521LPI:
INC21H;序号加1
201408INCR0;数据区地址指针加1
2015D9F5DJNZR1,LP;继续
2017D2D5SETBF0;未搜索到关键字,则置位用户标志
201980FEHERE:
SJMPHERE
【4-12]把长度为10H的字符串从内部RAM的输入缓冲区INBUF向设在外部RAM的输出缓冲区OUTBUF进行传送,一直进行到遇见字符“CR"时停止。
若字符串中无字符“CR”,则整个字符串全部传送。
加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
ORG0000H
AJMPMAIN
ORG0030H
MAIN:
MOVR7,#10H;数据长度
MOVR0,#INBUF;源数据首地址
MOVDPTR,#OUTBUF;目的数据首地址
LOOP:
MOVA,@R0;把源数据的值赋给A
CJNEA,#0DH,LOOPl;判断是否为“CR”(ASCII码值为0DH)
SJMPENDl;是“CR",则结束传送
LOOPl:
MOVX@DPTR,A;把A的值赋给目的数据
INCR0;源数据下一个地址值
INCDPTR;目的数据下一个地址值
DJNZR7,L00P;判断数据传送是否完毕
ENDI:
SJMPENDI
END
【4-13】内部RAM从2OH单元开始存放一个正数表,表中之数为无序排列,并以“-1”作为结束标志。
编程实现在表中找出最小正数,存入10H。
加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
ORG0000H
AJMPMAIN
ORG0030H
MAIN:
MOVR0,#20H;正数表首址
MOV10H,#7FH;初始值设为正数最大值
LOOP:
MOVA,@R0
CJNEA,“-1’’,CHK;比较结束标志“-1”
SJMPEND1;是“-l",结束比较
CHK:
CJNEA,10H,CHKI;比较两个数大小
SJMPLOOP1;两个数相等,不交换
CHKI:
JNCLOOP1;A较大,不交换
MOV10H,A;A较小,交换
LOOP1INCR0
SJMPLOOP‘
END1:
SJMPEND1
END
例如:
已知(20H)=22H,(21H)=23H,(22H)=0CH,(23H)=20H,(24H)=16H,(25H)=-1。
执行结果:
(10H)=0CH
【4-14】比较两个ASCII码字符串是否相等。
字符串的长度在内部RAM的2H单元,第一个字符串的首地址在30H中,第二个字符串的首地址在50H中。
如果两个字符串相等,则置用户标志FO为0;否则,置用户标志FO为1。
加上必要的伪指令,并对源程序加以注释(每个ASCII码字符为一个字节,如ASCII码“A”表示为41H)。
LOOPl:
MOVX@DPTR,A;把A的值赋给目的数据
INCR0;源数据下一个地址值
INCDPTR;目的数据下一个地址值
DJNZR7,L00P;判断数据传送是否完毕
ENDI:
SJMPENDI
END
【答】字符串中每一个字符都可以用一个ASCII码表示。
只要有一个字符不相同,就可以判断字符串不相等。
ORG0000H’
AJMPMAIN·
ORG0030H
MAIN:
MOVR0,#30H第一个字符串的首地址
MOVR1.,#50H第二个字符串的首地址
LOOP:
MOVA,@R0第一个字符串的字符值赋给A
MOVB,@R1;第二个字符串的字符值赋给B
CJNEA,B,NEXT;两个字符值比较
INCR0字符值相等,则继续比较
INCR1.
DJNZ20H,LOOP;判断字符串是否比较完
CLRF0字符串相等,则F0位清0
SJMP$
NEXT:
SETBF0字符串不等,则F0位置1
SJMP$
END
例如:
(2OH)=03H,(3OH)=41H,(31H)=42H,(32H)=43H,(5OH)=41H,(51H)=
42H,(52H)=43H。
两个字符串均为“ABC"。
执行结果:
F0=0
【4—15】已知经A/D转换后的温度值存在40H中,设定温度值存在41H中。
要求编写控制程序,当测量的温度值大于(设定温度值+2℃)时,从P1.0引脚上输出低电平;当测量的温度值小于(设定温度值一2℃)时,从P1.0引脚上输出高电平;其他情况下,P1.0引脚输出电平不变(假设运算中C中的标志不会被置1)。
加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
ORG0000H
AJMPMAIN
ORG‘0020H
MAIN:
.
MOVB,41H;设定的温度值
MOVA.B
ADDA,#02H
MOVB,A;设定温度值+2℃
MOVA,40H;测量的温度值
CLRC
SUBBA,B
JNCLOWER;测量的温度值>(设定温度值+2℃),转LOWER子程序,使P1.0引脚上输出低电平
MOVB,41H;设定的温度值
MOVA,B
DECA
DECA.
MOVB,A;设定温度值一2℃
MOVA,40H;测量的温度值
CLRC
SUBBA,B
JCHIGH;测量的温度值<设定温度值-2℃,转HIGH子程序,使P1.0引脚上输出高电平
SJMP$;都不是,则P1.0引脚上输出不变
LOWER:
CLRP1.0
SJMP$
HIGH:
SETBP1.0’
SJMP$
END
【4—16】80C51单片机从内部RAM的31H单元开始存放一组8位带符号数,字节个数存放在30H中。
请编写程序统计出其中正数、0和负数的数目,并把统计结果分别存入20H、21H和22H三个单元中。
加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
LENGTHEQU30H;数据长度
DATA_ADREQU31H;数据首地址
POS_NUMEQU20H;正数个数
ZERO_NUMEQU21H;0个数
NEG_NUMEQU22H;负数个数
ORG0000H
AJMPMAIN,
ORG0030H
MAIN:
MOVPOS_NUM,#0;计数单元初始化为0
MOVZERO_NUM,#0
MOVNEG_NUM,#0
MOVR1,#LENGTH;数据长度
MOVR0,#DATA_ADR;数据首地址
LOOP:
MOVA,@R0.
JBACC.7,INC_NEG;符号位为1,该数为负数,跳转加1
CJNEA,#0,INC_POS
INCZERO_NUM;该数为0,0个数加1
AJMPL00P1
INCNEG:
INCNE~_NUM;负数个数加1
AJMPLOOPl.
INC_POS:
INCPOS_NUM;该数为正数,正数个数加1
LOOPl:
INCR0;判断统计是否结束
DJNZR1,LOOP
END
例如:
已知(30H)=08H,31H单元起存放数据为00H,80H,7EH,6DH,2FH,34H,
EDH,FFH。
执行结果:
(20H)=04H,(21H)=01H,(22H)=03H。
【4-17]两个10位的无符号二一十进制数,分别从内部RAM的40H单元和50H单元开始存放。
请编程计算该两个数的和,并从内部RAM的60H单元开始存放。
加上必要的伪指令,并对源程序加以注释。
【答】10位的无符号二~十进制数,占5字节,每个字节存放一个压缩BCD码(2位)。
ORG0000H