slide1
Download
Skip this Video
Download Presentation
第四章 指令系统 及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境

Loading in 2 Seconds...

play fullscreen
1 / 277

第四章 指令系统 及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境 - PowerPoint PPT Presentation


  • 192 Views
  • Uploaded on

第四章 指令系统 及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境. 第四章 指令系统及汇编语言程序设计语言. 4.1 编程语言 4.2 指令格式及其分类 4.3 寻址方式 4.4 数据传送类指令 4.5 逻辑操作类指令 4.6 算术运算类指令 4.7 位操作指令 4.8 控制类转移指令 4.9 汇编语言程序设计 4.10 汇编语言程序调试 4.11 利用 ISP 工具将程序下载到单片机中验证程序.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' 第四章 指令系统 及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境' - wood


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1
第四章 指令系统

及汇编语言程序设计

本章学习目标

  • 了解助记符、指令格式
  • 掌握单片机寻址方式
  • 掌握单片机指令系统
  • 掌握单片机汇编语言程序设计及开发环境
slide2
第四章 指令系统及汇编语言程序设计语言

4.1 编程语言

4.2 指令格式及其分类

4.3 寻址方式

4.4 数据传送类指令

4.5 逻辑操作类指令

4.6 算术运算类指令

4.7 位操作指令

4.8 控制类转移指令

4.9 汇编语言程序设计

4.10 汇编语言程序调试

4.11利用ISP工具将程序下载到单片机中验证程序

slide3
§4.1 编程语言

1、指令及指令系统

指令是计算机完成某种指定操作的命令,程序是

以完成一定任务为目的指令的有序组合。指令的集

合构成指令系统。

2、指令两种形式

  • 汇编指令的形式:人们进行编写、调试程序使用的形式;
  • 机器指令的形式:是机器所能识别的二进制数或十六进制数的形式。
slide4
§4.1编程语言

编写计算机程序有三种不同层次的计算机语言机器语言、汇编语言和高级语言。

  • 机器语言
    • 用二进制数表示的指令,是CPU唯一能够直接识别和执行的程序形式。
    • 缺点是不直观,不易识别、理解和记忆,因此编写、调试程序时都不采用这种形式的语言。
slide5
汇编语言(Assembly Language)
    • 是用英文缩写形式的助记符书写的指令,地址、数据也可用符号表示。
    • 优缺点:与机器语言程序相比,编写、阅读和修改都比较方便,不易出错。但用汇编语言编写的源程序必须进行汇编。
    • 目前,常用计算机软件自动完成汇编工作。

不同的CPU具有不同的汇编语言,一般不能通用。

    • 在实际系统中,对程序执行速度要求较高而软件处理功能有限的场合,以及对硬件操作有较强的针对性的场合,常用汇编语言编程。
slide6
高级语言(High Level Language)
    • 优缺点:不针对某种具体的计算机,通用性强。用高级语言编程不需了解计算机内部的结构和原理,这种语言的形式更接近英语,对于非计算机专业的人员比较易于掌握。高级语言程序易读、易编写,程序结构比较简洁,大量用于科学计算和事务处理。
    • 用高级语言编写的源程序同样必须编译后,计算机才能执行。编译程序比汇编程序复杂得多,需要占用较大容量的存储器,编译的过程也要花费更多的时间。
slide7
一、助记符语言
  • 汇编语言的指令由操作码和操作数组成。

操作码用规定的英文缩写字母组成,称为助记符。例如:

MOV A, #76H

表示的是将十六进制的数据76H送到累加器A中,

    • 二进制机器语言是:01110100和01110110
    • 十六进制数是:74H,76H。

其中74H表示操作码,是指将一个数据传送到累

加器A中,被传送的数据就是操作码的下一个字节,

即76H。

slide8
二、操作码

通常指令由操作码和操作数两部分组成。

  • 操作码功能:表示对操作数进行什么操作。
  • 表示形式:由英文缩写字母组成,容易理解和记忆。
  • 例如,MOV是数据的传送

ADD是数据的相加运算

ANL是数据的逻辑与运算

slide9
三、操作数
  • 操作数功能:指出对什么数进行操作以及将操作的结果放到何处。
  • 操作数的表示形式:可以是参与操作的数据,也可以是参与操作的数据所在存储器的地址,还可以是数据所在的寄存器等不同形式。
  • 寻找这些不同形式的操作数的方式称为寻址方式。
slide10
立即数
    • 定义:在汇编语言指令中,直接参与操作的数据称为立即数。
    • 表示方法:十进制的格式、十六进制格式、二进制的格式。

数据进制区分是在数据的后面加上后缀以示区别:十进制数据的后缀为D或省略,十六进制数据的后缀为H,二进制数据的后缀为B。

slide11
注意
    • 参与操作的数据的位数要与参与操作的环境相匹配。
    • 例如,指令MOV A, #71H,立即数71H是8位二进制数01110001B的十六进制格式,而A是8位的寄存器,所以给8位寄存器送的数据不能超出8位。
    • 同理,给十六位寄存器送的数据不能超出16位。
    • 数据只能是整数的格式,不能是小数的格式。逻辑数据也和二进制数据的表示一样,可以用十进制、十六进制、二进制的数据格式表示。
slide12
当汇编指令中的数据是十六进制且是以字母开头时,该数据应加一个前导0,以表示后面的字母不是变量而是数字。当汇编指令中的数据是十六进制且是以字母开头时,该数据应加一个前导0,以表示后面的字母不是变量而是数字。
  • 在8051内核单片机中,一个数据的前面有前缀#号则表示后面的数据是立即数,如果数据的前面没有#号,则说明该数据表示的是直接地址。
slide13
§4.2 指令格式及其分类

一、汇编语言的一般格式

标号:指令助记符 目的操作数,源操作数 ;注释

1、标号

  • 标号也叫做标识符,放在指令之前,是其后指令所在地址的名字,必须跟一冒号":"。
slide14
标号的作用
    • 标号用于表示某条指令跳转时的目标地址。
    • 程序在修改和调试时,指令所在的实际地址往往会随之变化,而代表地址的名字可以不变。因此,使用标号,可以给编程和修改带来极大的方便。
    • 不是每条指令都需要标号,通常在该指令作为跳转或调用的目的地址时需要标号。
slide15
标号的命名必须遵循下列规则:
    • 标号由字母(a~z或A~Z)、数字(0~9)或某些特殊字符(@、_、?等)组成,其中“_”是下划线;
    • 标号必须以字母(a~z或A~Z)或某些特殊的符号(@,_,?)开头,但问号“?”不能单独作标号;
    • 标号长度不允许超过31个字符;
    • 标号不能与指令助记符相同。
slide16
下面是符合上述规则的标号:
    • HOW NEXT_1 AA1Q
    • MCCl MODEL?? _DELAY
  • 下面是不符合上述规则的标号:
    • 5FVM -F33G ?
    • MOV ADD XOR

其中最后一行的三个标号均为指令助记

符,所以不能用做标号。

slide17
标号:指令助记符 目的操作数,源操作数 ;注释

2、指令助记符

  • 指令助记符也叫做操作码,是指令名称的代表符号,它是一条指令语句中所必需的,不可缺少,表示本指令所要进行的操作。
  • 例如:MOV 表示传送
slide18
标号:指令助记符 目的操作数,源操作数 ;注释

3、操作数

  • 操作数是参与本条指令操作的数据,有些指令不需要操作数,只有操作码;有些指令需要两个甚至三个操作数。
  • 在数据传送时,送出数据的叫做源操作数,接收数据的叫做目的操作数。指令中,目的操作数写在前,源操作数写在后,两操作数之间用逗号“,”分开。有些操作数可以用表达式表示。
  • 可以用不同的寻址方式得到操作数。
slide19
操作数提供方式:
    • 指令给出;
    • 在寄存器中,此时就用寄存器表示该操作数;
    • 在存储器中,这时候就用以地址表示的存储器表示该操作数。
  • 操作数的含义不同就表示了几种
slide20
标号:指令助记符 目的操作数,源操作数 ;注释

4、注释

  • 注释是为了阅读程序方便由编程人员加上的,并不影响程序的执行和功能,所以,注释部分不是必需的。
  • 注释部分必须用分号“;”开头,一般都写在它所注释的指令的后面,注释本身只用于对指令功能加以说明,使阅读程序时便于理解,所以注释可以用中文或者英文甚至任何便于理解的字符表示。
slide21
二、指令代码的存储格式
  • 指令存储位置:程序存储器
  • 指令由操作码和操作数组成,不同的指令所需要的操作数的个数有可能是不同的,所以每条指令的实际字节数不是固定的,
  • 例如,程序中有如下两条连续存放的指令:

MOV A,#68H

MOV B,#73H

slide22
MOV A,#68H
  • 该指令将十六进制数据68H送到累加器A中;
  • 这条指令是两字节指令;
  • 对应的机器码是:74H和68H两个字节,其中74H是操作码,68H是操作数.

MOV B, #73H

  • 该指令是将立即数73H送到寄存器B中;
  • 是三字节指令,对应的机器码是75H、F0H和73H三个字节,其中75H是操作码,B和73H是操作数。
slide23
指令存放格式
    • 在存储器中是以二进制数的形式、以字节为单位按照地址递增的顺序存放的。
    • 程序存储器中的指令机器码、数据字存放的规则是:从低地址开始,先存放操作码,然后是操作数。
slide24
假设这两条指令存放的起始地址是1000H,则存放的格式为:假设这两条指令存放的起始地址是1000H,则存放的格式为:
    • 左边一列表示的是程序存储器的地址
    • 右边一列是存放在该地址单元中的二进制指令。
slide25
程序执行过程
    • 程序执行时是依次逐条取出指令执行的。
    • 单片机内部有一个程序计数器,具有自动加一的特点,因而指令被逐字节取出,然后译码执行。
    • 首先取出操作码74H,经译码得知这是一条两字节的指令,要进行的操作是将立即数送到累加器A中,而操作数是以立即数的形式放在操作码的下一个地址中,程序计数器自动加一,将下一个地址中的数据68H取出来,送到累加器A中。
    • 程序计数器再次自动加一,指向下一条指令的第一个字节,取出75H,经译码得知这是一条三字节的指令,要进行的操作是将一个立即数送到一个寄存器中,这个寄存器是用该指令的第二个字节F0H来表示的,而地址F0H表示的就是寄存器B,本条指令的第三个字节内容就是要传送的立即数73H。
    • 这样随着程序计数器逐次加一,每条指令被一个字节一个字节地取出、译码和执行。
slide26
三、指令中的符号约定

在描述单片机指令系统时,经常使用各种缩写符号,各种符号及含义如表所示。

slide27
§4.3寻址方式

指令中寻找操作数的方式,称为寻址方式。

STC15F2K60S2单片机共有7种寻址方式

  • 立即数寻址
  • 寄存器寻址
  • 直接寻址
  • 寄存器间接寻址
  • 变址寻址
  • 相对寻址
  • 位寻址
slide28
1、立即数寻址
  • 定义

在指令中,指令操作所需要的操作数就在

指令中,作为指令的一个组成部分,CPU在

得到指令的同时也就立即得到了操作数。

slide29
例如:

M0V A,#28H;

    • 功能:将十六进制立即数28H送入累加器A中。指令执行后,A中为28H,A中原来的数据被覆盖,记作:A←28H
    • 其中,源操作数是立即数28H,目的操作数是累加器A。
    • 指令执行的操作是,将立即数28H送A。指令的机器码为两个字节:74H,28H。
slide30
假设该指令存放在物理地址为0100H开始的地址中,则,机器码的存放与指令的执行过程如图所示。假设该指令存放在物理地址为0100H开始的地址中,则,机器码的存放与指令的执行过程如图所示。

图4-1 MOV A,#28H 执行过程示意图

slide31
MOV A,#28H;
    • 注意:因为累加器A是8位的寄存器,所以在这里的立即数只能是8位数据,并且只能是整数,不能是小数、变量或者其他类型的数据。
    • 立即数只能作为源操作数,其位数要与目的操作数的位数一致。
    • 立即数前面的#号是表示其后所跟的数据是立即数而不是直接地址。
slide32
立即数寻址方式优点

采用立即数寻址方式的指令主要用来对寄

存器或存储器赋值。因为操作数可以从指令

中直接取得,不需要再到其他地方去寻找操

作数,所以,立即数寻址方式的指令执行速

度很快。

slide33
2、寄存器寻址
  • 定义

指令所用的操作数在CPU的内部寄存器

中,指令中的操作数用寄存器名表示。一条

指令中,源操作数和目的操作数式,都可

以采用寄存器寻址方式。

slide34
例如:
    • MOV A, #45H

;A←立即数45H

其中,源操作数45H为立即寻址方式,目的操作数为寄存器寻址方式。

    • INC R0

;R0 ←R0+1

该指令只有一个操作数,为寄存器寻址方式。

slide35
MOV A, R1

;A←R1

源操作数为寄存器R1,目的操作数为A,两者都是寄存器寻址方式。

  • 在寄存器寻址方式中,操作数用寄存器表示时有两种含义
    • 寄存器用于表示目的操作数时,是寄存器名,表示是某个寄存器,用于接收数据;
    • 寄存器用于表示源操作数时,是表示该寄存器中的数据。
slide36
例如: INC R5;指令机器码为0DH

;把寄存器R5的内容加1后再送回R5

该指令的执行过程如图所示。其中,R5所在的内部

RAM单元地址与寄存器组的选择有关。

图4-2 INC R5指令执行过程示意图

slide37
寄存器寻址方式优点
    • 采用寄存器寻址方式的指令在执行时,操作数就在寄存器中,对该操作数的存取操作在CPU内部进行,不需要使用总线周期读存储器,所以执行速度很快。
slide38
注意
    • 在数据传送之后,源操作数中的数据并不消失,仍然存在。
    • 例如,用寄存器作源操作数时,数据传送出之后寄存器中的内容仍然存在,只有作为目的操作数的寄存器被写入数据后,原来的数值会被新写入的数据所取代。这种性质,对于存储器也是同样的。
slide39
3、直接寻址
  • 定义

指令的操作数在存储器中时,指令中给出的是该操作数所在存储器的地址的方式。

  • 优点

直接寻址是对存储器进行访问时的最简单、最直接的方式。

slide40
例如:

MOV A,45H

    • 功能:将地址为45H的存储器单元中的内容取到A中。
    • 在这里,源操作数的寻址方式是直接寻址,表示要送出的数据在地址为45H的直接地址中;目的操作数的寻址方式是寄存器寻址。
    • 这条指令的机器码为:E5H、45H,其中,E5H是操作码,45H是操作数。
slide41
MOV A,45H

设机器码放在程序存储器地址为0100H和 0101H的两个

单元中,指令执行前,数据存储器的45H中的数据为34H,

则执行后A=34H,将A中原来的数据覆盖。

图4-3 MOV A, 45H 执行过程示意图

slide42
4、寄存器间接寻址(简称寄存器间址)
  • 定义:操作数所在存储单元的有效地址在指定的寄存器中,指令中给出的是存放这个地址的寄存器。
  • 常用作寄存器间接寻址的寄存器有R0、R1或数据指针DPTR。

在汇编语言中,使用间接寻址的标志是在寄存器前面加一个“@”号,以区别于寄存器寻址。

slide43
例如:

MOV A ,@R0

;将R0中的内容所表示

的地址单元中的内容送

给A

  • 设R0的内容为31H,31H单元的内容为51H,则执行后,累加器A的内容为51H。该指令的执行过程如图所示。

图4-4 MOV A,@R0 指令执行过程示意图

slide44
5、变址寻址
  • 两种寻址种类
    • 第一类:用PC作基地址加上累加器A的内容形成操作数的地址A+PC。
    • 第二类:使用DPTR作基地址,加上累加器A的内容形成操作数的地址A+DPTR。
slide45
例如:MOVC A,@A+PC,指令操作码助记符MOVC表示从程序存储器取数据,PC的内容指向下一个地址作为基地址,加上A中的数据就构成了所要取数的地址。
  • 例如:

……………

0100 7402 MOV A, #02

0102 83 MOVC A, @A+PC

0103 00 NOP

0104 00 NOP

0105 64 DB 64H

………

当执行到指令MOVC

A,@A+PC时,A=2,

PC=0103H,因此,A+PC=0105H,

@A+PC表示0105H作

为地址,从这个地址

指向的单元中取数据

送到A中,所以结果就

是把0105H中的数据

64H送到了A中。

slide46
例如:MOVC A,@A+DPTR,DPTR的内容加上A中的数据就构成了所要取数的地址。
  • 例如:

……………

MOV A,#02H

MOV DPTR,#TABLE

MOVC A,@A+DPTR

……………

TABLE: DB 30H

DB 31H

DB 32H

………………

slide47
变址寻址优点

特别适用于访问固化在程序存储器中的常数表格,以完成查表功能,如不同码制之间数据转换等。由于DPTR可以通过指令来设置,使用起来更加方便,因此,在实际应用中, MOVC A,@A+DPTR寻址使用更广泛。

slide48
6、相对寻址
  • 功能

该寻址方式主要用于相对跳转指令。

  • 寻址方法

把指令中给定的地址偏移量与本指令所在

单元地址(即程序计数器PC中的内容)相

加,即得到真正的程序转移地址。

slide49
与变址方式区别

该偏移量有正、负号,在该机器指令中必

须以补码形式给出,所转移的范围为相对于

当前PC值的-128~+127之间。

  • 例如: JC 80H

若C=0,则PC值不变,若C=1,则以现行的PC为

基地址加上80H得到转向地址。

slide50
JC 80H

假设若转移指令放在1005H,该指令的执行过程如图所示。

注意,指令偏移量以补码给出,所以80H代表着-80H。

图4-5 JC 80H执行示意图

slide51
7、位寻址

位操作指令能对位地址空间的每一位

进行运算和传送操作。

  • 例如:MOV C,P1.0

;将P1.0的状态传送到C

SETB 20H.6

;将20H单元的第6位置为1

CLR 25H

;将25H位的内容清零

slide52
综上所述,指令的寻址方式就是寻找操作数或寻找的操作数的地址的方式。综上所述,指令的寻址方式就是寻找操作数或寻找的操作数的地址的方式。
  • 寻址方式与存储器的结构有关。例如,访问程序存储器只能用变址寻址的方式;访问特殊功能寄存器只能用直接寻址方式;访问外部数据存储器只能用寄存器间接寻址方式等。
  • 一般来说,寻址方式越多,计算机功能越强,灵活性越大。所以寻址方式对机器的性能有重大影响。
slide53
§4.4 数据传送类指令

数据传送类指令是使用频率最高的一类指令。

  • 功能:主要用来给单片机的内部和外部资源赋值、进行堆栈的存取操作等。数据传送类指令执行前后,对程序状态字PSW一般不产生影响。
  • 分类:根据操作方式的不同,数据传送类指令分为三种:
    • 数据传送
    • 数据交换
    • 栈操作
slide54
一、数据传送指令

1、MOV指令

2、MOVX指令

3、MOVC指令

slide55
1、MOV指令
  • MOV指令的作用区间:内部数据存储器和特殊功能寄存器
  • 使用方法
    • 利用Rn可直接访问某工作寄存器;
    • 利用@Ri可间接寻址内部数据RAM的某一字节单元;
    • 直接寻址则可遍访内部数据RAM(00H~7FH)和特殊功能寄存器空间。
slide56
对于双操作数的数据传送指令允许在工作寄存器、内部数据RAM、累加器A和特殊功能寄存器(SFR)任意两个之间传送一个字节的数据,而且立即操作数能送入上述任何单元中。对于双操作数的数据传送指令允许在工作寄存器、内部数据RAM、累加器A和特殊功能寄存器(SFR)任意两个之间传送一个字节的数据,而且立即操作数能送入上述任何单元中。
    • 利用MOV指令还可以把16bit的立即数直接送入数据指针DPTR中。
  • 格式:MOV 目的字节, 源字节
  • 功能:把源操作数指定的字节变量传送到目的操作数指定的单元中,源字节内容不变。MOV指令一般不影响别的寄存器或标志。
slide57
(1)立即数送累加器A和Rn、内部RAM、SFR。

MOV A, #data8

MOV addr8,#data8

MOV @Ri, #data8

MOV Rn, #data8

@符号表示间接寻址,(Ri)表示把立即数送到

由Ri寄存器的内容所指出的那个RAM单元中去。Ri

中i=0或1。

;A← #data8

;(addr8)←#data8

;(Ri)←#data8

;Rn← #data8

slide58
例如: MOV R0, #60H

;将立即数60H送到寄存器R0中

MOV @R0, #56H

;将立即数56H送入到R0间接寻址的单元中,

;执行后60H单元的内容变为56H

利用直接寻址可把立即数送入内部RAM任意单元

或任一特殊功能寄存器,

例如:MOV 20H, #56H

;将立即数56H送入20H单元中

MOV P1, #80H

;把立即数80H直接送入P1口(字节地址为90H)中

slide59
(2)Rn、内部RAM、SFR与累加器A传送数据。有6条指令:(2)Rn、内部RAM、SFR与累加器A传送数据。有6条指令:

MOV A, addr8

MOV A, @Ri

MOV A, Rn

MOV addr8, A

MOV @Ri, A

MOV Rn, A

;A← (addr8)

;A← (Ri)

;A← Rn

;(addr8)←A

;(Ri)←A

;Rn←A

slide60
间接寻址@Ri是以Ri的内容作为地址进行寻址,由于Ri为8位寄存器,所以其寻址范围可为00H~FFH。例如,指令序列:间接寻址@Ri是以Ri的内容作为地址进行寻址,由于Ri为8位寄存器,所以其寻址范围可为00H~FFH。例如,指令序列:

MOV R1, #82H

MOV A, @R1

上述指令对于STC12C5A60S2单片机而

言,其功能是将内部RAM的82H单元中的内

容送到A中。内部80H~FFH的RAM单元,

只能使用这种间接寻址方式进行访问。

slide61
欲从DPL取数到累加器A,可用直接寻址方式:

MOV A, 82H

;执行后A中内容将是DPL中的值,也可使用下面的指令

MOV A,DPL

slide62
(3)Rn、SFR和内部数据RAM之间的数据传送。有5条指令:(3)Rn、SFR和内部数据RAM之间的数据传送。有5条指令:

MOV addr8, addr8

MOV addr8,@Ri

MOV addr8, Rn

MOV @Ri, addr8

MOV Rn, addr8

;(addr8目)←(addr8源)

;(addr8)←(Ri)

;(addr8)←Rn

;(Ri)←(addr8)

;Rn←(addr8)

slide63
例如:MOV 60H, 50H

;把50H单元的内容送到60H单元

  • 例如,若设PSW中标志位RS1、RS0为“01”,则选中第1组工作寄存器区,此时,

MOV 40H, R0与

MOV 40H, 08H是等价的。

  • 例如,用立即寻址指令可直接给内部RAM中30H和P1口上置数:

MOV 30H, #25H

MOV P1, #0CAH

执行后:(30H)=25H,(P1)=0CAH。

slide64
(4)目标地址传送
  • 功能:把16位常数装入数据指针。只有一条指令:

MOV DPTR ,#data16

  • 例如: MOV DPTR ,#0150H

表示把16位常数装入数据指针。执行后,DPTR=0150H,其中DPH=01H,DPL=50H

slide65
2、外部数据存储器(或扩展并行I/O口)与累加器A传送指令——MOVX2、外部数据存储器(或扩展并行I/O口)与累加器A传送指令——MOVX
  • 功能

主要用于累加器A和外部RAM或扩展并行

I/O口进行数据传送。这种传送只有一种寻址

方式,就是寄存器间接寻址。

slide66
两种寄存器间接寻址
    • 用R1或R0进行寄存器间接寻址。这种方式能访问外部数据存储器(或扩展并行I/O口)256个字节中的一个字节。若要访问更大的空间,需使用P2口输出高8位地址。需先给P2和Ri赋值,然后执行MOVX指令。
    • 用16位的数据存储器地址指针DPTR进行寄存器间接寻址。这种方法能遍访64KB的外部数据存储器(或扩展并行I/O口)的任何单元。
slide67
指令格式:MOVX 目的字节, 源字节
  • 有4条指令

MOVX A, @DPTR ;A←(DPTR)

MOVX A, @Ri ;A←(Ri)

MOVX @DPTR,A ;(DPTR)←A

MOVX @Ri, A ;(Ri)←A

  • 注意:由于使用R1或R0寄存器间接寻址方式访问外部数据存储器时,寻址范围受到256字节限制,因此,在实际应用中,一般使用DPTR寄存器间接寻址方式访问外部数据存储器。
slide68
例如:若外部数据存储器单元中:(0100H)=60H,(0101H)=2FH例如:若外部数据存储器单元中:(0100H)=60H,(0101H)=2FH

则执行: MOV DPTR ,#0100H

MOVX A, @DPTR

;执行后,累加器A=60H

slide69
3、程序存储器向累加器A传送指令——MOVC
  • 查表:对于程序存储器的访问,单片机提供了两条极其有用的查表指令。这两条指令采用变址寻址,以PC或DPTR为基址寄存器,以累加器A为变址寄存器,基址寄存器与变址寄存器内容相加得到程序存储器某单元的地址值,MOVC指令把该存储单元的内容传送到累加器A中。
slide70
指令格式: MOVC A ,@A+PC

; PC←PC+1,A←(A+PC)

MOVC A ,@A+DPTR

; A←(A+DPTR)

  • 功能:把累加器A中内容与基址寄存器(PC、DPTR)内容相加,求得程序存储器某单元地址,再把该地址单元内容送累加器A。指令执行后不改变基址寄存器内容,由于执行16位加法,从低8位产生的进位将传送到高位去,不影响任何标志。
slide71
MOVC A ,@A+PC
  • MOVC A ,@A+DPTR
    • 这两条指令主要用于查表,即完成从程序存储器读取数据的功能。
    • 由于两条指令使用的基址寄存器不同,因此使用范围也不同。
slide72
MOVC A ,@A+PC
  • MOVC A ,@A+DPTR
    • 以PC为基址寄存器时,CPU在取出本指令后PC自动加1,因为本指令为1字节指令,所以这时PC已不是原值,而是PC+1的值。因为累加器中的内容为8位无符号整数,这就使得本指令查表范围只能在以PC当前值开始后的256个字节范围内;
    • 以DPTR作为基址寄存器时,由于DPTR的内容可赋不同的值,使得该指令应用范围较为广泛,表格常数可设置在64KB程序存储器的任何地址空间。其缺点是,若DPTR已有它用,在赋表首地址之前必须保护现场,执行完查表后再予以恢复。
slide73
【例4-1】 试编制根据累加器A中的数(0~9之间)查其平

方表的子程序。

解:程序代码如下:

COUNT: PUSH DPH

PUSH DPL ;保护DPTR内容

MOV DPTR ,#TABLE ;赋表首址→DPTR

MOVC A ,@A+DPTR ;据A中内容查表

POP DPL

POP DPH ;恢复DPTR原内容

RET ;返回

TABLE: DB 00,01,04,09,16,25,36,49,64,81

slide74
二、数据交换指令

包括字节交换指令和半字节交换指令。

1、字节交换指令

XCH A,addr8 ;A←→(addr8)

XCH A,@Ri ;A←→(Ri)

XCH A,Rn ;A←→Rn

上述指令把累加器A中内容与第二操作数所

指定的工作寄存器、间接寻址或直接寻址的

某单元内容互相交换。

slide75
例如,

设R0=20H,A=3FH,(20H)=75H,

执行指令

XCH A,@R0

;执行结果A=75H,(20H)=3FH

slide76
2、半字节交换指令

XCHD A,@Ri ;A3~0←→(Ri)3~0

该指令把累加器A的低4位和寄存器间接寻

址的内部RAM单元的低4位交换,高4位内容

不变,不影响标志位。

  • 例如,设R1的内容为30H,A的内容为69H,内部RAM中30H的内容为87H,指令

XCHD A,@R1

; 执行结果:A=67H,(30H)=89H

slide77
三、栈操作指令
  • 栈的作用
    • 主程序调用子程序或中断处理过程时,分别要保存返回地址即断点地址和保护现场,以便在返回时能够回到调用前的程序段,继续运行原来的程序。
    • 进入子程序或中断处理程序后,需要保护子程序或中断处理程序所用到的通用寄存器中的数据。
slide78
现场保护和恢复
    • 保护现场:进入子程序或中断处理程序后还要保护所用寄存器的值。
    • 恢复现场:子程序返回或中断处理返回前,还要能够恢复这些寄存器的值
    • 保存返回地址的方法:将返回地址(断点地址)保存到堆栈中,返回主程序前从堆栈中取出上述地址放回到指令计数器PC中,按照放回后的PC值,从程序存储器中取指令执行就返回到了主程序被中断了的地方,以继续执行主程序。
    • 保护现场的方法:将现场条件(寄存器的值)先推入(PUSH)堆栈保存,然后再使用这些寄存器,返回主程序前,使用POP指令恢复寄存器中的值。
slide79
堆栈区
    • 位置:内部存储器的一部分区域专门用于堆栈
    • 数据存取规则:后进先出(LIFO—Last In First Out),即最后存入的数据将被最先取出。
    • 堆栈指针SP:SP始终指向栈顶。

图4-6 堆栈示意图

slide80
栈操作指令

PUSH addr8 ;SP←SP+1,(SP)←(addr8)

POP addr8 ;(addr8)←(SP),SP←SP- 1

上述两条指令分别完成两种基本堆栈操作,一种

叫入栈(PUSH),一种叫出栈(POP)。

slide81
STC15F2K60S2单片机堆栈编址采用向地

址增大的方向生成,即栈底占用较低地址,

栈顶占用较高地址,其操作过程为:

    • 入栈操作:先SP+1→SP,指向栈顶的上一个空单元,然后把直接寻址单元的内容压入SP所指的单元中。
    • 出栈操作:先弹出栈顶内容到直接寻址单元,然后SP- 1→SP,形成新的堆栈指针。
    • 注意:PUSH指令和POP指令一定要成对出现,并注意顺序。
slide82
例如:

PUSH ACC ;保护累加器ACC中内容

PUSH PSW ;保护标志寄存器内容

…… ;执行其他程序

POP PSW ;恢复标志寄存器内容

POP ACC ;恢复累加器ACC中内容

该程序执行后,累加器ACC和PSW寄存器

中的内容可得到正确的恢复。

slide83
若为:

PUSH ACC

PUSH PSW

…… ;其他程序

POP ACC

POP PSW

则执行后,将使得ACC和PSW中的内容互

换。

slide84
在数据传送类操作中应注意以下几点:
    • 除了用POP或MOV指令将数据传送到PSW外,传送操作一般不影响标志位。当向累加器中传送数据时,会影响PSW中的P标志。
    • 执行传送类指令时,把源地址单元的内容送到目的地址单元后,源地址单元中的内容不变。
    • 对特殊功能寄存器SFR的操作必须使用直接寻址,也就是说,直接寻址是访问SFR的惟一方式。
slide85
对于STC15F2K60S2单片机内部RAM的80H~FFH单元只能使用@Ri间接寻址方式访问。对于STC15F2K60S2单片机内部RAM的80H~FFH单元只能使用@Ri间接寻址方式访问。
  • 将累加器A压入堆栈或弹出堆栈时,应使用PUSH ACC和POP ACC指令,不能使用PUSH A和POP A指令。否则,程序编译会出错。因为累加器写成A或ACC在汇编语言指令中是有区别的,使用A时,表示使用的是寄存器寻址方式;而使用ACC时,表示使用的是直接寻址方式。
slide86
§4.5逻辑操作类指令

逻辑操作类指令主要完成与、或、清“0”、求反、左

右移位等逻辑操作,共有24条。

  • 分类:单操作数和双操作数
    • 单操作数:专门对累加器A进行的逻辑操作,包括:清“0”、求反、左右移位等,操作结果保存在累加器A中。
    • 双操作数:累加器A或直接寻址单元作为第一操作数和第二操作数之间的逻辑与、或和异或操作,结果保存在A中或直接寻址单元中。第二操作数可以是立即数、寄存器Rn、内部数据RAM单元或者SFR。
slide88
§4.5逻辑操作类指令

一、对累加 器A进行的逻辑操作

对累加器A进行的逻辑操作包括清“0”、求反和移

位,分别介绍如下:

1、累加器A清“0”

CLR A

;A←0,把00H送入累加器A中

2、累加器A求反

CPL A

;A← ,把累加器内容按位求反后送入累加器A中

slide89
例如,设累加器A原来内容为67H
    • 执行“CLR A”后将变成00H
    • 再执行“CPL A”后将变为0FFH

3、累加器A左右移位

RL A;累加器左循环移位

RLC A;累加器通过CY左循环移位

RR A;累加器右循环移位

RRC A;累加器通过CY右循环移位

SWAP A; 累加器高低半字节互换

左移一位相当于乘以2,右移一位相当于除以2

slide90
例 MOV A ,#01H;A←01H

RL A ;A←02H

RL A;A←04H

RL A ; A←08H

上述指令序列执行后,累加器A=08H。

若继续执行下面的指令:

RR A;A←04H

RR A;A←02H

RR A;A←01H,累加器内容又变为1。

通过进位标志CY的移位可用于检查一个字节中各位的状

态或用于逐位输出的情况,也可构成多个字节的移位操作。

slide91
【例4-2】 在40H和41H中存放一个双字节数据(即

16位数据),高位字节数据在41H中,低位字节数

据在40H中,试将其除以2。

解:利用循环右移指令可以将一个字节的数据除以2。如果

将双字节数据除以2,可以考虑使用带进位标志CY的循环右

移指令。程序代码如下:

CLR C ;先将进位标志清零,为第一次移位做准备

MOV A, 41H

RRC A

MOV 41H, A ;高位字节

MOV A, 40H

RRC A

MOV 40H, A

slide92
指令SWAP交换A中低和高半字节(位3~0和位

7~4),也看作是一个4位循环移位指令,不影响标

志。

  • 例如: MOV A,#0A5H

SWAP A

;执行结果 A=5AH

slide93
二、双操作数逻辑操作指令

双操作数的逻辑操作主要包括:累加器A与立即

数、内部存储器之间以及直接地址单元与累加器A、立即数之间的逻辑操作。逻辑操作是按位进行

  • “ANL”指令常用来屏蔽字节中的某些位,

与0则该位清0,与 1保留该位不变;

  • “ORL”指令常用来使字节中的某些位置1,

或1则该位置1,或0保留该位不变;

  • “XRL”指令用来对字节中某些位取反,

异或1则该位取反,异或0保留该位不变

slide94
1、累加器A与立即数、内部存储器之间的按位逻辑操作1、累加器A与立即数、内部存储器之间的按位逻辑操作

ANL(ORL,XRL)A,

slide95
逻辑与、或、异或的定义分别如下所示:
    • 与:A∧B代码组合 0×1=1×0=0×0=0 ;有0即0

1×1=1 ;全1为1

    • 或:A∨B代码组合1+0=0+1=1+1=1 ;有1即1

0+0=0 ;全0为0

    • 异或:A⊕B代码组合 0⊕1=1⊕0=1 ;相异为1

0⊕0=1⊕1=0 ;相同为0

slide96
例如,设A的内容为63H,R2为0AAH,分别执行命令(ANL、ORL、XRL)后,结果如下:例如,设A的内容为63H,R2为0AAH,分别执行命令(ANL、ORL、XRL)后,结果如下:

ANL A,R2

ORL A,R2

XRL A,R2

;A=22H

;A=0EBH

;A=0C9H

slide97
2、直接地址单元(内部RAM、SFR)与累

加器A、立即数之间的按位逻辑操作

ANL(ORL,XRL)addr8, A

ANL(ORL,XRL)addr8, #data8

上述指令完成内部数据RAM或SFR中直接寻址单

元与累加器A、立即数之间的逻辑与(或,异或)

操作,执行结果送回内部数据RAM或SFR中。

slide98
例如,设50H单元的内容为0AAH,A中内容为

15H,则分别执行下面指令时的结果如下:

ANL 50H,#0F0H

;(50H)=0A0H,屏蔽50H单元的低4位(清零)

ORL 50H,#0FH

;(50H)=0AFH,将50H单元的低4位置1

XRL 50H,A;(50H)=0BFH

当用逻辑与、或、异或指令修改一个并行I/O口输出内容时,则原始值将从该输出口的锁存器中读取,而不是从该输出口的引脚上读取。

slide99
【例4-3】 设两位用ASCII码表示的数分别保存在40H、41H

单元中,编程把其转换成两位BCD数,并以压缩形式存入

40H单元中。

解:方法一:

ANL 40H,#0FH ;40H的ASCⅡ码变成BCD码

MOV A,41H

ANL A,#0FH ;41H的ASCⅡ码变成BCD码

RL A ;左移4位

RL A

RL A

RL A

ORL 40H, A ;结果存40H单元中

slide100
方法二:使用SWAP指令会使程序更简炼。

ANL 40H,#0FH ;40H的ASCⅡ码变成BCD码

MOV A, 41H ;

ANL A,#0FH ;41H的ASCⅡ码变成BCD码

SWAP A ;高、低4位交换

ORL 40H, A ;结果存40H单元中

slide101
§4.6算术运算类指令

该类指令主要完成加、减、乘、除四则运算,以

及增量、减量和二十进制调整操作。除增量、减量

指令外,大多数算术运算指令会影响到状态标志寄

存器PSW。

表4-3 算术运算类指令对标志的影响

slide102
一、加减运算指令

在加减运算指令中,以累加器A为第一操作

数,并存放操作后的结果。第二操作数可以

是立即数、工作寄存器、寄存器间接寻址字

节或直接寻址字节。

运算结果会影响溢出标志OV、进位CY、

辅助进位AC和奇偶标志P。

slide103
1、加法指令:

ADD A,#data8;A←A+#data8

ADD A,addr8 ;A←A+(addr8)

ADD A,@Ri;A←A+(Ri)

ADD A,Rn;A←A+Rn

上述指令,把源字节变量(立即数、直接地址单

元、间接地址单元、工作寄存器内容)与累加器相

加,结果保存在累加器中,影响标志AC、CY、OV、

P。

slide104
例如, MOV A, #0C3H

ADD A, #0AAH

运算后,CY=1,OV=1,AC=0,PSW=85H,

A=6DH

溢出标志OV取决于带符号数运算,和的第6、7位中有一位产生进位而另一位不产生进位,则使OV置1,否则OV被清0。OV=1产生溢出。

slide105
2、带进位加法指令

ADDC A, #data8 ;A←A+#data 8+CY

ADDC A, addr8 ;A←A+(addr8)+CY

ADDC A, @Ri ;A←A+(Ri)+CY

ADDC A, Rn ;A←A+Rn+CY

除了相加时应考虑进位位外,其他与一般

加法指令完全相同。

slide106
例如,设累加器A内容为0AAH,R0内容为55H,C内容为1,执行指令:例如,设累加器A内容为0AAH,R0内容为55H,C内容为1,执行指令:

ADDC A,R0

运行结果: A=00000000B AC=1,CY=1,OV=0

slide107
【例4-4】设双字节加法中,被加数放20H、21H单

元,加数放30H、31H单元,和存放在40H、41H单

元,若高字节相加有进位则转OVER处执行。试编

程实现之。

解:程序代码如下:

ADDM: MOV A,20H ;取低字节被加数

ADD A,30H ;低位字节相加

MOV 40H,A ;结果送40H单元

MOV A,21H ;取高字节被加数

ADDC A,31H ;加高字节和低位来的进位

MOV 41H,A ;结果送41H单元

JC OVER ;若有进位,则转OVER处执行

……

OVER: ……

slide108
3、带借位减指令

SUBB A,#data8;A←A - #data8 - CY

SUBB A,addr8;A←A -(addr8)- CY

SUBB A,@Ri;A←A -(Ri)- CY

SUBB A,Rn ;A←A - Rn – CY

在加法中,CY=1表示有进位,CY=0表示无进

位;在减法中,CY=1则表示有借位,CY=0表示无

借位。

slide109
OV=1表示带符号数相减时,从一个正数中减去一个负数得出了一个负数或从一个负数中减去一个正数时得出一个正数的错误情况。和加法类似,该标志也是由运算时,差的第6、7位两者借位状态经异或操作而得。OV=1表示带符号数相减时,从一个正数中减去一个负数得出了一个负数或从一个负数中减去一个正数时得出一个正数的错误情况。和加法类似,该标志也是由运算时,差的第6、7位两者借位状态经异或操作而得。
  • 由于减法只有带借位减一条指令,所以在首次进行单字节相减时,须先清借位位,以免相减后结果出错。
slide110
例如,设累加器A的内容为D9H,R0的内容为87H,求两者相减结果。例如,设累加器A的内容为D9H,R0的内容为87H,求两者相减结果。

CLR C

SUBB A,R0

执行结果:A=52H,CY=0,OV=0

若运算两数为无符号数,则其溢出与否和OV状态

无关,而靠CY是否为1予以判别,OV仅表明带符号

数运算时是否溢出。

slide111
【例4-5】 两字节数相减,设被减数放在20H、21H

单元,减数放在30H、31H单元,差放在40H、41H

单元。试编程实现之。

解:程序代码如下:

SUBM: CLR C ;低字节减之前借位CY清0

MOV A,20H ;被减数送A

SUBB A,30H ;低位字节相减

MOV 40H,A ;结果送40H单元

MOV A,21H ;被减数高字节送A

SUBB A,31H ;高字节相减

MOV 41H,A ;结果送41H单元

JC OVER ;若有借位,则转OVER处执行

……

OVER: ……

slide112
二、乘除运算指令

乘除运算指令在累加器A和寄存器B之间进

行,运算结果保存在累加器A和寄存器B中。

slide113
1、乘法指令

乘法指令如下:

MUL AB

该指令把累加器A 和寄存器B中的8位无符号整数

相乘,16位乘积的低字节在累加器A中,高字节在

寄存器B中,如果乘积大于255(0FFH),则溢出

标志位置“1”,否则清“0”,运算结果总使进位标志CY清“0”。乘法指令可以下面的竖式表示:

slide114
例如,设A=82H(130),B=38H(56),执行指令:

MUL AB

执行结果:乘积为1C70H(7280),

A=70H,B=1CH,OV=1,CY=0

slide115
【例4-6】 利用单字节乘法指令进行多字节乘法运

算。设双字节数低8位存放在30H,高8位存放在

31H单元,单字节数存放在40H单元,编程实现双

字节乘以单字节的运算,乘积按由低位到高位依次

存放在50H、51H、52H单元中。

解:双字节数乘以单字节数,设双字节数用X表

示,单字节数用Y表示,则其乘法可表示为:

(X2·28+X1)·Y=X2·Y·28+X1·Y

slide116
利用MUL指令分别进行X2·Y和X1·Y的乘法运算,然后把等号右边两项移位相加即得其积。可以使用下面的竖式表示:利用MUL指令分别进行X2·Y和X1·Y的乘法运算,然后把等号右边两项移位相加即得其积。可以使用下面的竖式表示:

其中,“(X1Y)低”表示的是X1和Y乘积的低8位,其他符号代表的含义类似。

RES0就是“(X1Y)低”,即最后结果的最低位;

RES1是“(X1Y)高+(X2Y)低”的结果;

RES2是“(X2Y)高”和由“(X1Y)高+(X2Y)低”产生的进位相加的结果。

slide117
程序代码如下:

MOV A,30H

MOV B,40H

MUL AB ;X1·Y

MOV 51H,B ;积高字节存51H

MOV 50H,A ;积低字节存50H

MOV A,31H

MOV B,40H

MUL AB ;X2·Y

ADD A,51H

;X2·Y低8位与X1·Y高8位相加作为积的第二字节

MOV 51H,A

MOV A,B

ADDC A,#00H ;最高字节加低位进位

MOV 52H,A ;最高字节存52H单元

slide118
2、除法指令
  • 除法指令如下:

DIV AB

该指令把累加器A中的8位无符号整数除以寄存器B中8位无符号整数,所得结果的商存放在累加器A中,余数在寄存器B中,标志位CY和OV均清“0”。

slide119
注意:若除数(B中内容)为00H,则执行后结果为不定值,并置位溢出标志OV。注意:若除数(B中内容)为00H,则执行后结果为不定值,并置位溢出标志OV。
  • 例如,设累加器内容为147(93H),B寄存器内容为13(0DH),则执行命令:

DIV AB

执行结果:A=0BH,B=04H,OV=0,CY=0

slide120
三、增量、减量指令

增量指令完成加1运算,减量运算完成减1运算。

这两条指令均不影响标志位。

1、增量指令

INC A

INC addr8

INC @Ri

INC Rn

INC DPTR

;A ← A+1

;(addr8) ← (addr8)+1

;(Ri) ← (Ri)+1

;Rn ← Rn+1

;DPTR ← DPTR+1

slide121
注意: INC指令将指定变量加1,结果送回原地址单元,原来内容若为0FFH,加1后将变成00H,运算结果不影响任何标志位。
  • 例如,设R0=7EH,内部数据RAM中

(7EH)=0FFH,(7FH)=40H,则执行指

令:

INC @R0

INC R0

INC @R0

;(7EH)← 00H

;R0 ← R0+1,执行后,R0=7FH

;(7FH)← 41H

slide122
2、减量指令

DEC A

DEC addr8

DEC @Ri

DEC Rn

  • 注意:DEC指令将指定变量减1,结果送回

原地址单元,原地址单元内容若为00H,减1

后变成0FFH,不影响任何标志位。

;A ← A-1

;(addr8)← (addr8)-1

(Ri) ← (Ri)-1

;Rn ← Rn -1

slide123
例如程序:

MOV R1,#7FH

MOV 7EH,#00H

MOV 7FH,#40H

DEC @R1

DEC R1

DEC @R1

;R1 ← 7FH

;(7EH) ← 00H

;(7FH) ← 40H

;(7FH) ← 3FH

;R1 ← R1-1,执行后,R1=7EH

;(7EH) ← 0FFH

slide124
四、二——十进制调整指令
  • 指令如下:

DA A

  • 该指令的调整条件和方法:
    • 若A3-0>9或AC=1,则A3-0←A3-0+06H;
    • 若A7-4>9或CY=1,则A7-4←A7-4+60H。
    • 若两个条件同时满足或者A7-4=9且低4位修正有进位,则A7-0←A7-0+66H。即,若累加器低4位大于9或半进位位AC=1,则加06H修正;
    • 若相加后累加器高4位大于9或进位位CY=1,则加60H修正;
    • 若两者同时发生或高4位虽等于9但低4位修正时有进位,则应加66H修正。
slide125
DA指令使用说明
    • 对二——十进制的加法进行调整的指令。
    • 两个压缩型BCD码按二进制数相加,必须经过本条指令调整后才能得到压缩型的BCD码和数(读者可以使用87H+68H进行测算)。
    • 由于指令要利用AC、CY等标志位才能起到正确的调整作用,因此它需要跟在加法(ADD、ADDC)指令后面使用。
    • 如果该指令前面没有加法指令,则完成累加器A的内容的二——十进制转换。对用户而言,只要保证参加运算的两数为BCD码,并先对BCD码执行二进制加法运算(用ADD、ADDC指令),然后紧跟一条DA A指令即可。
    • DA A指令不能对减法进行十进制调整。
slide126
【例4-7】设计6位BCD码加法程序。设被加数保存在内部RAM中32H、【例4-7】设计6位BCD码加法程序。设被加数保存在内部RAM中32H、

31H、30H单元,加数保存在42H、41H、40H单元,相加之和保存在

52H、51H、50H单元,忽略相加后最高位的进位(溢出)。

解:程序代码如下:

BCDADD:MOV A,30H ;第一字节加

ADD A,40H

DA A

MOV 50H,A ;存第一字节和(BCD码)

MOV A,31H ;第二字节加

ADDC A,41H

DA A

MOV 51H,A ;存第二字节和(BCD码)

MOV A,32H ;第三字节加

ADDC A,42H

DA A

MOV 52H,A ;存第三字节和(BCD码)

slide127
【例4-8】假设有两个十进制数,被减数保存在30H单元,减【例4-8】假设有两个十进制数,被减数保存在30H单元,减

数保存在40H单元。编程实现二者的减法运算,结果存50H

单元中。

解:利用十进制加法调整指令作十进制减法调整,必须采用

补码相加的方法,用9AH(即十进制的100)减去减数即得

以10为模的减数补码。程序代码如下:

BCDSUB: CLR C ;清进位位

MOV A,#9AH ;求减数补码

SUBB A,40H

ADD A,30H ;进行补码相加

DA A

MOV 50H,A ;结果(差)存50H单元

slide128
§4.7 位操作指令

位操作指令以位作为处理对象,分别完成位传

送、位状态控制、位逻辑操作、位条件转移等功

能,共有17条。

可被指令识别的位地址表示方式有如下几种:

  • 直接用位地址(十进制或十六进制数)表示,或写成位地址表达式表示。
  • 写成字节地址加位数方式表示,二者之间用“.”号隔开。例如0B8H.0,20H.1等。
  • 位寄存器的定义名称,如C、EA等。
  • 对于位寻址寄存器,可以用字节寄存器名加位数来表示,二者之间用“.”号隔开。例如P1.0,PSW.4等。
  • 用户使用伪指令事先定义过的符号地址。
slide129

表4-4 位操作指令的操作码助记符及对应的操作数

slide130
一、位传送指令

MOV C,bit ; CY ← (bit)

MOV bit,C ;(bit) ← CY

指令的功能:是把第二操作数所指出的布尔变量

传送到由第一操作数指定的位单元中。其中一个操

作数必为位累加器(进位标志CY),另一个可以是

任何直接寻址位(bit)。指令执行结果不影响其他

寄存器或标志位。

slide131
例如,设内部数据RAM中(20H)=79H,执行指令:例如,设内部数据RAM中(20H)=79H,执行指令:

MOV C,07H

;07H是位地址,即字节地址20H的第7位,将使CY=0。

slide132
二、位状态控制指令

位状态控制指令包括位的清“0”、取反和置位。

1、位清“0”指令

CLR bit;(bit) ← 0

CLR C; CY ← 0

上述指令可使直接寻址位(bit)或位累加

器CY清“0”,不影响其他标志。

slide133
例如,内部数据RAM字节地址25H单元的内容为34H(0011 0100B),执行指令:

CLR 2AH

;2AH为字节地址25H第2位的位地址将使25H单元的内容变为30H(0011 0000B)。

slide134
2、位求反指令

CPL bit;(bit) ← ( )

CPL C ; CY ←

上述指令可把直接寻址位(bit)或位累加器CY

内容取反,不影响其他标志。

  • 例如,执行指令序列:

MOV 25H, #5DH

CPL 2BH

CPL P1.2

;(25H)=0101 1101B

;(25H)=0101 0101B

; P1.2求反

slide135
3、位置位指令

SETB bit;(bit)← 1

SETB C; CY ← 1

上述指令把任何可寻址的位或进位标志CY置1,

不影响其他标志。

  • 例如,P1口原已写入了49H(0100 1001B),则执行

SETB P1.7

;将使P1口输出数据变为C9H(1100 1001B)。

slide136
三、位逻辑操作指令

1、位逻辑与指令

ANL C,bit; CY ← CY∧(bit)

ANL C,/bit; CY ← CY∧( )

上述指令将直接寻址位的内容或直接寻址位的内

容取反后(不改变原内容)与位累加器CY进行逻辑

“与”操作,结果保存在CY中。“/bit”表示对该寻址

位内容取反后再进行位操作。

slide137
位逻辑“与” 操作示意图如图所示。

图4-7 ANL指令逻辑示意图

a) ANL C,bit指令执行示意图 b) ANL C,/bit指令执行示意图

slide138
例如,当位地址(7FH)=1并且累加器中

(ACC.7)=1时,进位位C置1,否则C清0,

可编程序如下:

MOV C,7FH;CY←(7FH)

ANL C,ACC.7;CY←CY∧ ACC.7

slide139
2、位逻辑或指令

ORL C,bit;CY ← CY ∨(bit)

ORL C,/bit;CY ← CY ∨(/bit)

上述指令将直接寻址位的内容或直接寻址位的内容取反后(不改变原寻址内容)与位累加器CY进行逻辑“或”操作,结果保存在CY中。

slide141
例如,将位地址7FH中的内容和累加器ACC.7中的内容相“或”的程序如下:例如,将位地址7FH中的内容和累加器ACC.7中的内容相“或”的程序如下:

MOV C,7FH

ORL C,ACC.7

;相“或”的结果存CY中

slide142
四、位条件转移指令

位条件转移指令分为判CY转移和判直接寻址位状态转移两种。

1、判CY转移指令

JC rel

JNC rel

上述两条指令通过判进位CY的状态决定程序的

走向,前一条若进位标志为1,后一条若进位标志为

0,就可使程序转向目标地址,否则顺序执行下一条

指令。目标地址为第二字节中的带符号的偏移量与

PC的当前值(PC←PC+2)之和,不影响任何标志。

; 若CY= 1,则PC←PC+rel,否则顺序执行。

; 若CY= 0,则PC←PC+rel,否则顺序执行。

slide143
JC rel指令操作过程如图a)
  • JNC rel指令操作过程如图b)

(a)JC rel指令

(b)JNC rel 指令

图4-9 JC指令和JNC指令执行示意图

slide144
在实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。这样做有两个好处,一是程序的可读性好,二是不必进行偏移量的计算。在实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。这样做有两个好处,一是程序的可读性好,二是不必进行偏移量的计算。
  • 例如,程序段:

ADD A,#30H; 加法指令,影响标志位C

JC L2;若C=1(有进位),则转L2,否则,继续执行

L1: ……

L2: ……

slide145
2、判直接寻址位转移指令

JB bit,rel

;若(bit)=1,则PC←PC+rel

JNB bit,rel

;若(bit)=0,则PC←PC+rel

JBC bit,rel

;若(bit)=1,则PC←PC+rel,

且(bit)←0若条件不满足,

指令顺序执行。

slide146
三条指令操作过程分别如图a)、图b)和图c)所示。三条指令操作过程分别如图a)、图b)和图c)所示。

图4-10 JB、JNB、JBC指令执行示意图

a) JB bit,rel 指令 b) JNB bit,rel 指令 c) JBC bit,rel 指令

slide147
在实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。在实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。
  • 例如,指令序列:

MOV P1, #0CAH

MOV A, #56H

JB P1.2, L1

JNB ACC.3, L2

L1: ……

L2: ……

;P1←0CAH(11001010B)

;A←56H(01010110B)

; P1.2=0 不转,继续执行

; ACC.3=0 转L2处执行

slide148
另一段程序:

MOV A,#43H

JBC ACC.2,L1

JBC ACC.6,L2L1:

……

L2: ……

执行后均使程序转向L2处,但前段程序转移后维

持原变量ACC.3=0不变,后段程序却把原变量

ACC.6=1清0。

; A← 43H(01000011B)

; ACC.2=0 不转

;ACC.6=1 转L2,且ACC.6← 0

slide149
§4.8 控制转移类指令
  • 使程序不按存放的顺序执行,而是转到另外的地址去执行包括:转移指令、调用指令和返回指令:
  • 转移指令和调用指令的区别
    • 转移指令只是跳转到新地址去,不再跳转回来;
    • 调用指令只是暂时转到新的地址处执行一段指令,执行完这一段指令以后再跳转回来,按照调用之前的顺序继续执行程序。
    • 所以,调用指令要具有能够跳转回来并能够能继续执行调用之前的程序的功能,这些功能都是借助堆栈的操作实现的。
slide151
1、控制转移指令

(1)无条件转移指令

  • 长转移指令
  • 绝对转移指令
  • 相对短转移指令
  • 间接转移指令

(2)条件转移指令

  • 累加器判零转移指令
  • 比较转移指令
  • 循环转移指令
slide152
(1)无条件转移指令
  • 无条件转移指令,是使程序不按照指令的存放顺序执行,而是无条件转到另一处执行的指令,该类指令不影响标志位。
  • 实质上,无条件转移指令就是控制程序计数器PC从现行值转移到目标地址。
    • 长转移指令LJMP
    • 绝对转移指令AJMP
    • 相对短转移指令SJMP
    • 间接转移指令JMP
slide153
1)长转移指令

LJMP addr16;PC←addr16

该指令提供16位目标地址,将指令中第二、第三

字节地址码分别装入PC的高8位和低8位中,程序无

条件转向指定的目标地址去执行,执行结果不影响

标志位。由于直接提供16bit目标地址,所以执行这

条指令可以使程序从当前地址转移到64KB程序存储

器地址空间的任何单元。

slide154
例如,如果在程序存储器0000H单元存放一条指令例如,如果在程序存储器0000H单元存放一条指令

LJMP 0100H

执行结果:复位后程序将跳到0100H单元去执行。

slide155
2)绝对转移指令

AJMP addrll

;PC←PC+2,PC15~11不变,PC10~0←addr10~0

第二字节存放的是低8位地址,第一字节5、6、7位存放着高3位地址a10~a8。

  • 注意:AJMP为双字节指令,当程序真正转移时PC值已加2,因此,目标地址应与AJMP后面相邻指令的第一字节地址在同一2KB范围内。如果超过了2KB范围,汇编程序会提示出错。本指令不影响标志位。
slide156
指令执行时分别把高3位和低8位地址值取出送入程序计数器PC的低11位,维持PC的高5位(PC+2后的)地址值不变,实现2KB范围内的程序转移。指令执行时分别把高3位和低8位地址值取出送入程序计数器PC的低11位,维持PC的高5位(PC+2后的)地址值不变,实现2KB范围内的程序转移。

图4-11 AJMP指令执行示意图

slide157
3)相对短转移指令

SJMP rel;PC←PC+2,PC←PC+rel

其中,rel为相对偏移量,是一个8位带符号的数。

指令控制程序无条件转向指定地址。该指定地址

由指令第二字节的相对地址和程序计数器PC的当前

值相加形成。因而目标地址可以在这条指令首地址

的前128字节到后127字节之间。

slide158
4)间接转移指令

JMP @A+DPTR; PC←A+DPTR

该指令把累加器里的8位无符号数与作为基址寄存器DPTR中的16位数据相加,所得的值装入程序计数器PC做为转移的目标地址。执行16位加法时,从低8位产生的进位将传送到高位去。

指令执行后不影响累加器和数据指针中的原内

容,不影响任何标志。

slide159
JMP @A+DPTR; PC←A+DPTR

这是一条极其有用的多分支选择转移指令,其转

移地址是在程序运行时动态决定的,这也是和前3条

指令的主要区别。

因此,可在DPTR中装入多分支转移程序的首地

址,而由累加器A的内容来动态选择其中的某一个

分支予以转移,这就可用一条指令代替众多转移指

令,实现以DPTR内容为起始的256个字节范围的选

择转移。

slide160
LJMP 、AJMP、 SJMP

在实际应用中,由于AJMP和SJMP指令的

跳转范围有限,而LJMP(长转移指令)不受

跳转范围的限制,因此,一般情况下都可使

用LJMP指令代替AJMP和SJMP指令。

slide161
(2)条件转移指令
  • 条件转移指令,是以执行该指令时的状态标志为条件,决定是否改变程序执行的顺序的指令。换句话说,就是符合条件就转移;不符合条件就不转移,顺序执行指令。
  • 条件转移指令属于短距离相对转移,适用于与绝对地址无关的程序,跳转范围以当前地址为中心的-128~+127字节之内。如果转移距离超过短距离范围,则必须使用两级以上的跳转。
slide162
(2)条件转移指令
  • 累加器判零转移指令
  • 比较转移指令
  • 循环转移指令
slide163
1)累加器判零转移指令

JZ rel; 若累加器为0则转移

JNZ rel; 若累加器不为0则转移

两条指令均为双字节,其中第二条字节为带符号的相对偏移量,PC现行值(PC加2后)与偏移量相加即得转移地址。该指令不改变累加器内容,不影响标志位。

slide164
JZ rel

JNZ rel

指令的执行过程如图所示。

图4-12 JZ和JNZ指令执行示意图

slide165
例如,执行程序:

MOV A,P0

; P0口内容送累加器A

JZ L1

; A不为0,则不跳转,继续执行;A=0,则跳转L1

DEC A

; A减1

L1: ……

slide166
2)比较转移指令

CJNE (目的字节),(源字节),rel

  • 该指令比较前面两个操作数的大小,如果它们的值不相等则转移,相等则继续执行。
  • 三字节指令,PC当前值(PC+3 → PC)与指令第三字节带符号的偏移量相加即得到转移地址,如果目的字节的无符号整数值小于源字节的无符号整数值,则置位进位标志,否则清“0”进位位,指令不影响任何一个操作数。
slide168
具体的比较转移指令有4条:

CJNE A,#data8,rel

CJNE A,addr8,rel

CJNE @Ri,#data8,rel

CJNE Rn,#data8,rel

slide169
指令的操作过程如图所示。

由图可见,当取完CJNE指令时PC值已是PC←PC+3,指向了下面相邻指令的第一字节地址,然后比较源操作数和目的操作数,判断结果决定程序走向,由于取指令操作PC已加3,所以程序转移范围是以PC+3为起始地址的+127~-128字节单元地址。

图4-14 CJNE指令执行流程示意图

slide170
例如,设(R7)=53H,执行下列指令

CJNE R7,#68H,K1

; 由于R7<68H,转K1,且CY←1

… ; 在此处理相等的情况

K1 : JC K3

; 因为CY=1,判出R7<68H,转K3执行

K3: …

slide171
3)循环转移指令

DJNZ (字节),rel

这是一条减1与0比较指令,程序每执行一

次该指令,就把第一操作数字节变量减1,结

果送回到第一操作数中,并判字节变量是否

为0,不为0转移,否则顺序执行。

注意:如果第一操作数的字节变量的原值

为00H,则执行指令后,变为0FFH,不影响

任何标志。

slide172

图4-15 DJNZ指令的执行过程

  • 循环转移指令共有两条:

DJNZ direct, rel

DJNZ Rn, rel

  • 指令操作过程

如图所示。

由图可以看出,循环转移的目标地址为DJNZ之后相邻指令的第一个字节地址与带符号的相对偏移量相加之和。

使用该指令可以很容易地构成循环,只要给直接地址或工作寄存器赋不同初值,就可方便地控制循环次数,而使用不同的工作单元或寄存器就可派生出很多条循环转移指令。

slide173
DJNZ用于软件延时

软件延时就是使程序在运行时消耗时间,是经常采用的方法,这种方法节约硬件成本,使用灵活,计时精确,但是占用了CPU的时间,经常使用在对CPU的使用效率要求不苛刻的情况下。

slide174
DJNZ实现软件延时

DJNZ指令执行时间为两个机器周期,循环一次可

产生两个机器周期延时。当主频12MHz,循环次数

为24时,下面的程序可产生49us的软件延时循环,

在P1.0引脚上输出一个50μs的负脉冲。

CLR P1.0; P1.7输出变低电平

MOV R2,#18H; 赋循环初值

HERE : DJNZ R2,HERE ;R2 ← R2-1,不为零继续循环

SETB P1.0 ; P1.7输出高电平

slide175
DJNZ实现重复执行程序代码

例如,多项单字节数求和:设数组长度放R0,数

组首地址存放在R1中,数组之和保存在20H单元

中,假设相加的结果不大于256。可编程如下:

CLR A; A清0

SUMC: ADD A,@R1; 相加

INC R1; 地址指针增1

DJNZ R0,SUMC; 字节数减1不为0继续加

MOV 20H,A; 结果存20H单元

slide176
1、控制转移指令
  • 无条件转移
  • 条件转移

2、子程序调用和返回指令

  • 长调用指令
  • 绝对调用指令
  • 返回指令
  • 中断返回指令
  • 空操作指令NOP
slide177
子程序的功能
    • 子程序就是用来对一系列指令进行封装,实现模块化、可重用化及抽象化,从而有利于程序的结构化开发,使程序结构更清晰。
    • 合理划分代码结构是软件成功的基本保障。
slide178
每种微处理器或者微控制器都有子程序的调用和返回指令。每种微处理器或者微控制器都有子程序的调用和返回指令。
    • 对于STC15F2K60S2单片机来说,有两条调用指令:LCALL(长调用)及ACALL(绝对调用)和一条与之配对的子程序返回指令RET。
slide179
(1)长调用指令

LCALL addr16 ;

长调用与LJMP一样提供16位地址,可调用64KB范围内所

指定的子程序。

例:LCALL STR;表示调用STR子程序

PC ←PC+3

SP←SP+1

(SP)←PC7~0

SP← SP+1

(SP)←PC15~8

PC ←addr16

slide180
(2)绝对调用指令

ACALL addr11;

该指令提供11位目标地址,限在2KB地址范围内调用子程序,由于受2KB的限制,因此,一般程序中使用LCALL指令代替。

PC ←PC+2

SP←SP+1

(SP)←PC7~0

SP←SP+1

(SP)←PC15~8

PC10~0 ←addr11

PC15~11不变

slide181
(3)返回指令

RET;

RET表示子程序结束返回主程序从堆栈中弹出调

用子程序时压入的返回地址,使程序从调用指令

(LCALL或ACALL)的下面相邻指令开始继续执

行。

PC15~8←(SP)

SP←SP-1

PC7~0←(SP)

SP←SP-1

slide182
(4)中断返回指令

RETI

该指令用于中断服务子程序的返回,其执

行过程类似于RET,详见与中断有关的章节

介绍。

slide183
(5)空操作指令NOP

NOP ;PC←PC+1

执行本指令除了PC加1外不作任何操作,而转向

下一条指令去执行。不影响任何寄存器和标志位。

由于是单周期指令,所以时间上只有一个机器周期。

常用于精确延时或时间上的等待。

slide184
例如,利用NOP指令产生方波。

LOOP: CLR P2.7 ;P2.7清0输出

NOP ;空操作

NOP NOP

NOP

SETB P2.7 ;置位P2.7高电平

NOP

NOP ;空操作

NOP

NOP

LJMP LOOP

slide185
§4.9 汇编语言程序设计

一、伪指令

  • 用户将编辑好的汇编语言源程序通过专门的软件(称为汇编程序)汇编成对应的机器语言程序时,需要有一些专门的说明性语句。
  • 例如,指定目标程序或数据存放的起始地址、给一些指定的标号赋值、在内存中予留工作单元、表示源程序结束等指令
  • 指令并不产生对应CPU操作的机器码,故称为伪指令(Pseudo-Instruction),也叫做指示性语句;相对应的,可以产生实质性操作的指令叫做指令性语句。指令性语句表示了CPU要进行的某种操作。
  • 例如,MOV A,#30H,表示的是将立即数30H送到寄存器A中。
slide186
1、起始地址设置伪指令ORG(ORIGIN)

格式为: ORG xxxxH

ORG是起始地址设置伪指令的操作码,

xxxx是四位十六进制地址。该指令表明其

后紧跟的指令性语句的机器码放在以xxxxH为起始地址的单元中。

slide187
一般的,在整个程序的起始处放置一条

“ORG 0000H”伪指令,表明下面开始的指令性语句

从0000H开始存放。后面有一定独立性的程序段也

可以用这条指令指定程序段存放的起始地址。

例如:

ORG 0000H

START: LJMP MAIN

MOV A,#00H

……

ORG 0100H

DELAY: MOV R0,#30H

……

slide188
ORG伪指令的作用
    • 单片机复位的时候,一个重要操作是将程序计数器PC清零。在复位结束后,系统从程序存储器存放的第一个地址单元0000H开始取指令,汇编的时候就需要告诉汇编程序将后面的语句经汇编后放在地址为0000H开始的区域,因此,整个程序的起始地址用“ORG 0000H”伪指令说明,后面的延时子程序DELAY 在指令“ORG 0100H”的说明作用下,经汇编后是被放置在地址为0100H开始的区域。
    • 在例子中,如果没有“ORG 0100H”这条语句,延时程序DALAY也会得到汇编,汇编后的机器码紧接着前面的程序顺序存放。
slide189
2、数据定义伪指令
  • 功能:定义一个数据存储区,其类型由数据定义伪指令指定,可以给存储区赋初值,也可以仅仅给变量分配存储单元,而不赋予特定的值。
  • 一般格式

[标号:] 数据定义伪指令 操作数[,操作数…] [;注释]

方括号中的内容为可选项。变量名后面不跟冒

号。伪指令后面的操作数可以不止一个。如有多个

操作数,互相之间用逗号隔开。

slide190
常用的数据定义伪指令有DB和DW:

(1)定义字节DB(Define Byte)

[标号:] DB 〈项或项表〉

其中项或项表:指一个字节、数或数字串,或以

引号括起来的ASCII码字符串(一个字符用ASCII

码表示,相当于一个字节)。

该指令的功能是把项或项表的数值存入从标号开

始的连续单元中,每个操作数存放时占1个字节,多

个操作数时,按排列顺序首先从低地址存放。

slide191
(2)定义字DW(Define Word)
  • DW伪指令定义的是字变量
  • 每个字变量占2个字节的存储单元,两个字节的存储单元相邻,低位字节在低地址中,高位字节在高地址中。
  • 多个操作数时,按排列顺序从低地址开始存放。
slide192
例如:

ORG 1000H

SEG:DB 23H;定义一个字节

DW 1000H;定义一个字

DB ‘MCS-51’;定义一个字符串

END

则: (1000H)=23H SEG的地址为1000H

(1001H)=00H

(1002H)=10H

(1003H)=4DH ‘M‘的ASCII码

(1004H)=43H ‘C’ 的ASCII码

(1005H)=53H ‘S’ 的ASCII码

(1006H)=2DH ‘-’的ASCII码

(1007H)=35H 数字5的ASCII码

(1008H)=31H 数字1的ASCII码

slide193
由数据定义伪指令DB或者DW后面的操作数确定变量的初值,常用的有以下几种形式:由数据定义伪指令DB或者DW后面的操作数确定变量的初值,常用的有以下几种形式:
    • 常数或数值表达式。
    • ASCII码字符串。
    • 表示定义的变量无确定值。
slide194
汇编程序中的常数,可采用不同的数制和不同的表示方法:汇编程序中的常数,可采用不同的数制和不同的表示方法:
    • 十进制数:数字的后面加一个字母“D”(Decimal),表示是十进制数;或者什么也不加,默认为是十进制数。
    • 二进制数:数字的后面加一个字母“B”(Binary),如10101001B。
    • 十六进制数:数字的后面加一个字母“H”(Hexadecimal),而且,当十六进制数字不是以数字0~9开始,而是以字母(A~F)开头时,前面要再加一个前导数字0,这是为了在进行汇编时,以区别是数字,不是符号名。
    • ASCII常数:应将字符放在单引号中,例如‘A’,‘8’等。
slide195
汇编语言语句中的表达式为数值表达式,由数值和运算符组成,产生一个数值结果。运算符为算术运算符,常用的算术运算符有:十(加),一(减),*(乘),/(除)。汇编语言语句中的表达式为数值表达式,由数值和运算符组成,产生一个数值结果。运算符为算术运算符,常用的算术运算符有:十(加),一(减),*(乘),/(除)。
  • 在使用时应注意,作为操作数部分的项或项表,若为数值,其取值范围应为00~0FFH。
slide196
3、等值伪指令EQU(Equate)

标号 EQU 表达式

  • 功能:是将语句操作数的值赋于本语句的标号。格式中的表达式可以是一个常数、符号、数值表达式或地址表达式等。

如果源程序中需要多次引用某一表达式,则可利用EQU伪指令给其赋一个标号(名字),在以后的代码中,可用这个标号来代替上述表达式,从而使程序更加简洁,便于阅读。如欲改变表达式的值,也只需在EQU指令处修改一次,而不必修改多处,使程序易于调试、修改和维护。

slide197
【例4-9】

COLUMN EQU 32H

ROW EQU 68H

BUFFER DB ?

MOV A,#COLUMN

MOV B,#ROW

MUL AB

MOV BUFFER,A

MOV BUFFER+1,B

  • 上述程序段执行后,就把COLUMN 和 ROW
  • 的乘积放在了单元BUFFER和BUFFER+1中。只要改变COLUMN 和 ROW的值就可以计算不同数据的乘积。
slide198
注意:在同一程序中,用EQU伪指令对标号赋值后,该标号的值在整个程序中不能再改变。注意:在同一程序中,用EQU伪指令对标号赋值后,该标号的值在整个程序中不能再改变。
slide199
4、DATA指令

符号名 DATA 表达式

该指令用于将一个内部RAM的地址赋给指定的符

号名。表达式必须是一个简单表达式,其值在

00H~0FFH之间。

例如:

BUFFER DATA 40H

slide200
5、XDATA指令(Extenal Data)

符号名 XDATA 表达式

该指令用于将一个外部RAM的地址赋给指定的符

号名。表达式必须是一个简单表达式,其值在

0000H~0FFFFH之间。

例如:

MYDATA XDATA 0100H

slide201
6、定义位命令BIT

字符名称 BIT 位地址

用于给字符名称定义位地址。

例如:

DOGOUT BIT P3.4

经定义后,允许在后续的指令代码中用DOGOUT代替P3.4。

slide202
7、文件包含命令INCLUDE
  • 文件包含命令INCLUDE用于将寄存器定义文件(一般的后缀名为.INC)包含于当前程序中,与C语言中的#include语句的作用类似。
  • 使用格式为:

$INCLUDE (文件名)

slide203
例如,为了使用方便,作者把STC15F2K60S2单片机的寄存器定义保存在文件STC15.INC中。使用时,可以在程序的开始处使用下面的命令将其包含到用户程序中:例如,为了使用方便,作者把STC15F2K60S2单片机的寄存器定义保存在文件STC15.INC中。使用时,可以在程序的开始处使用下面的命令将其包含到用户程序中:

$INCLUDE (STC15.INC)

  • 使用上述命令后,在用户程序中就可以直接使用STC15F2K60S2单片机的特殊寄存器名称了。
  • 例如,

MOV CMOD,#10000000B

;设置PCA工作模式

slide204
8、条件汇编控制指令
  • 条件汇编控制指令的作用是使源程序中的一部分程序行根据需要决定是否进行汇编。
  • 条件汇编控制伪指令的一般格式:

IF 表达式

[ 程序块1 ]

[ ELSE ]

[ 程序块2 ]

ENDIF

slide205
当IF指令中的表达式为真时,汇编程序汇编程序块1;当IF指令中的表达式为真时,汇编程序汇编程序块1;
    • 当IF指令中的表达式为假时,汇编程序块2。在一个条件结构中,仅有一个程序块被汇编,其它的则被忽略。
  • IF块可嵌套使用,最大嵌套深度为63层(Keil uVision集成开发环境只能达10层)。
  • 如果IF ELSEIF和ELSE块不汇编,则其嵌套的条件块也不汇编。
slide206
9、汇编结束伪指令
  • 格式:

END [标号]

  • 汇编程序结束时,最后一条伪指令为END。
  • 指令格式中的标号是整个汇编语言源程序第一条可执行语句的标号。该伪指令告诉汇编程序:整个源程序结束,汇编程序停止汇编,并指出第一条指令性语句的标号。
  • 在一般的程序中,END后的标号都省略不写。
slide207
二、汇编语言程序设计的一般步骤和基本框架

程序是指令的有序集合。编写一个功能完善的、

完整的程序,正确性是最主要的,但整个程序占内

存的空间大小、每条指令的功能、长度、执行速度

等都要考虑,尽可能使其优化。一个完善的系统设

计应该具有设计方案正确、程序结构规范等基本性

质,这不仅给程序的设计和调试带来方便,加速调

试过程,而且有益于程序的维护和升级。

slide208
汇编语言程序设计的一般步骤是:
    • 分析课题,确定算法或解题思路。
    • 根据算法或思路画出流程图。
    • 根据算法要求分配资源,包括内部RAM、定时器、中断等资源的分配。
    • 根据流程图编写程序。
    • 上机调试源程序,进而确定源程序。

对于复杂的程序可以按功能分为不同的模

块,按模块功能确定结构。编写程序时采用

模块化的程序设计方法。

slide209
$INCLUDE (STC12.INC)

;包含STC15F2K60S2单片机寄存器定义头文件

;------这里可以编写程序中用到的一些符号定义(使用EQU、DATA、BIT等伪指令)

ORG 0000H

START: LJMP MAIN;跳转到主程序

ORG 0003H

LJMP INT0_ISR ;外部中断0入口

ORG 000BH

LJMP T0_ISR ;定时器0中断入口

ORG 0013H

LJMP INT1_ISR ;外部中断1入口

ORG 001BH

LJMP T1_ISR ;定时器1中断入口

ORG 0023H

LJMP UART1_ISR ;串口1中断入口

slide210
ORG 002BH

LJMP ADC_ISR ;ADC中断服务程序入口

ORG 0033H

LJMP LVD_ISR

;低电压检测中断服务程序入口

ORG 003BH

LJMP PCA_ISR ;PCA中断服务程序入口

ORG 0043H

LJMP UART2_ISR;串口2中断服务程序入口

ORG 004BH

LJMP SPI_ISR ;SPI中断服务程序入口

slide211
ORG 0053H

LJMP INT2_ISR;INT2中断服务程序入口

ORG 005BH

LJMP INT3_ISR ;INT3中断服务程序入口

ORG 0063H

LJMP T2_ISR ;定时器2中断服务程序入口

ORG 0083H

LJMP INT4_ISR ;INT4中断服务程序入口

slide212
ORG 0100H

MAIN: MOV SP,#70H

;设置堆栈指针(可根据实际情况进行修改)

……;初始化内存区域内容

……;设置有关特殊功能寄存器(SFR)的控制字

……;根据需要开放相应的中断控制

MAINLOOP:

;主程序循环

LJMP MAINLOOP

slide213
;下面是各个中断服务子程序的入口

INT0_ISR: ;外部中断0服务子程序

…… ;根据需要填入适当的内容

RETI

INT1_ISR: ;外部中断1服务子程序

…… ;根据需要填入适当的内容

RETI

T0_ISR: ;定时器0中断服务子程序

…… ;根据需要填入适当的内容

RETI

T1_ISR: ;定时器1中断服务子程序

…… ;根据需要填入适当的内容

RETI

UART1_ISR: ;串口1中断服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

slide214
UART2_ISR: ;串口2中断服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

ADC_ISR: ;ADC中断服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

SPI_ISR: ;SPI通信中断服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

LVD_ISR: ;低电压检测服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

PCA_ISR: ;PCA和PWM中断服务子程序

…… ;根据需要填入适当的内容(注意中断请求标志位的清零)

RETI

;下面可以编写其他子程序或者定义程序中所用的常数

slide215
INT2_ISR: ;INT2中断服务子程序

…… ;根据需要填入适当的内容

RETI

INT3_ISR: ;INT3中断服务子程序

…… ;根据需要填入适当的内容

RETI

T2_ISR: ;定时器2中断服务子程序

…… ;根据需要填入适当的内容

RETI

INT4_ISR: ;INT4中断服务子程序

…… ;根据需要填入适当的内容

RETI

;下面可以编写其他子程序或者定义程序中所用的常数

END

slide216
注意
    • 由于地址0003H、000BH、0013H、001BH、0023H 、002BH、0033H、003BH、0043H、004BH、0053H、005BH、0063H和0083H是专门为中断处理子程序分别预留的入口地址,所以第一条指令是一条长跳转指令,跳到避开上述中断处理子程序入口地址的0100H的地址,主程序MAIN从这个地址开始存放,MAIN 语句前面的伪指令“ORG 0100H”表示,以标号MAIN表示的主程序放在0100H开始的区域,当然也可以是跳到能够避开上述入口地址的其他地址。
slide217
如果用户系统根本没有任何中断源,或者没有使用全部中断源,就可以不用或者少用中断的功能,0003H到0083H的区域也就无须全部或部分用于中断处理。没有任何中断的情况下,主程序甚至可以从0000H开始连续存放下去。如果用户系统根本没有任何中断源,或者没有使用全部中断源,就可以不用或者少用中断的功能,0003H到0083H的区域也就无须全部或部分用于中断处理。没有任何中断的情况下,主程序甚至可以从0000H开始连续存放下去。
  • 主程序的末尾是一条长跳转指令,跳转到某个合适的地方反复执行主程序。一般的子程序不可形成死循环,但是作为整个主程序却应该是一个最大的死循环。无论执行哪个子程序,之后都要回到主程序,反复循环运行。
slide218
程序流程图
    • 在程序编制以前,先根据系统方案绘制程序流程图是一个很好的方法。
    • 程序流程图可以简洁清晰地将程序的分支走向标示清楚,尤其是在程序复杂,编写人员较多相互衔接容易出错的的情况下,利用流程图理顺各部分关系显得尤为重要。
slide219
画流程图有两个常用的结构:顺序执行的矩形框和条件分支的菱形框。画流程图有两个常用的结构:顺序执行的矩形框和条件分支的菱形框。
    • 顺序执行:某个局部功能或者顺序执行的语句使用矩形方框表示,矩形方框内注明程序的功能,各方框之间用箭头表示执行顺序,一目了然;
    • 条件分支:遇到需要根据条件判断是否转移时,使用菱形方框表示,菱形框内注明分支条件,不同出口表明分支的去向。
slide221
循环程序设计
  • 当程序处理的对象具有重复性规律时,可以使用循环程序设计。一个循环表示重复执行一组指令(程序段)。

图4-17 典型循环程序结构的流程图

slide222
三、典型汇编语言程序设计举例

1、分支程序设计

2、查表程序设计

3、循环程序设计

4、定点数运算子程序设计

5、数据排序程序设计

6、代码转换程序设计

slide223
1、分支程序设计

程序分支是通过条件转移指令实现的,即根据条

件进行判断后决定程序的走向。条件满足则进行程

序转移,不满足就顺序执行程序。

  • 通过条件判断实现单分支程序转移的指令有JZ、JNZ、CJNE和DJNZ等。
  • 以位状态为条件,进行程序分支的指令JC、JNC、JB、JNB和JBC等。
slide224
【例4-9】编程实现下面的比较函数。设变

量x存放在R0,求得的y 值存入SIGN单元。

解:可以利用CJNE指令和进位位C状态控制转移(JC指令)来实现三分支转移。

slide225
SIGN EQU 50H

ORG 0000H

LJMP MAIN

ORG 0100H

MAIN: CJNE R0,#37,NOTEQ;R0与37比较,不相等则转NOTEQ

MOV SIGN,#00H ;若比较相等,则SIGN←0

LJMP ENDM

NOTEQ:JC NEG ;两数不相等,若R0<37则转NEG

MOV SIGN,#01H ;R0>37时,SIGN←+1

LJMP ENDM

NEG: MOV SIGN,#0FFH ;R0<37时,SIGN←-1

ENDM:NOP

END

slide226
2、查表程序设计
  • 查表法产生的背景
    • 参数的计算非常复杂;
    • 公式计算法计算程序长,难于计算;
    • 需要耗费大量时间;
    • 非线性参数,无法用一般算术运算就可以计算出来,如指数、对数、三角函数以及积分、微分等运算;
    • 数学计算无法建立相应的数学模型。
  • 查表法定义

就是把事先计算或测得的数据按一定顺序编制成表格,查表程序根据被测参数的值或者中间结果,查出最终所需要的结果。它具有程序简单,执行速度快等优点。

slide227
应用举例
    • 在键盘处理程序中,查找按键相应的命令处理子程序的入口地址;
    • 在LED显示程序中,获得LED数码管的显示字模;
    • 在一些快速计算的场合,根据自变量的值,从函数表上查找出相应的函数值以及实现非线性修正、代码转换等等。
  • 常用MOVC A,@A+DPTR查找程序存储器空间的代码或常数,每次传送一个字节。
slide228
例如,假如要显示的数据在累加器A中,采用共阳极例如,假如要显示的数据在累加器A中,采用共阳极

LED显示,则可以采用下面的查表法获得LED显示字模:

MOV DPTR, #SEGTAB;获得字模表的首地址

MOVC A,@A+DPTR;查表获得字模

…… ;下面可以送出字模进行显示

SEGTAB:DB 0C0H ;0的字模

DB 0F9H ;1的字模

DB 0A4H ;2的字模

DB 0B0H ;3的字模

DB 99H ;4的字模

DB 92H ;5的字模

DB 82H ;6的字模

DB 0F8H ;7的字模

DB 80H ;8的字模

DB 90H ;9的字模

slide229
3、循环程序设计
  • 延时程序是典型的循环程序。
  • 下面就以延时程序为例,说明循环程序的设计方法。延时程序是典型的循环程序,流程图如图所示。

图4-18 延时程序流程图

slide230
简单延时子程序如下(注释部分为指令的时钟周期数):简单延时子程序如下(注释部分为指令的时钟周期数):

MOV R7,#150 ;2

LOOP:DJNZ R7,LOOP;4

RET

STC15F2K60S2为1T的8051单片机,当系统时钟为6MHz时,每个时钟周期为1/6us,上述程序可延时约0.1ms。为了达到准确延时的目的,可以在适当的地方加入NOP指令。

slide231
若需要加长延时时间,可采用多重循环延时程序方法。若需要加长延时时间,可采用多重循环延时程序方法。
  • 下面介绍的延时程序,内循环为单位延时(0.1ms),外循环次数可在调用前设定,根据设定值不同,可在0.1~25.5ms任选延时。
    • 入口:设延时时间N(以0.1ms为单位)送入R0。
    • 出口:延时到,退出程序,无参数传递。

DELAY:MOV R7, #150

;当时钟为6MHz时,延时约0.1ms

LOOP:DJNZ R7,LOOP

DJNZ R0,DELAY

RET

slide232
4、定点数运算子程序设计

多字节无符号加法子程序和减法子程序设计较简

单,在此介绍有代表性的多字节BCD码减法程序和

多字节乘法程序的设计。

(1)多字节十进制BCD码减法

由于指令系统中只有十进制加法调整指令DA

A,也即该指令只有在加法指令(ADD、ADDC)

后,才能得到正确的结果。为了用十进制加法调整

指令对十进制减法进行调整,必须采用补码相加的

办法,用9AH减去减数即得以十为模的减数的补码。

slide233
入口:被减数低字节地址存放于R1,减数低字节地址存放于R0,字节数存放于R2。入口:被减数低字节地址存放于R1,减数低字节地址存放于R0,字节数存放于R2。
  • 出口:差(补码)的低字节地址存放于R0,字节数存放于R3。

07H为符号位。0表示结果为正,1表示结

果为负。

slide234
SUBCD: MOV R3,#00H ;差字节数置0

CLR 07H ;符号位清0

CLR C ;借位位C清0

SUBCD1: MOV A,#9AH

SUBB A,@R0 ;相差

ADD A,@R1

DA A

MOV @R0,A

INC R0 ;地址值增1

INC R1

INC R3 ;差字节增1

slide235
CPL C

;进位求反,以形成正确借位

DJNZ R2,SUBCD1

;未减完继续,减完向下执行

JNC SUBCD2

;无借位去SUBCD2返主,否则继续

SETB 07H ;差为负置“1”符号位

SUBCD2: RET ;返回

slide236
程序说明
    • 程序中,减数求补后与被减数相加,方可利用DA A指令进行调整
    • 若二者相加调整后结果无进位(C=0),实际上表示二者相减有借位
    • 若二者相加调整后有进位(C=1),则进行求反操作。
slide237
求BCD码8943H - 7649H=?为例进行测算。

先对低位字节运算:

10011010 9A

-) 01001001 49

01010001 得49对100补码51

+) 01000011 加43

0 10010100 差为94

C=0无进位,表示二者相减有借位。应对借位标

志求反使C=1。

slide238
再对高字节运算:

10011010 9A

-) 01110110 76

00100100 得76对100补码为24

-) 00000001 减去借位位C=1

00100011 得减数减1后的值为23

-) 10001001 加被减数89

10101100

+) 01100110 对结果加66修正

1 00010010 差为12

slide239
高字节减数变补与减数相加有进位,实际上表示两者相减无借位,为正确反映借位情况应对进位标志求反使C=0(减去时C=1,表示有借位;C=0,表示无借位)。高字节减数变补与减数相加有进位,实际上表示两者相减无借位,为正确反映借位情况应对进位标志求反使C=0(减去时C=1,表示有借位;C=0,表示无借位)。
  • 最后运算结果差为1294H,且无借位,计算正确。
slide240
(2)多字节乘法运算子程序
  • STC15F2K60S2单片机指令系统中只有单字节的乘法指令MUL AB,而在工程应用中常需8位乘16位、两个16位数相乘的运算。
slide241
以两个16位无符号数相乘为例说明多字节乘法程序设计。设被乘数存放在R2、R3两单元(高字节在前),乘数存放在R6、R7两单元,两个双字节无符号数相乘,结果送33H、32H、31H、30H。该算法的示意图如图所示。以两个16位无符号数相乘为例说明多字节乘法程序设计。设被乘数存放在R2、R3两单元(高字节在前),乘数存放在R6、R7两单元,两个双字节无符号数相乘,结果送33H、32H、31H、30H。该算法的示意图如图所示。
  • 其中(R3R7)L表示R3×R7的低8位,

(R3R7)H表示R3×R7的高8位,

其余几项的含义类似。

程序如下:

图4-19 多字节乘法运算流程

slide242
DMUL: MOV A,R3

MOV B,R7

MUL AB;R3×R7

MOV 30H,A ;(30H) ← (R3×R7)L

MOV 31H,B ;(31H) ← (R3×R7)H

MOV A,R2

MOV B,R7

MUL AB;R2×R7

ADD A,31H ;(R3×R7)H+(R2×R7)L

MOV 31H,A

CLR A

ADDC A,B

MOV 32H,A ;(32H) ← (R2×R7)H

slide243
MOV A,R3

MOV B,R6

MUL AB;R3×R6

ADD A,31H

MOV 31H,A

MOV A,B

ADDC A,32H ;(R2×R7)H+(R3×R6)H

MOV 32H,A

MOV F0,C ;暂存Cy

slide244
MOV A,R2

MOV B,R6

MUL AB;R2×R6

ADD A,32H

MOV 32H,A

CLR A

MOV ACC.0,C

MOV C,F0 ;加前次加法的进位

ADDC A,B

MOV 33H,A

RET

slide245
5、数据排序程序设计
  • 数据排序是将数据块中的数据按升序或降序排列。下面以数据的升序排序为例,说明数据排序程序的设计方法。
  • 数据升序排列常采用冒泡法。冒泡法是一种相邻数据互换的排列方法,同查找极大值的方法一样,一次冒泡即找到数据块的极大值放到数据块最后,再一次冒泡时,次大数排在倒数第二位置,多次冒泡实现升序排列。
slide246

图4-20 冒泡法数据排序程序流程图

  • 例如,将片内RAM 30H~37H中的数据从小到大升序排列。
  • 设R7为比较次数计数器,初值为07H。
  • F0为冒泡过程中是否有数据交换的状态标志,F0=0表示无交换发生,F0=1表示有互换发生,须继续循环。
  • R0为指向RAM单元的地址指针初值为30H。流程图如图所示。
slide247
程序如下:

SORT: MOV R6,#07H

GOON: CLR F0 ;交换标志清0

MOV R0,#30H ;数据首址送R0

MOVA,R6

MOV R7,A ;各次冒泡比较次数送R7

LOOP: MOV A,@R0 ;取前数

MOV3BH,A ;存前数

INC R0

MOV 3AH,@R0 ;取后数

CLR C

CJNE A,3AH,EXCH

LJMP NEXT

slide248
EXCH: JC NEXT ;前数小于后数不交换

MOV @R0,3BH

DEC R0

MOV @R0,3AH ;前后数交换

INC R0

SETB F0 ;置交换标志位

NEXT: DJNZ R7,LOOP ;未比较完,进行下一次比较

JNB F0,DONE

;一次也没有交换,说明已经按顺序排列

DJNZ R6,GOON ;更新下一轮比较次数

DONE: RET ;返回

slide249
6、代码转换程序设计
  • 在汇编语言程序设计中,数据输入/输出、A/D、D/A转换等常采用BCD码,字符的存储用ASCII码,算术逻辑运算又采用二进制数。
  • 除了用硬件逻辑实现转换外,可采用算法处理和查表方法软件实现。
slide250
(1)4位二进制数转换为ASCII代码
  • 从ASCII编码表可知,若4位二进制数小于10,则此二进制数加上30H即变为相应的ASCII码,若大于10(包括等于10),则应加37H。
    • 入口:转换前4位二进制数存R2。
    • 出口:转换后的ASCII码存R2。
slide251
ASCB1:MOV A,R2

ANL A,#0FH ;取出4位二进制数

CJNE A,#0AH,NOTA

;影响CY标志,但是不改变A中的值

NOTA: JC LOOP ;该数<10去LOOP

ADD A,#07H ;否则加07H

LOOP: ADD A,#30H ;加30H

MOV R2,A ;转换之ASCII码送R2中

RET ;返回

slide252
(2)ASCII码转换为4位二进制数
  • 入口:转换前ASCII码送R2。
  • 出口:转换后二进制数存R2中。

BCDB1:MOV A,R2

CLR C

SUBB A,#30H ;ASCII码减30H

MOV R2,A ;得二进制数送R2

SUBB A,#0AH

JC LOOP ;该数<10返回主程序

MOV A,R2

SUBB A,#07H ;否则再减07H

MOV R2,A ;所得二进制数送R2

LOOP:RET ;返回

slide253
(3)BCD码转换为二进制码子程序
  • 例:设有用BCD码表示的4位十进制数分别存于R1、R2中,其中R2存千位和百位数,R1存拾位和个位数,要把其转换成二进制码。
  • 解决思路:可用由高位到低位逐位检查BCD码的数值,然后累加各十进制位对应的二进制数来实现。其中,1000=03E8H,100=0064H,10=000AH(个位数的BCD码与二进制码相同)。
slide254
入口:待转换的BCD码存于R1、R2中,分配如下:入口:待转换的BCD码存于R1、R2中,分配如下:

低位字节 R1

高位字节 R2

  • 出口:结果存在20H、21H单元中,其中20H存低字节,21H存高字节。
slide255
BCDB11:MOV 20H,#00H

MOV 21H,#00H ;存结果单元清0

MOV R3,#0E8H

MOV R4,#03H ;1千的二进制数送R3、R4

MOV A,R2

ANL A,#0F0H ;取千位数

SWAP A ;将千位数移至低四位

JZ BRAN1 ;千位数为0去BRAN1

LOOP1: DEC A

LCALL ADDT

;千位数不为0,加千位数二进制码

JNZ LOOP1

slide256
BRAN1:MOV R3,#64H

MOV R4,#00H ;百位数的二进制码送R3、R4

MOV A,R2

ANL A,#0FH ;取百位数

JZ BRAN2

;百位数是0去BRAN2,否则继续

LOOP2: DEC A

LCALL ADDT

JNZ LOOP2 ;加百位数的二进制码

slide257
BRAN2: MOV R3,#0AH

MOV A,R1

ANL A,#0F0H ;取拾位数

SWAP A

JZ BRAN3 ;拾位数为0去BRAN3,否则继续

LOOP3: DEC A

LCALL ADDT

JNZ LOOP3 ;加拾位数的二进制码

BRAN3: MOV A,R1

ANL A,#0FH

MOV R3,A

LCALL ADDT

RET

slide258
ADDT: PUSH PSW

PUSH ACC

CLR C

MOV A,20H ;在20H、21H单元中

ADD A,R3 ;累计转换结果

MOV 20H,A

MOV A,21H

ADDC A,R4

MOV 21H,A

POP ACC

POP PSW

RET

slide259
7、STC15F2K60S2单片机双数据指针的使用
  • 两个16位的数据指针:DPTR0和DPTR1。它们的逻辑地址相同,但是物理上是独立的。
  • 功能:利用这两个数据指针,可以方便地进行数据的迁移和拷贝。
  • 使用方法:这两个数据指针在指令中只能以DPTR的形式出现,因此,在使用中,需要进行切换。这种切换是通过设置辅助寄存器AUXR1中的DPS位实现的。
    • 当DPS选择位为0时,选择DPTR0;
    • 当DPS选择位为1时,选择DPTR1。辅助寄存器AUXR1各位定义如下:
slide260
DPS:DPTR寄存器选择位。
    • 0:选择DPTR0;
    • 1:选择DPTR1
slide261
【例4-10】编程实现将单片机内部扩展RAM中0000H~000FH单元中的内容传送到0040H~004FH单元中。【例4-10】编程实现将单片机内部扩展RAM中0000H~000FH单元中的内容传送到0040H~004FH单元中。
  • 思路:可以分别由DPTR0和DPTR1分别指向源数据地址和目的数据地址。
slide262
编程如下:

AUXR1 DATA 0A2H

ORG 0000H

LJMP MAIN

ORG 0100H

MAIN: MOV SP,#30H ;设置堆栈指针

MOV R2,#10H ;设置计数值

ANL AUXR1,#0FEH ;DPS.0=0,选择DPTR0

MOV DPTR,#0000H ;设置源数据地址指针

ORL AUXR1,#01H ;DPS.0=1,选择DPTR1

;该句可用INC AUXR1代替(思考:为何?)

MOV DPTR,#0040H ;设置目的数据地址指针

LOOP: ANL AUXR1,#0FEH ;该句可用INC AUXR1代替

MOVX A,@DPTR

INC DPTR ;修正源数据地址指针

ORL AUXR1,#01H ;该句可用INC AUXR1代替

MOVX @DPTR,A

INC DPTR ;修正目的数据地址指针

DJNZ R2,LOOP

SJMP $ ;$表示本条语句的地址。SJMP $相当于HERE: SJMP HERE

END

slide263
8、STC15F2K60S2单片机数据Flash(EEPROM)的使用
  • STC15F2K60S2单片机片内集成了1KB的数据Flash存储器,可以作为EEPROM使用,用来保存程序的设置参数。
slide264
【例4-11】一个完整的数据Flash操作实例。

$INCLUDE (STC15.INC)

;包含STC15F2K60S2单片机寄存器定义文件

;定义ISP/IAP命令

ISP_IAP_BYTE_READ EQU 1H ;字节读

ISP_IAP_BYTE_PROGRAM EQU 2H ;字节编程

ISP_IAP_SECTOR_ERASE EQU 3H ;扇区擦除

;定义Flash操作等待时间及允许IAP/ISP操作的常数(设置IAP_CONTR)

ENABLE_IAP EQU 82H ;系统工作时钟<20MHz时

DEBUG_DATA EQU 5AH

;EEPROM单元的测试值,如正确应等于该值

START_ADDRESS EQU 0000H ;EEPROM测试起始地址

slide265
ORG 0000H

LJMP MAIN

ORG 0100H

MAIN: MOV SP, #70H ;堆栈指针指向 70H单元

LCALL Delay ;延时

;读出EEPROM测试起始地址单元的内容

MAIN1: MOV DPTR, #START_ADDRESS

;将EEPROM测试起始地址送DPTR数据指针

LCALL Byte_Read

MOV 40H, A ;将EEPROM 的值送40H 单元保存

CJNE A, #DEBUG_DATA, NOT_EQU_DEBUG_DATA

;如果数据不正确,就跳转

;数据正确时,可以进行其他操作

LCALL Delay ;延时

SJMP $ ;数据正确,CPU在此无限循环执行此句

slide266
NOT_EQU_DEBUG_DATA:

;此处存放EEPROM里的数据错误时,需要进行的处理程序代码

;将该EEPROM所在的扇区整个擦除,将正确的数据写入

LCALL Delay ;延时

MOV DPTR,#START_ADDRESS

;将EEPROM测试起始地址送DPTR数据指针

LCALL Sector_Erase ;擦除整个扇区

MOV DPTR, #START_ADDRESS

;将EEPROM测试起始地址送DPTR数据指针

MOV A, #DEBUG_DATA

;写入 EEPROM 的数据为 #DEBUG_DATA

LCALL Byte_Program ;字节编程

SJMP $ ;字节编程后,CPU在此无限循环执行此句

slide267
;--------- 读一字节 --------------------------------

;读一字节,调用前需打开IAP功能,入口:DPTR=字节地址,返回:A=读出字节

Byte_Read:

MOV IAP_CONTR,#ENABLE_IAP ;打开IAP功能,设置Flash操作等待时间

MOV IAP_CMD,#ISP_IAP_BYTE_READ ;设置为IAP/ISP字节读模式命令

MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址

MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址

MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器

MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动

NOP

MOV A,IAP_DATA ;读出的数据在IAP_DATA单元中,送入累加器A

LCALL IAP_Disable ;关闭IAP功能, 清相关的特殊功能寄存器

RET

slide268
;------------------- 字节编程 ------------------------

;字节编程,调用前需打开IAP功能,入口:DPTR=字节地址, A=需写入的数据

Byte_Program:

MOV IAP_CONTR, #ENABLE_IAP;打开IAP功能,设置 Flash 操作等待时间

MOV IAP_CMD, #ISP_IAP_BYTE_PROGRAM ;设置为字节编程模式命令

MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址

MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址

MOV IAP_DATA, A ;要编程的数据先送进ISP_DATA寄存器

MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器

MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动

NOP

LCALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器

RET

slide269
;------------------- 字节编程 ------------------------

;字节编程,调用前需打开IAP功能,入口:DPTR=字节地址, A=需写入的数据

Byte_Program:

MOV IAP_CONTR, #ENABLE_IAP;打开IAP功能,设置 Flash 操作等待时间

MOV IAP_CMD, #ISP_IAP_BYTE_PROGRAM ;设置为字节编程模式命令

MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址

MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址

MOV IAP_DATA, A ;要编程的数据先送进ISP_DATA寄存器

MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器

MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动

NOP

LCALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器

RET

slide270
;------------------- 字节编程 ------------------------

;字节编程,调用前需打开IAP功能,入口:DPTR=字节地址, A=需写入的数据

Byte_Program:

MOV IAP_CONTR, #ENABLE_IAP;打开IAP功能,设置 Flash 操作等待时间

MOV IAP_CMD, #ISP_IAP_BYTE_PROGRAM ;设置为字节编程模式命令

MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址

MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址

MOV IAP_DATA, A ;要编程的数据先送进ISP_DATA寄存器

MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器

MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动

NOP

LCALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器

RET

字节读操作也可以使用MOVC指令,使用MOVC访问数据Flash存储器时,其地址范围为F000H~F3FFH。

slide271
§4.10汇编语言程序调试

程序编写完成后,并不一定能够保证实现

所期望的功能,一般都需要使用集成开发环

境对程序进行调试和验证。

常见的集成开发环境是Keil uVision。

slide272
Keil集成开发环境中包括一个项目管理器,要创建一个应用,需要按下列步骤进行操作:Keil集成开发环境中包括一个项目管理器,要创建一个应用,需要按下列步骤进行操作:
    • 启动Keil,新建一个项目文件并从器件库中选择一个器件。
    • 新建一个源文件并把它加入到项目中。
    • 针对目标硬件设置工具选项。
    • 编译项目并生成可以编程到程序存储器的HEX文件。
    • 下载到单片机中进行仿真调试。
slide273

出错的行

双击错误信息行,可进行错误定位

利用教材中的例子进行演示!

4 11 isp
4.11利用ISP工具将程序下载到单片机中验证程序4.11利用ISP工具将程序下载到单片机中验证程序

一、ISP下载程序的运行过程

图4-41 STC15F2K60S2单片机ISP编程流程

slide275
使用ISP功能时,需要注意以下几点:
    • 如果用户系统的P3.0和P3.1连接到RS-485电路,下载程序时,需要将其断开。并且,建议在下载选项中选择“下次冷启动时需P3.2/P3.3=0/0才可以下载程序”。
    • 要使用ISP功能,必须让单片机掉电后重新上电,外部手动复位或者看门狗复位都不能使单片机运行ISP程序。
    • 单片机运行ISP程序时,检测有无合法下载命令流,大约需要时间几十ms~几百ms,如果没有合法的下载命令流,则立即运行用户程序。
slide276
使用ISP功能时,需要注意以下几点:
    • 如果已设置只有当P3.2和P3.3同时为0时,才判断是否下载用户程序,则冷启动后,如果P3.2和P3.3不同时为0,则直接运行用户程序,只会占时50uS,可忽略不计。
    • 程序调试完成后,建议用户选择P3.2和P3.3不同时为0,立即运行用户程序,跨过系统ISP监控程序。这样可以加快用户系统的启动速度。
    • 使用ISP下载程序时,计算机端的控制软件必须先发下载命令流,再给单片机上电复位。
slide277
二、使用ISP工具下载程序的步骤

利用教材中的例子进行演示!

ad