单片机第18、19讲

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机汇编语言程序设计
第一节相关术语
一、计算机语言
三类:完全面向机器的机器语言;非常接近机器语言的符号化语言;面向过程的高级语言。

■机器语言:能够被计算机直接识别和执行的语言,由“0”、“1”组成。

■汇编语言:使用助记符表示二进制指令的语言。

■高级语言:不依赖于具体计算机、面向问题或过程的语言,其形式类似于自然语言、数学公式等。

二、源程序与目标程序
■源程序:用汇编语言或高级语言编写出的程序。

对于汇编语言来说,一般以.ASM为程序文件的扩展名。

■目标程序:由机器语言(机器码)构成的、可为计算机直接识别、执行的程序。

一般以.OBJ为程序文件的扩展名。

三、汇编、编译、解释
■汇编:将汇编语言源程序转换成目标程序的过程。

人工汇编与机器汇编(后详)。

■编译:将高级语言源程序转换成目标程序、可执行程序(文件)的过程。

例如C语言的工作方式。

■解释:执行高级语言程序的另一种方式,逐条语句进行解释(生成该语句对应的机器码加以执行),但不生成目标程序。

例如BASIC语言的工作方式。

汇编语言程序具有运算效率高、目标程序小、占用内存少等特点,故在微处理器组成的测控系统中常采用汇编语言。

缺点:各种微处理器有各自的指令系统,程序不能互换。

四、汇编语言的指令格式(已在第三章中讲解,在此做简要说明)
{ [标号]:操作码助记符[第一操作数][,第二操作数] [,第三操作数] [;注释] ■标号是用符号表示的该指令在程序存储器中的地址,汇编源程序经汇编后标号将对应具有确定的数值(地址)。

标号一般是由字母打头的字母数字串(长度≤8)。

■操作码表示指令要实现的操作,用助记符表示。

例如:MOV、ADD、等。

77
■操作数表明了操作的对象,根据不同的操作码(指令功能),指令中的操作数可以有一、二、三
个,也可能没有操作数。

源操作数——操作时的操作对象。

目的操作数——操作的结果。

在单、双操作数指令中,通常指的是靠近操作码(左边)的那个操作数。

在MCS-51中,有时目的操作数与某个源操作数相同。

■注释部分是用户为了方便阅读程序所加的说明,可有可无。

}
第二节伪指令
伪指令:不被计算机执行的指令。

它们仅对汇编过程其辅助作用,对汇编过程进行控制。

汇编时伪指令不生成机器码。

一、设置目标程序在程序存储器中起始位置伪指令ORG
格式:ORG addr16
功能:指定此指令后的汇编程序所对应的目标程序代码在程序存储器中的存放地址。

例:
ORG 2000H
MOV A, 20H (机器码:E5 20)

程序存储器中,(2000H)=E5H;(2001H)= 20H;……。

说明:
■一个汇编程序中可以多次使用ORG指令,以按用户的意愿将不同模块的程序存放在程序存储器的不同区域中。

但一般应保证按程序的自然次序Add16从小到大,且应使汇编后各部分不发生重叠(举例说明)。

■程序的开始一般应设置一ORG指令,否则将默认为ORG 0000H。

■注意:在使用子程序或中断系统时,应通过ORG指令使主程序的存放区域避开中断向量区及子程序区。

二、汇编结束伪指令END
格式:[标号:]END
功能:结束汇编过程。

遇到END指令后,汇编系统将不对其后的程序进行汇编。

特别注意:END 一定要放在程序(包括子程序等)的最后!(这一点不同于C、BASIC语言中的END)
三、等(赋)值伪指令EQU
格式:字符符号EQU 常量或符号
功能:给指令中的字符符号赋予由后面的常量或符号所对应的值(包括数值或字符串)。

一旦定义
后,后面的程序中可以使用该字符符号代替对应的常量或符号。

因此,所有EQU指令一般均放在程序78
的最开始处。

例:
TIMES EQU #10H
AA EQU R6
MOV AA, TIMES
DELAY EQU 1234H
FLAG EQU 0D0H (FLAG等同于PSW)
四、定义字节伪指令DB
格式:[标号:] DB 8位二进制数表
功能:从标号指定的地址开始,连续定义若干个存储单元(字节)的内容(若无标号或ORG指令则表示从当前地址顺序存放)。

汇编后这些内容将在写EPROM时存放在指定的单元中。

该指令用来在程序存储器中存放一些必要的常量(如字形码等)。

例:
ORG 1000H
TAB: DB 23H, 73, “6”, “B”
TAB1: DB 110B
说明:若给出的内容为字符(”6”、”B”),则该指令将把该字符所对应的ASCII码存放到给定的单元。

五、定义字伪指令DW
格式:[标号:] DW 16位二进制数表
功能:从标号指定的地址开始,连续定义若干个存储单元(字)的内容(若无标号或ORG指令则表示从当前地址顺序存放)。

该指令与DB功能相似。

例:
ORG 2000H
TAB: 1234H, 0ABH, “MN”
注意:存放数据时,低地址存放高8位,高地址存放低8位。

上面的结果为:
(2000H)= 12H;(2001H)= 34H;
(2002H)= 00H;(2003H)= 0ABH
(2004H)= 4DH;(2005H)= 4EH (M、N的ASCII码)
六、预留存储区伪指令DS
格式:[标号:] DS 表达式
功能:从给定的标号地址、或ORG定义的地址、或本条指令的顺序地址开始,预留出由表达式之值确定的数个单元,供程序后用。

例如:
ORG 2000H
BUFF: DS 06H
79
CNT: MOV A,#30H
汇编后,从2000H开始,保留6个连续的存储单元,因此第三条指令的起始存放地址(标号CNT 所对应的地址)为2006H。

注意:伪指令DB、DW、DS都只对程序存储器起作用,不能用它们对数据存储器的内容进行赋值或其他初始化工作。

七、位地址定义伪指令BIT
格式:字符符号BIT 位地址
功能:用指定的字符符号代替指令中的位地址,在后面的程序中可用该符号表示对应的位地址。

例如:
A1 BIT P1.0
A2 BIT Acc.7
A3 BIT 20H.7
CLR A1
SETB A3
第三节汇编方式与汇编过程
汇编的方式有两种:人工汇编和机器汇编。

一、人工汇编
人工汇编指的是通过查表、伪指令说明、计算等逐条确定出指令的机器代码,从而得到目标程序的过程。

由于一般的应用程序中通常包括各种标号以及控制转移类指令,因此人工汇编过程通常分为两步:
1. 第一次汇编
查出各条指令所对应的机器码(教材p227附录A),根据ORG等伪指令和各条指令的字节数,确定出每条指令、每个字节的机器码在程序存储器中的存放地址。

说明:第一次汇编后,各指令、字节的汇编地址尚不能完全确定,因为
某些标号所对应的地址尚无法最后确定;
某些控制转移类指令代码中的相对偏移量尚无法确定,仍用标号表示。

2. 第二次汇编
依次求出各标号所对应的具体地址,进而计算出各相对偏移量,完成汇编。

举例:对连续存放在片内30H单元开始的16个单元的内容求和,结果放在2FH中。

80
说明:
■四条伪指令不生成机器代码,只在汇编时起辅助汇编的作用;
■第一次汇编时,标号地址LOOP、HERE保留着,以计算相对偏移量;
■第二次汇编时,DJNZ指令中的相对偏移量为-7,、SJMP指令中的相对偏移量为-2(一定要注意计算时要以当前指令执行结束后PC的内容为计算基准!);
■等值伪指令的功用;
■循环结构说明;数据存放地址指针的调整(INC R0,结合R0间址);DJNZ指令在循环控制中的应用。

人工汇编的缺点:在查机器码、计算偏移量、确定地址时非常容易出错;汇编效率低;不适用于程序较长的场合。

二、机器汇编
用特定的汇编程序在计算机上完成汇编工作。

汇编程序与指令系统是一一对应的。

机器汇编方法:交叉汇编(在PC机上)、驻留汇编(在仿真器上)。

机器汇编完成的任务:指令机器码的翻译;符号定义;相对偏移量计算与指令地址定位;生成目标程序和列表文件;等等。

目标程序(.OBJ):指令机器码的有序集合。

列表文件(.LST):包括汇编地址、指令机器码、源程序、汇编后的有关信息等。

81
82 汇编时若源程序有错误,则给出出错信息,停止汇编。

(有关机器汇编的方法、内容结合实验进行练习)
第四节 单片机汇编语言程序设计步骤与方法
1. 问题分析
2. 程序总体结构设计,确定算法
一般采用模块话设计,即主程序加若干功能子程序的结构。

MCS-51的许多算法都已模块化了,可直接作为子程序使用。

注意算法对执行速度、所需存储单元数量、代码长度的影响。

3. 画程序的流程图
根据任务及确定的程序结构、算法画流程图,是所有程序设计的基本步骤。

下图为流程图绘制过程
中常用的图形符号(教材中的不标准)。

起始框、结束框
准备框
判断框
数据输入/
输出框
一般进程预定义的进程(子程序)
连接线
4. 规划存储器
为提高存储器的使用效率及方便性,同时考虑今后二次开发的需要,必须在编写程序之前对存储器做合理的规划,必要时应列表说明。

对照下图对程序存储器(ROM )规划、数据存储器(RAM )规划加以简要说明。

ROM
0000H 0003H~
002FH RAM
片内
片外
低地址
低地址
高地址
高地址
5. 编写程序,实现任务
用指令对流程图中的各部分加以具体实现。

注意实际应用程序中还要考虑增加可靠性程序(测试程序、软件陷阱、看门狗等)。

6. 调试与汇编
一般按模块调试。

特别注意子程序的出、入口参数要求,主程序与子程序的参数冲突。

一般采用机器汇编。

7. 程序固化
一般使用专门的EPROM写入器。

对EEPROM及Flash ROM、片内固化的ROM请参阅有关资料。

第五节结构化程序模块设计
在单片机程序设计过程中,有一些典型程序结构是经常用到的,例如顺序结构、循环结构、分支结构、子程序结构等。

下面将对比较常用的几种结构模块设计做以简述。

一、顺序结构程序设计
顺序结构程序是一种无分支的直线结构程序,即程序的执行是按PC自动加1的顺序进行的。

有关情况及示例程序参阅教材。

二、循环结构程序设计
所谓循环,指的是多次重复执行一组相同的操作。

在MCS-51中,主要利用各种条件转移指令进行循环控制,如DJNZ、CJNZ、JZ、JNZ、JC、JNC 等。

设计循环结构程序时,主要应注意以下几个问题:
■循环程序参数的初始化:规划循环变量、设置循环次数、累加器清零等。

■循环体设计:即重复执行的指令。

■循环控制:确定循环条件,何种条件下循环进行、结束。

■循环嵌套。

举例:
例1. 教材P108例7-9
设从片内数据存储器30H单元开始存有10H个无符号数据,试求出数据块中最大的数,并存人40H 单元。

分析:寻找最大值的方法是把第一个数据作为基准数,即最大数,依次取第二个数、第三个数…与之比较,若比较结果是基准数较小,则用较大的数代替原来的基准数,这样一直将数据块搜索完毕,找到最大值,程序如下:
MOV R7,#0FH ;比较次数
MOV R1,#30H ;地址指针置初值
83
84 MOV A ,@R1 ;用第一个数作为最大数 LOOP : CLR C ;清C 准备相减 INC R1 ;指向下一个数据 SUBB A ,@R1 ;用减法进行比较 JNC NEXT ;A>((R ))则转移
MOV A ,@R1 ;A< (((R1))则用当前数据替换前最大数 SJMP NEXTl
NEXT : ADD A ,@R1 ;恢复A NEXTl :DJNZ R7,LOOP ;循环结束条件 MOV 40H ,A
例2. 有一数据块从片内RAM 的30H 单元开始存入,设数据块长度为10个单元。

根据下式:
⎪⎩
⎪⎨⎧<=>+=0
0100
02
x x x x x y
求出y 值,并将y 值放回原处。

参考程序如下:
ORG 2000H MOV R0,#10 MOV R1,#30H START :MOV A ,@R1 ;取数
JB ACC.7,NEG ;若为负数,转NEG JZ ZER0
;若为零,转ZER0
ADD A ,#02H ;若为正数,求X+2
AJMP
SA VE
;转到SA VE ,保存数据
ZER0: MOV
A ,# 64H ;数据为零,Y=100
AJMP
SA VE
;转到SA VE ,保存数据
NEG : DEC A ;求∣X ∣(减1后取反)
CPL A
SA VE : MOV
@R1,A ;保存数据
INC R1 ;地址指针指向下一个地址 DJNZ R0,START ;数据未处理完,继续处理
SJMP

;暂停
三、分支、散转结构程序设计
分支结构程序就是条件判断分支程序,即根据不同的条件,执行不同的程序段。

分支程序的设计要点如下:
■确定分支条件。

■选用合适的条件转移指令。

①判累加器A是否为零指令JZ和JNZ;②比较条件转移指令CJNE、DJNZ;③判进位标志指令JC和JNC;④判位条件转移指令JB和JNB等。

■正确选定转移的目标地址,一般在转移的目的地址处设定标号。

1. 无条件分支程序——程序设计者事先设计好的分支结构(也称为散转结构)
经常使用指令LJMP、AJMP 、SJMP、JMP (@A+PC、@A+DPTR)。

★使用转移指令表的散转程序
例:根据R2的内容,转向不同的处理程序:
(R2)= 0:转向PROG0
(R2)= 1:转向PROG1
……
(R2)= n:转向PROGn
参考程序:
MOV DPTR, #TABJ ;指向散转指令表首址
MOV A, R2 ;读R2的内容
RL A ;由于散转指令AJMP占用2字节,因此将A的内容
乘2,以便于执行JMP @A+DPTR指令
JNC NADD ;若(A)>255则使TABJ翻到下一页,否则顺序执行
INC DPH
NADD: JMP @A+DPTR ;执行散转
TABJ: AJMP PROG0
AJMP PROG1
……
PROG0: ……

PROG1: ……

PROGn: ……
85

★使用地址偏移量表的散转程序
当各分支程序的代码长度小于256字节时,可以考虑使用此种方法。

该方法实际上是先查出各分支程序所对应的相对偏移量,然后将此偏移量存放到A,通过指令JMP @A+DPTR实现程序的散转。

同上例的问题,程序如下:
MOV A, R2
MOV DPTR, #TABJ
MOVC A, @A+DPTR
JMP @A+DPTR
TABJ: DB rel0 ;PROG0对应的相对偏移量
DB rel1 ;PROG1对应的相对偏移量

PROG0: ……

PROG1: ……

★其他散转程序(略)
■采用转向地址表的散转程序
■采用“RET”指令的散转程序
2. 有条件分支程序——根据已经执行的程序对标志位、ACC 或内部RAM 的某些位的影响结果决定程序的流向。

JC/JNC、JZ/JNZ 、CJNE 、DJNZ指令。

(参见循环结构程序设计中的例2)
注意:
■正确指定实现分支的判别条件
■正确确定转移的目标地址
四、查表程序设计
■查表:利用DB、DW等伪指令,通过汇编及程序固化,在程序存储器的指定位置上存放一些常量数据,需要时可利用读程序存储器的指令将这些常数取出,这种操作称为查表。

■查表程序广泛用于LED显示、打印机打印、数值计算、代码转换等场合。

86
■查表过程中要使用读程序存储器的指令,在MCS-51中有两个:
MOVC A, @A+DPTR
MOVC A, @A+PC
使用前一种指令,首先将表首地址送DPTR,然后将欲查的项次送A,执行指令后查得的数据即存放在A中。

使用第二种指令,首先欲查的项次送A。

由于(PC)为执行此指令后的地址数据,故一般在此指令后马上用DB等指令将表数据直接放在后面。

相比而言,后者由于不占用DPTR,故比较方便。

前者则因为表格数据的存放位置比较明确,因此也广泛使用。

举例:若A中存放的是某一数字的BCD码,试确定该数字所对应的8段LED显示码。

【说明:8段LED显示器的工作原理与字符的显示码
a b c d e f g h
共阴接法共阳接法
+5V
以共阴接法为例:
h ————a
“0”的显示码:0 0 1 1 1 1 1 1 B (3FH)
“1”的显示码:0 0 1 1 0 0 0 0 B (30H)
“2”的显示码:0 1 0 1 1 0 1 1 B (5BH)
“3”的显示码:0 1 0 0 1 1 1 1 B (4FH)
“4”的显示码:0 1 1 0 0 1 1 0 B (66H)
“5”的显示码:0 1 1 0 1 1 0 1 B (6DH)
“6”的显示码:0 1 1 1 1 1 0 1 B (7DH)
“7”的显示码:0 0 0 0 0 1 1 1 B (07H)
“8”的显示码:0 1 1 1 1 1 1 1 B (7FH)
“9”的显示码:0 1 1 0 1 1 1 1 B (6FH)
(若同时显示小数点,只需加上80H;显示其他字符可如法炮制)
★利用MOVC @A+DPTR查表的程序
MOV DPTR, #2000H
MOVC @A+DPTR
MOV 30H, A

87
ORG 2000H
DB 3FH, 30H, 5BH, 4FH, 66H
DB 6DH, 7dH, 07H, 7FH, 6FH
★利用MOVC @A+PC查表的程序
MOVC @A+PC
DB 3FH, 30H, 5BH, 4FH, 66H
DB 6DH, 7dH, 07H, 7FH, 6FH
MOV 30H, A

五、子程序设计
■使用子程序可以减少编程工作量及程序的代码长度,同时使程序结构清晰。

■子程序是一种独立的、特定的、标准化的代码段,需要时可按参数要求调用。

■调用子程序的程序称为主程序。

■子程序可以嵌套调用。

■子程序可分为两类:
通用子程序——用ACALL、LCALL调用,RET返回住程序。

中断子程序——符合响应中断的条件时系统自动调用,RETI返回主程序。

■发生子程序调用时(PC)的内容称为断点(地址,Breakpoint)。

关于子程序的设计主要应注意以下两个问题:
1. 主程序与子程序之间的参数传递
调用、执行子程序时需要在主程序中预先设置某些参数,调用返回时应把必要的结果传递回主程序,此外,一些存储地址也需要进行主程序——子程序之间的参数传递。

具体参数传递的方法有三种:■通过工作寄存器R0~R7或片内RAM
■通过堆栈
■通过DPTR
2. 保护现场
单片机中的变量均为全局变量。

在子程序的运行过程中,可能会“刷新”主程序中所使用过的一些RAM、工作寄存器甚至SFR。

因此,在程序设计时有时需要先将某些数据保护起来再调用子程序,调用后再恢复这些数据,分别称为保护现场和恢复现场。

保护现场及恢复现场的基本方法是使用堆栈,使用时需要特别注意进、出栈的次序。

88。

相关文档
最新文档