www.8951.com

进入论坛

淘宝网店

软件下载

返回主页 单片机教程 单片机软件 电路设计 电子基础 网站产品 购买方式  进入论坛 软件下载

单片机的指令(二)

  这一课继续讲解其他的数据类指令。提示:下面的内容我们下册中才会用到,这里只是为了把数据传递类指令讲完,才提前把它们讲一下,您不知道也没关系。

一.数据传递类指令 .累加器A 与片外RAM 之间的数据传递类指令什么是片外RAM(即片外数据存储器)呢?单片机不是有内部RAM 吗?为什么还要片外RAM 呢?难道单片机的内部RAM 还不够用吗?的确如此,当单片机的内部RAM 不够时,我们就要扩充RAM 空间。那么单片机能扩充多少的外部RAM空间呢?89C51 单片机的片外RAM可以扩展到64K,即从0000H-FFFFH,那么它是怎样和累加器A 进行数据传递的?

 

它们之间的传递指令共有以下四条:

1 MOVX A@Ri

2 MOVX @RiA

3 MOVX A@DPTR

4 MOVX @DPTRA

指令说明: A.在51 系列单片机中,与外部存储器RAM 传递数据的只可以是累加器A,所有要送入或读出外部RAM 的数据必须先送到A 中去,在此我们可以看出内外部RAM 的区别了:内部RAM 间可以直接进行数据的传递,而外部RAM 则不行。比如,要将外部RAM 中某一单元(设为100H 单元的数据)送入另一个单元(设为200H 单元),就必须先将100H 单元中的内容读入A,然后再送到200H 单元中去。

   在这里有一个问题:CPU 是如何区分内、外部RAM 的?大家看这里的四条指令,其操作码都是MOVX ,而内部RAM 的操作码则是MOVCPU 就是根据不同的指令来自动区分读写内、外部RAM 的。

B.要读出或写入外部的RAM ,当然还必须知道外部RAM 的地址,在后两条指令中,地址是被直接放在DPTR 中的;而前两条指令由于Ri(即R0 R1)只是一个8 位的寄存器,所以只能提供低8 位的地址。不过有时我们要扩展的外部RAM 数量比较少(少于或等于256 个字节),提供低8 位的地址也就足够了。

C.使用时应当首先将要读出或写入的地址送入DPTR Ri 中,然后再用读写指令。举例:将外部RAM 100H 单元中的内容送入外部RAM 200H 单元中。

MOV DPTR#0100H

MOVX A@DPTR

MOV DPTR,#0200H

MOVX @DPTR,A 7

累加器A 与片外ROM 之间的数据传递类指令 MOVC AA+@DPTR

前一小节讲了累加器A 与外部RAM 之间的数据传递类指令,接下来再来讲讲片外ROM 与累加器A 之间的数据传递类指令。在讲解之前,先来了解一下内部ROM 和外部ROM 的组成,89C51 的内部有4K FLASH ROM 空间,其地址为000H-FFFH ,片外可以扩展到64KOOOOH-FFFFH),在这64K ROM 空间中,有4K 字节的地址是片内和片外公用的(即000H-FFFH),而1000H-FFFFH 的空间是片外ROM 专用的。

 

    讲到这里大家就会问:既然有4K 的地址是公用的,那么CPU 是如何区分的呢?不知大家是否还记得,在第二讲单片机的硬件电路中,有一个引脚EA(即31 脚),当EA=1CPU 从片内ROM 4K 字节中取指令,如果地址超过了4KFFFH),单片机就自动转向片外ROM 取指令,大家注意:这个过程是自动完成的,不需要人工干预;而当EA=0 时,CPU 只从片外ROM 取指令。讲到这里,不知大家注意没有,当使用外部ROM 和外部RAM 时,它们的寻址空间都是0000H-FFFFH,也就是说它们在地址上是重叠的,那么CPU 在读取指令时又是如何来区分当前是从ROM 取指令还是从单片机教程(MCS-51 系列) RAM 取指令呢?请大家来看第二课的89C51 单片机硬件电路图,29 脚是PSEN ,当我们置位PSEN 时(即PSEN=1),CPU 就读取外部ROM 指令;而要从外部RAM 读取指令时就置位WR(即16 脚)或RD(即17 脚),这样即使ROM 地址和RAM 地址是重叠的,也不会出现混乱。

   这里又有一个问题了,16 脚和17 脚不是并行口P3.6 P3.7 吗?如果我们把它当作第二功能WR RD 来使用,CPU 又是如何来区分的呢?这个问题我们前面已经讲过了,这里再重复一遍:单片机引脚的第二功能是不需要人工干预的,也就是说只要CPU 执行到相应的指令,就自动转成了第二功能。了解了片外ROM 的读取指令原理,再来看片外ROM 与累加器A 之间的数据传递指令(注意ROM 只能读取指令,而不能写入数据,这一点和RAM 是不同的)。

 

    MOVC AA+@DPTR 指令说明:

A.本指令是将ROM 中的数送入A 中。通常称其为查表指令,常用此指令来查一个已做好在ROM 中的表格。

B.此条指令引出一个新的寻址方法:变址寻址。本指令是要在ROM 的一个地址单元中找出数据,显然必须知道这个单元的地址,这个单元的地址是这样确定的:在执行本指令前DPTR 中有一个数,A 中也有一个数,执行指令时,将A DPTR 中的数加起来,就成为要查找的数的单元地址。

C.查找到的结果被放在A 中,因此,本条指令执行前后,A 中的值不一定相同。 举例:有一个数在R0 中,要求用查表的方法确定它的平方值(此数取值范围是0-5

MOV DPTR#TAB

MOV AR0

MOVC A@A+DPTR

TAB: DB 0,1,4,9,16,25

R0 中的值为�2�,送入A 中,而DPTR 中的值则为�TAB�,则最终确定的ROM 单元的地址就是�TAB+2�,也就是到�TAB+2 �这个单元中去取数,取到的是�4�(Db 后面的第三个数)。其它数据也可以次类推。

    从这里可以看出,我们使用了标号(象TAB 等)来代替具体的ROM 单元地址,事实上,标号的真实含义就是地址的数值,在这里它就代表了TAB+0TAB+1 TAB+25 这几个数据在ROM 中的存放位置;而我们以前学过的如LCALL DELAY 指令,DELAY 代表的是以DELAY 为标号的那段程序在ROM 中存放的起始地址,CPU 就是根据这个起始地址才找到指令的,无法理解是吗?没关系,让我们先来看几个符号的含义就会明白了。

 

二.单片机的伪指令(注意:伪指令不是单片机指令)我们前面简单提到过,END 是伪指令,那么到底什么是伪指令?它在单片机中有什么作用呢?接下来我们就来讨论这个问题,伪指令是单片机中用来给寄存器定义或者赋值的特殊指令为什么要用伪指令呢?让我们来看下面的实验:

1DB—定义字节伪指令它的功能是从程序存储器ROM 单元的某个地址开始,存入一组规定好的8 位二进制常数。例如:ORG 2000H TABDB 45H48H1034H;以上指令经汇编后,将对从2000H 开始的若干ROM 单元赋值,即(2000H=45H,(2001H=48H,(2002H=0AH,(2003H=34H。讲到这里,有的人会问:在这些指令中,我直接用MOV 2000H45HMOV 2001H48H ⋯⋯不就得了,干吗要用DB 指令呢?是的,从理论上讲,两者的效果是一样的,只是因为我们现在的程序都很短,单片机不可能只做这些简单的工作,当程序比较长时,这些指令的意义就不一样了。

除了刚刚提到的END DB 伪指令外,单片机中还有那些伪指令呢?下面简单讲解一下:

DW—定义字伪指令  在计算机中,一个字由两个字节组成,也就是说,如果一个字节可以表示一个8 位数的话,那么一个字就可以表示一个十六位的数(关于这方面的问题我们留到下册中再来讨论,这里就不讲了,以免增加大家的学习难度),如此一来,这条伪指令的功能也就清楚了,就是从指定的ROM 单元开始,定义若干个16 位常数;

 

  上一课我们已经讲过,51 系列单片机要存放一个16 位的常数就必须把这个数分成两个8 位数据来存放,通常我们把一个16 位数的高8 位放入低地址,而把低8 位放入高地址(注意:这两个地址必须是紧挨着的)。例如:ORG 3000H ABCDW 2345H0A859H;程序经汇编后,(3000H=23H,(3001H=45H,(3002H=A8,(3003H=59H。注意:象0A859H 这样的数值在写法上,A 的前面一定要加上个0

 

3DS—保留空间伪指令它的功能是从指定的地址开始,保留若干个字节的ROM 空间留作它用。例如:ORG 2000H ABCDS0 8H LOOPMOV A30H;汇编以后,从2000H 开始,将保留8 ROM 单元留作它用,那么以LOOP 为标号的指令就存放在2008H 单元中。这里有一点请大家注意:这几条伪指令都只能对程序存储器(ROM)起作用,而不能用它们来对数据存储器(RAM)进行赋值或做其他的工作。至于它们到底有什么作用,我们什么时候才需要用到它们?我们将在下册的实验中再作讲解。现在让我们通过一段程序来解释一下查表程序的使用方法,这可是一定要学会的。

 

例如:

MOV DPTR#100H

MOV AR0

MOVC A@A+DPTR . .

ORG 0100H DB 0,1,4,9,16,25

如果R0 中的值为“2”,则最终地址为“100H+2 ”即“102H”,到102H 单元中找到的是“4”。这个可以看懂了吧,那为什么不这样写程序,要用标号呢?不是增加疑惑吗?如果用标号写的话,在写程序时,就必须确定这张表格在ROM 中的具体位置。如果写完程序后,又想在这段程序前插入一段程序,那么这张表格的位置就又要变了(要改ORG 100H 这条指令),如果我们是经常需要修改程序的,那多麻烦,所以就用标号来替代,只要一编译程序,位置就自动发生变化,我们把这件事交给计算机去做了。

 

8.堆栈的操作指令什么是堆栈,我们前面已经介绍过了,那么堆栈是如何进行数据传递的呢?对堆栈的操作指令有2 条:

1PUSH direct 2POP direct

1 条指令称之为推入,就是将direct 中的内容送入到堆栈中;第2 条指令称之为弹出,就是将堆栈中的内容送回到direct 中。推入指令的执行过程是:首先将SP 中的值加1,然后把SP 中的值当作地址,将direct 中的值送进以SP 中的值为地址的RAM 单元中。例如:

MOV SP#5FH

MOV A#100

MOV B#20

PUSH ACC

PUSH B

这段指令的执行过程是这样的:将SP 中的值加1,即变为60H ,然后将A 中的值(#100 )送到60H 单元中,因此执行完PUSH ACC 这条指令后,内存60H 单元的值就是100 ,同样,执行PUSH B 时,是将SP+1 ,即变为61H ,然后将B 中的值送入到61H 单元中,即执行完本条指令后,61H 单元中的值变为20。这是推入,那么弹出又是怎么样的呢?请看下面的例子:

MOV SP#5FH

MOV A#100

MOV B#20

PUSH ACC

PUSH B

POP B

POP ACC

POP 指令的执行是这样的:首先将SP 中的值作为地址,并将此地址中的数送到POP 指令后面的那个direct 中,然后SP 1。上面程序的执行过程是:将SP 中的值(现在是61H)作为地址,取61H 单元中的数值(现在是20),送到B 中,所以执行完POP B 指令后B 中的值是20,然后将SP 1,那么此时SP 的值就变为60H ,然后执行POP ACC ,将SP 中的值(60H )作为地址,从该地址中取数(现在是100),并送到ACC 中,所以执行完本条指令后,ACC 中的值是100

 

这有什么意义呢?ACC 中的值本来就是100B 中的值本来就是20,是的,在本例中,的确没有意义,但在实际工作中,推入堆栈结束后(即执行指令PUSH B 后)往往要执行其他的指令,而且这些指令会把A 中的值和B 中的值改掉,所以在程序执行结束后,如果我们要把A B 中的值恢复原值,那么这些指令就有意义了,具体应用我们将在以后的课程中讲到。

 

这里还有一个问题,如果不用堆栈,比如说在PUSH ACC 指令处用MOV 60HA,在PUSH B 处用指令MOV 61HB,然后用MOV A60HMOV B61H 来替代两条POP 指令,不也一样吗?是的,从结果上看是一样的,但是从过程看是不一样的,PUSH POP 指令都是单字节,单周期指令,而MOV 指令则是双字节,双周期指令。更何况,堆栈的作用不止于此,所以一般的单片机上都设有堆栈,而我们在编写子程序,需要保存数据时,通常也采用堆栈的方法来实现。

 

 9.其他的数据传递类指令

1XCH ARn

2XCH Adirect

3XCH A@Ri

4XCHD A,@Ri

5MOVC AA+PC

 

前面的4 条指令是进行数据交换用的,第1 条,寄存器与累加器交换;第2 条直接地址与累加器交换;第3 条间接RAM 与累加器交换;第4 条间接RAM 与累加器的低4 位交换;第5 条是累加器与代码字节之间的数据传递类指令,这些指令作为初学者可能暂时还用不上,所以就不介绍了,大家只要了解一下就可以了,等下册中我们再来详细的讨论。

三.本课总结到本课为止,数据传递类指令全部讲解完了,在单片机的指令中,数据传递类指令是使用最多的指令,因此这部分的内容是必须掌握的,如何来使用这些指令,我们将在以后的课程中结合具体的实验加以介绍。为了加深印象,大家可以用DUBG8051 软件对上述指令进行反复练习,用实验结果来加深课堂知识。

 

单片机经典教程

 第一课 单片机的概述和分类

 第二课 单片机引脚功能介绍

 第三课 单片机内部结构(一)

 第四课 单片机内部结构(二)

 第五课 单片机内部结构(三)

 第六课 单片机内部结构(四)

 第七课 单片机内部结构(五)

 第八课 单片机内部结构(六)

 第九课  单片机是如何工作的?

 第十课 寻址是如何实现的

 第十一课 单片机的指令(一)

 第十二课 单片机的指令(二)

 第十三课 单片机的指令(三)

 第十四课 单片机的指令(四)

 第十五课 单片机的指令(五)

 第十六课 单片机程序的设计

 第十七课 单片机定时/计数器

 第十八课 单片机的中断系统

 第十九课 定时与中断实验一

 第二十课 定时与中断实验二

 第二十一课 键盘接口与编程一

 第二十二课 键盘接口与编程二

 第二十三课 数码管接口与编程1

 第二十四课 数码管接口与编程2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

XL2000单片机开发板&实验仪 XL600+51mini仿真器 xl400+51mini开发板 XL400单片机学习开发板 XL600编程实验单片机开发板
 
EP3.0支持stc双串口编程器 Ep51 单片机编程器 Top853 usb通用编程器 Top2007多功能编程器 GENIUS UPL800通用编程  

编辑:学林单片机@ 修订1.3 2010-01-25  学林电子,中国单片机学习板和开发板第一品牌   本文8951.com版权所有,未经书面批准转载必究。

当前共1030篇单片机基础入门文章,更多精彩内容请进入学林单片机论坛   联系我们 法律声明  粤ICP备05015330号