单片机部分答案第四版北航马忠梅.docx
《单片机部分答案第四版北航马忠梅.docx》由会员分享,可在线阅读,更多相关《单片机部分答案第四版北航马忠梅.docx(16页珍藏版)》请在冰豆网上搜索。
单片机部分答案第四版北航马忠梅
已知(A)=7AH,(R0)=30H,(30H)=A5H,PSW=80H。
问执行(单独执行)以下各指令的结果
XCHA,R0;A=30H,R0=7AH
XCHA,30H;A=A5H
XCHA,@R0;A=A5H
XCHDA,@R0;A=75H;二者低4位互换
SWAPA;A=A7H;A高低4位互换
ADDA,R0;A=AAH,Cy=0,OV=1(a6a7=1)
ADDA,30H;A=1FH,Cy=1,OV=0
ADDA,A,#30H;A=AAH,Cy=0,OV=1;
ADDCA,30H;A=20H,Cy=1,OV=0;因为PSW的Cy=1
SUBBA,30H;A=D4H,Cy=1,OV=1;因为PSW的Cy=1
SUBBA,#30H;A=49H,Cy=0,OV=0;因为PSW的Cy=1
已知(A)=83H,(R0)=17H,(17H)=34H。
执行以下指令后A=?
ANLA,#17H;逻辑与(A)=03H
ORL17H,A;逻辑或(17H)=37H
XRLA,@R0;异或(A)=34H
CPLA;取反(A)=CBH
将内部RAM20H、21H、22H,连续三个单元的内容以此放入
2FH、2DH、2EH单元
MOVR0,#20H
MOVR1,#2FH
LOOP:
MOVA,@R0
MOV@R1,A
INCR0
DECR1
CJNER0,#23H,LOOP
SJMP$
外部数据RAM在2000H~2100H区域有一个数据块,将他们移动到3000H~3100H区域
解一:
MOVDPTR,#2000H
MOVP2,#30H
MOVR1,#00H
LOOP:
MOVXA,@DPTR
MOVX@R1,A
INCDPTR
INCR1
CJNER1,#00H,LOOP
INCP2
MOVXA,@DPTR
MOVX@R1,A
解二:
MOVDPTR,#2000H
MOVP2,#30H
MOVR1,#00H
LOOP:
MOVXA,@DPTR
MOVX@R1,A
INCDPTR
INCR1
CJNER1,#00H,LOOP
INCP2
MOVA,DPH
CJNEA,#21H,NEXT
NEXT1:
MOVXA,@DPTR
MOVX@R1,A
SJMP$
NEXT:
INCDPTR
SJMPNEXT1
解三:
MOVDPTR,#2000H
MOVR5,#00H
MOVA,#00H
MOVR1,A
LOOP:
MOVA,R1
MOVXA,@A+DPTR
MOVX@R0,A
MOVDPTR,#3000H
MOVA,@R0
MOVX@A+DPTR,A
INCR1
DJNZR5,LOOP
MOVDPTR,#2100H
MOVXA,@DPTR
MOVDPTR,#3100H
MOVX@DPTR,A
外部数据RAM从2000H开始有100个数据块,将他们移动到2030开始的单元
解一:
MOVDPTR,#2000HMOVR4,#64H
MOVP2,#10HLOOP1:
MOVXA,@R1
MOVR1,#00HMOVX@DPTR,A
MOVR4,#64HINCR1
LOOP:
MOVXA,@DPTRINCDPTR
MOVX@R1,ADJNZR4,64H,LOOP1
INCDPTR
INCR1
DJNZR4,64H,LOOP
MOVDPTR,#2030H
MOVP2,#10H
MOVR1,#00H
解二:
MOVDPTR,#2000HMOVR3,#64H
MOVP2,#10HDJNZR3,LOOP
NEXT:
MOVR1,#00HSJMP$
MOVR4,#64H
LOOP:
MOVXA,@DPTR
MOVX@R1,A
INCDPTR
INCR1
NEXT1:
DJNZR4,LOOP
LOOP1:
MOVDPTR,#1000H
MOVP2,#20H
MOVR1,#30H
习题参考答案
习题3.8051主要的存储空间是什么?
为什么两个RAM的空间不同?
答:
8051单片机的存储空间分为数据RAM和代码ROM,其中数据RAM又分为片内RAM和片外RAM。
片内RAM的地址为8位,由单片机指令直接在单片机内部寻址访问,而片外RAM的地址为16位,只能由单片机的MOVX指令通过外部总线访问。
习题4.编一段程序,把8位口新的输入值和前一次的输入值进行比较,然后产生一个8位数。
这个数中的位为“1”的条件是:
仅当新输入的位为“0”,而前一次输入的位为“1”。
答:
设该8位口为P1,新产生的8位数为x:
unsignedcharx;
x=P1;
x&=~P1;
习题6.按给定的存储类型和数据类型,写出下列变量的说明形式:
up,down整数,使用堆栈存储;
first,last浮点数,使用外部数据存储器存储;
cc,ch字符,使用内部数据存储器存储。
答:
堆栈只能存储内部RAM字节内容,必须在idata区:
(复位后SP=07H,但是07H中存放堆栈地址,上电复位后典型寄存器的值?
)
intidataup,down;
floatxdatafirst,last;
charidatacc,ch;或chardatacc,ch;
习题7.
判断下列关系表达式或逻辑表达式的运算结果(1或0)
1、10==9+1;1
2、0&&0;0
3、10&&8;1
4、8||0;1
5、!
(3+2);0
6、设x=10,y=9;x>=8&&y<=x;1
习题8.
设x=4,y=8,说明下列各题运算后,x,y和z的值分别是多少?
1、z=(x++)*(--y);x=5,y=7,z=28
2、z=(++x)-(y--);x=5,y=7,z=-3
3、z=(++x)*(--y);x=5,y=7,z=35
4、z=(x++)+(y--);x=5,y=7,z=12
习题9.分析下列运算表达运算顺序。
1、c=a||(b);(b)是为0或1(逻辑值),若a=0则a||(b),结果赋给c
2、x+=y-z;y-z,x+(y-z),结果赋给x
3、-b>>2;-b,结果右移2位。
注:
-b不是取反也不能确定为负数;取反一般是变成2进制然后按位取反。
如b=-3,即0FDH,则-b=3,而不是0FD按位取反
4、c=++a%b--;a=a+1,a%b,b=b-1,%结果赋给c
5、!
m&n;!
m,若结果为1再和n相与。
X(不是&&)
!
m,再和n相与
6、a
习题参考答案
习题6.用选择分支编写程序,把输入的一个数字按下列对应关系显示。
当输入Z时,程序结束。
#include<>
#include<>
main()
{
unsignedchark;
do
{
scanf(“%c”,&k);
switch(k)
{
case‘1’:
printf(“A”);break;
case‘2’:
printf(“B”);break;
case‘3’:
printf(“C”);break;
case‘4’:
printf(“D”);break;
default:
printf(“?
”);break;
}
}while(k!
=‘Z’);
while
(1);
}
习题7.若在C中的switch操作漏掉break,会发生什么?
答:
若在case语句中漏掉break,则程序执行case选择部分程序后不会按照要求退出switch语句,而是继续执行下一个case语句选择的内容。
习题8.编写程序,输出x3数值表,x为0—10。
main()
{
unsignedcharx;
unsignedinty;
for(x=0;x<11;x++)
{
y=(unsignedint)x*x*x;
printf(“%c,%d\n”,x,y);
}
while
(1);
}
习题9.用三种循环方式分别编写程序,显示1—100的平方。
答:
三种流程图如下:
#defineuintunsignedint
main()
{
unsignedinty;
unsignedcharx;
for(x=0;x<101;x++)
{
y=(unsignedint)x*x;
printf(“%c,%d\n”,x,y);
}
while
(1);
}
main()
{
unsignedinty;
unsignedcharx=1;
while(x<101)
{
y=(unsignedint)x*x;
printf(“%c,%d\n”,x,y);
x++;
}
while
(1);
}
main()
{
unsignedinty;
unsignedcharx=1;
do
{
y=(unsignedint)x*x;
printf(“%c,%d\n”,x,y);
x++;
}while(x<101);
while
(1);
}
习题9.写出下列数组使用*运算的替换形式。
[2];[i+1];[5][3]。
1、*(data+2)p107
2、*(num+i+1)
3、*(*(man+5)+3)
习题10.设下列运算表达式中p是指针,试分析各表达式的运算顺序。
=*p--;=*p++;
[++i]=*p++;=*--*++p-6。
答:
1、先取*p给b,再使p减1单元(注意不是*p减1单元);
2、先取*p给x,再使p加1单元(注意不是*p加1单元);
3、先使i加1,再取*p给a[i],再使p加1单元;
4、这里p是指针的指针,先使p加1单元,再使*p减1单元,再使*(*p)减6后赋给y;
习题12.结构的定义和说明在程序中的作用是什么?
在对结构初始化时应该注意些什么问题。
答:
结构的定义和说明在程序中可以把一组关系密切的变量存放在一个连续的存储空间中,便于对这些变量的访问。
同一个结构中不能存在同名变量名称。
可以把具有相同结构的已知结构直接用“=”对结构进行赋值,或者通过其成员的逐个引用分别赋值。
在没有赋值前结构成员的值是不确定的,有可能被编译器启动代码初始化为0。
习题14.使用union的目的是什么?
定义union,它用于容纳下列数据:
intdata[4];
charch[8];
floatf。
答:
使用union的目的之一是若干个不会同时使用的变量公用存储单元,以便节省存储空间。
同一个union中不能存在同名变量名称。
uniondata_type
{
intdata[4];
charch[8];
floatf;
}mydata;
习题参考答案
习题1.C语言中,函数的存储类型和数据类型的意义是什么?
答:
一,函数存储类型有extern(外部函数)和static(内部函数或静态函数)。
在没有任何存储类说明的情况下函数都是全程序可见的,即函数的默认存储类特性为extern。
Static存储类使函数对对其所在的文件定义之前的部分和非定义文件是不可见的,不能调用的。
二,数据类型是说明函数的返回值类型。
包括简单类型(char,unsignedchar,int,unsignedint,long,unsignedlong,float,bit),复合型(stuct,union)
和无类型(void)
习题3.作为函数形式参数使用的数组名具有什么特征?
它们的使用特点是什么?
1、当用数组作为函数的参数时,应当在调用函数和被调用函数中分别定义数组;
2、实参数数组与形式参数数组的类型应当一致;
3、实参数数组与形式参数数组的大小可以一致,也可以不同,用户需自行考虑数组的边界问题。
习题5.当一个函数需要返回多于一个值时,可以怎么做?
可以通过返回指针实现,先把需要返回的所有数据连续存放在一段存储空间中,让该指针指向其首地址,然后返回该指针。
•7.编写字符串字符替换函数replchr(s,c1,c2),把字符串s中的c1置换为c2
•voidreplchr(char*s,charc1,charc2)
•{chari=0,temp;
•while(s[i]!
='\0')
•{
•if(s[i]==c1){
•temp=c1;
•c1=c2;
•c2=temp;}
•else
•s++;写把十六进制字符串s变换成整数值返回的函数htoi(s)
#include“”
#include“”
inttranslat(charc)写函数itob(n)。
它把整数n变换成二进制字符串,并返回字符串地址。
unsignedcharp[17];
unsignedchar*itob(intn)
{unsignedchari=0;
unsignedintm;
if(n<0)
{p[i++]=’-’;
m=-n;
}
elsem=n;
do
•{p[i++]=(m&0x8000)?
’1’:
’0’;写把字符串s逆转的函数reverse(s).
voidreverse(unsignedchar*s)
{
unsignedchari,s[],n;
for(i=0;i<(n-1)/2;i++)
{
t=s[i];
s[i]=s[n-1-i];
s[n-1-i]=t;
}
}
例:
s[10]=“0”或”abcdefghi”
s[11]=“09”或”abcdefghij”
习题11.编写把字符串s逆转的递归函数reverse(s)。
答:
使用reverse(s,strlen(s)-1)即可实现
unsignedchars=“abcdefg”;
voidreverse(unsignedchar*p,unsignedchari)
{
unsignedcharn=p[0];
p[0]=p[i];
p[i]=n;
if(i>2)reverse(p+1,i-2);
}
习题12.设计并初始化一个具有2个元素的2维数组保存图画(如正方形)的X-Y坐标值。
然后设计一个画图函数。
标明怎样调用函数画正方形。
#include<>
unsignedcharG[1][2]={1,2};用图11-3的接口电路,编写由ADC0809的通道6连续采集20个数据放在数组中的程序
解一:
#include<>
#include<>
#defineIN6XBYTE[0x7ffe]/*设置ADC0809的通道6地址*/
sbitad_busy=P3^3;/*即EOC状态*/
charad0809(void)/*A/D采集函数*/
{uchari;
IN6=0;/*启动转换*/
i=i;i=i;/*延时等待EOC变低*/
while(ad_busy==0);/*查询等待转换结束*/
return(IN6);
}
voidmain(void)
{staticucharidataad[20];
ucharj;
for(j=0;j<20;i++){ad[j]=ad0809();}/*20次采样ADC0809通道6的值*/
}
解二:
#include<>
#include<>
#defineucharunsignedchar
#defineIN6XBYTE[0xfffe]/*设置ADC0809的通道6地址*/
sbitad_busy=P3^3;/*即EOC状态*/
voidad0809(ucharidata*x)/*采样结果放指针中的A/D采集函数*/
{uchari;
ucharxdata*ad_adr;
ad_adr=&IN6;
for(i=0;i<20;i++)/*20次采集*/
{*ad_adr=0;/*启动转换*/
i=i;/*延时等待EOC变低*/
i=i;
while(ad_busy==0);/*查询等待转换结束*/
x[i]=*ad_adr;/*存转换结果*/
}
voidmain(void)
{staticucharidataad[20];
ad0809(ad);/*采样ADC0809通道的值*/
}
4.对0809进行数据采集编程。
要求对8路模拟量连续采集24h,每隔10min采集一次,数据存储在外部数据存储区中。
解:
图11-3
#include<>
#include<>
#defineucharunsignedchar
#defineuintunsignedint
#defineIN0XBYTE[0x7ff8]/*设置ADC0809的通道0地址*/
sbitad_busy=P3^3;/*即EOC状态*/
uintoverflow_count=0;/*T1中断次数初值*/
voidad0809(ucharxdata*x)/*采样函数,结果x[]放外部数据存储器*/
{uchari;
ucharidata*ad_adr;
ad_adr=&IN0;
for(i=0;i<8;i++)/*处理8通道*/
{*ad_adr=0;/*启动转换*/
i=i;/*延时等待EOC变低*/
i=i;
while(ad_busy==0);/*查询等待转换结束*/
x[i]=*ad_adr;/*存转换结果*/
*(*(p+j)+i)=x[i];
ad_adr++;/*下一通道*/
}
}
/*定时器1中断服务程序;每100ms执行一次,fosc=6MHz*/
voidtimer1_ISR(void)interrupt3
•{TH1=(65536–50000)/256;于频率测量,何时采用频率测量法,何时采用周期测量法?
解:
频率较高时,采用频率测量法;
频率较低时,采用周期测量法;
这样就可以提高测量精度