NEXT: INC
DJNZ MOV SJMP END
R0 $
;修改地址指针
;计数器减1,非0,则继续
;保存O的个数计数值到50H单元 ;暂停
R7,CONT
50H,R6 END
6.已知A=83H,R0=17H,(17H)=34H,写出下列程序段执行之后的A中的内容。 ANL ORL XRL CPL A
END
ANL ORL XRL CPL
A
A,#17H 17H,A A,@R0
;A=03H
;A= 0000 0011 ∨ 0011 0111 =0011 0100
答:
;(17H)=0011 0100 ∨ 0000 0011=0011 0111 ;A=1100 1011
A,#17H 17H,A A,@R0
7.已知单片机的晶振频率为12MHz,分别设计延时为0.1s、1s的子程序。
答:已知单片机的晶振频率为12MHz,则机器周期为1us,延时子程序是通过执行指令序列中机器周期数来达到,如果要0.1s,即100ms,也就是100000us,所以需要机器周期数达到100000。要延时达到1S,可通过对延时为0.1秒的子程序调用10次来实现。 DELAY100MS: D1: D2:
DELAY1S: LOOP:
MOV DJNZ RET
R7,#10
;计数10次
1 99795+2
ACALL DELAY100MS
R7,LOOP
;延时100ms子程序
NOP
MOV R6,#200
;1个机器周期
MOV R7,#250
;1个机器周期
;1个机器周期
DJNZ R7,D2 ;2个机器周期,3*251=753
DJNZ R6,D1 ;2个机器周期,(1+753+2)*132=99792 RET
;2个机器周期,1+99792+2=99795,约100ms
;未达到10次则继续 10*(2+99795+2) ;返回2+10*(2+99795+2)=997992
8.内部RAM从20H单元开始处有一数据块,以ODH为结束标志,试统计该数据块的长度,将该数据块送到外部数据存储器7E01H开始的单元,并将长度存入7E00H单元。 解:从20H的指针用R0,从外部RAM7E01开始的指针用DPTR,计数器用R7
MOV MOV MOV
R7,#0
;字节计数器赋初值 ;设片外RAM地址指针初值
R0,#20H
;设片内RAM地址指针初值
DPTR,#7E01H
CONT: MOV
INC INC INC CJNE MOV SJMP END
A,@R0
;取片内RAM中的一个字节
MOVX @DPTR,A
R7 R0 DPTR $
;存入片外RAM指针所指单元 ;长度计数器加1 ;片内RAM地址指针加1 ;片外RAM地址指针加1 ;未达到结束标志
;取块计数长度值 ;保存 ;暂停
A,#0DH,CONT
A,R7
MOVX @DPTR,A
9.内部RAM从DATA开始的区域中存放着10个单字节十进制数,求其累加和,并将结果存入SUM和SUM+1单元。
解:R7计数,R6保存累加和高8位,R0用作地址指针
ORG LJMP ORG
A A NEXT R6 R0 $
;若无进位则不用管高8位 ;有进位,高8位加1 ;片内RAM地址指针加1 ;未完继续
;保存低8位 ;保存高8位
0000H 100H 40H R7,#10
;字节计数器赋初值 ;设片内RAM地址指针初值 ;累加结果的高8位
;加RAM中的一个字节到ACC
R0,#DATAA R6,A
30H
MAIN
SUM
EQU
DATAA EQU MAIN: MOV
MOV CLR MOV DA JNC INC DJNZ MOV MOV SJMP END
;累加器清0
CONT: ADD A,@R0
NEXT: INC
R7,CONT
SUM,A SUM+1,R6
;暂停
10.内部RAM从DATA1和DATA2单元开始处存放着两个等长的数据块,数据块的长度在LEN单元中。请编程检查这两个数据块是否相等,若相等,将0FFH写入RESULT单元,否则将0写入RESULT单元。
解:从DATA1开始的指针用R0,从DATA2开始的指针用R1,计数器用R7 LEN
EQU
10 30H
DATA1 EQU
DATA2 EQU RESULT EQU
MOV MOV MOV MOV CJNE INC INC DJNZ MOV SJMP
40H 50H R7,#LEN
;字节计数器赋初值
;设片内RAM地址指针初值 ;设片外RAM地址指针初值 ;取片内RAM R0所指的的一个字节
;将R1所指单元内容取到片内RAM地址7FH中
R0,#DATA1 R1,#DATA2 A,@R0 7FH,@R1
CONT: MOV
A,7FH,NOEQ R0 R1 $
;比较,不相等则结束 ;DATA1 RAM地址指针加1 ;DATA2 RAM地址指针加1 ;未完,继续 ;相等,准备写入FFH ;转写入结果处 ;不相等,准备写入00H
;保存比较结果标志 ;暂停
R7,CONT DOWN
A,#0
A,#0FFH
NOEQ: MOV DOWN: MOV
SJMP END
RESULT,A
11.编制程序,将内部RAM中M1、M2、M3和M4单元中的无符号数xl、x2、x3和x4相加,并把和存入RO和R1(R0中为高8位)中。 解: M1 M2 M3 M4
EQU EQU EQU EQU MOV ADD JNC MOV JNC INC JNC INC SJMP END
30H 40H 45H 4FH A,M1 A,M2 R0,#1 A,M3
;取第一个数 ;与第二个数相加 ;有进位,高8位置1 ;与第三个数相加
NEXT1 ;如果无进位,则转移至第三个相加
NEXT1: ADD
NEXT2 R0
A,M4
;没有进位,则转至第四个数相加 ;有进位,高8位加1
;与第四个数相加 ;没有进位,则转至结束 ;有进位,高8位再加1
;低8位保存到R1 ;暂停
NEXT2: ADD
NEXT3 R0 $
R1,A
NEXT3: MOV
第4章 单片机的C51语言 习题
1.C语言的优点是什么?C程序的主要结构特点是什么?
答:C语言是一种高级语言,学习比低级容易,不需要具体组织、分配存储器资源和处理端口数据,可以直接驱动单片机的所有资源。
C程序以函数为单位,由一个主函数和若干个其他函数构成,主函数是程序的入口,其他函数由主函数直接或间接调用。程序可以由一个文件或多个文件组成。文件类型包括头文件和C语言源文件,也可以是汇编语言文件,C程序可与汇编语言混合编程。
2.C51语言的变量定义包含哪些关键因素?为何这样考虑? 答:C语言的变量定义格式如下:
[存储种类] 数据类型 [存储类型] 变量名 其中:
存储种类与标准C语言相同,包括:自动型(auto)、外部型(extern)、静态型(static)、寄存器型(register)。
数据类型除了包含标准C语言类型的字符型(char),整型(int),长整型(long),浮点型(float),双精度型(double)外,还有二进制位型(bit),特殊功能寄存器型(sfr),SFR可位寻址的位类型(sbit)。
存储类型包括:片内RAM区(data)、片内可位寻址区(bdata),片内RAM间接寻址区(idata),片外RAM页寻址区(pdata),片外RAM区(xdata)、ROM区(code)。
只所以比标准C语言多了存储类型,就是因为MCS-51单片机的存储结构中有四个物理存储空间(片内RAM、片内ROM,片外RAM,片外ROM),三个逻辑地址空间(片内RAM,片外RAM,ROM),而且有多种寻址方式(直接寻址、间接寻址、页面寻址、位寻址)所致,所以在定义变量时,要根据其所在位置和寻址方式明确指定存储类型。
3.C51与汇编语言的特点各有哪些?怎样实现两者的优势互补?
答:C51是结构化语言,代码紧凑;接近自然语言,程序可读性强,易于调试、维护;库函数丰富,编程工作量小,可使产品开发周期短;具有机器级控制能力,功能很强,适合于嵌入式系统开发;汇编指令无关,易于掌握,上手快。
汇编语言优点是编写的程序代码精炼、执行速度快,在相同功能下,汇编语言程序可能比C语言程序效率高。缺点是对程序员要求高,必须对单片机的硬件结构非常熟悉才能编程,不便于编写比较复杂的程序。
可根据需要对要求时间性很强的代码用汇编语言编写,其它部分用C语言编写,两者混合编程就可以实现优势互补。
4.指出下面程序的语法错误: #include
int a=7,C delay(10) void delay();{ cgar i;
for(i=O; i<=255; ”++”); } 答:
#include
//a和C必须先定义才可使用 //缺分号,应该提在使用前说明
//延时子程序必须先定义,或先有函数原型说明
delay(10) void delay();{
//作为函数定义,有函数定义不能嵌套的问题,
//即不能在一个函数内定义另一个函数,而且“{”前不应有分号 //作为函数原型说明,应该放在函数调用之前,且其后不应该接函数体 cgar i; }
//主函数没有结束,缺”}”
5.定义变量a,b,c,其中a为内部RAM的可位寻址区的字符变量,b为外部数据存储区浮点型变量,c为指向 int 型 xdata 区的指针。 答:
6.编程将8051的内部数据存储器20H单元和35H单元的数据相乘,结果存到外部数据存储器中(任意位置)。
解:方法二:单用C语言编程实现 #include
unsigned int xdata x; unsigned char *ptr,a,b; ptr=0x25;
char bdata a; float xdata b; int xdata *c;
//字符型应该是unsigned char
for(i=O; i<=255; ”++”);// ”++”应改成i++