(玩电子) 电子技术学习与研究
当前位置单片机教程网 >> 基础教程 >> 浏览文章

8课:单片机寻址方式与指令系统

作者:佚名   来源:本站原创   点击数:x  更新时间2007年08月16日   字体

   通过前面的学习我们已经了解了单片机内部的结构并且也已经知道要控制单片机让它为我们干学要用指令我们已学了几条指令但很零散从现在开始我们将要系统地学习8051单片机的指令部份

一概述

1指令的格式

   我们已知要让计算机做事就得给计算机以指令并且我们已知计算机很笨保只能懂得数字如前面我们写进机器的75H90H00H等等所以指令的第一指式就是机器码格式也说是数字的形式但这中式实在是为难我们人了太难记了于是有另一指式助记符格式如MOV P1#0FFH这样就好记了 这两指式之间的关系呢我们不难理解本质上它们完全等价只是形式不一样而已

2汇编

  我们写指令使用汇编格式而计算机和单片机只懂机器码格式所以要将我们写的汇编格式的指令转换为机器码格式这种转换有两种办法手工汇编和机器汇编手工汇编实际上就是查表因为这两指式纯粹是格式不一样所以且一对应的查一张表格就行了不过手工查表总是嫌麻常所以就有了计算机软件用计算机软件来替代手工查表这就是机器汇编

二单片机的寻址

  让我们先来复习一下我们学过的一些指令MOV P1#0FFHMOV R7#0FFH这些指令都是将一些数据送到对应的位置中去为什么要送数据呢第一个因为送入的数能让灯全灭掉第二个是为了要实现延时从这里我们能看出来在用单片机的编程语言编程时经常要用到数据的传递事实上数据传递是单片机编程时的一项重要工作一共有28条指令单片机共111条指令下面我们就从数据传递类指令开始吧

  分析一下MOV P1#0FFH这条指令我们不难得出结论第一个词MOV是命令动词也就是决定做什么事情的MOV是MOVE少写了一个E所以就是传递保这就是指令规定做什么事情后面还有一些参数分析一下数据传递必须要有一个础也就是你要送什么数必须要有一个目的保也就是你这个数要送到什么地方去显然在上面那条单片机指令中要送的数源就是0FFH而要送达的地方目的地就是P1这个寄存器在数据传递类指令中均将目的地写在指令的后面而将源写在最后

  这条指令中送给P1是这个数本身换言之做完这条指令后我们能明确地知道P1中的值是0FFH但是并不是任何时候都能直接给出数本身的例如在我们前面给出的单片机延时程序例是这样写的

MAIN SETB P1.0 保

LCALL DELAY

CLR P1.0 常

LCALL DELAY

AJMP MAIN

以下子程序

DELAY MOV R7#250

D1 MOV R6#250

D2 DJNZ R6D2

DJNZ R7D1

RET 保

END 保保

表1

-----------------------------------------------------

 MAIN SETB P1.0 保

MOV 30H#255

LCALL DELAY

CLR P1.0 常

MOV 30H,#200

LCALL DELAY

AJMP MAIN

以下子程序

DELAY MOV R730H

D1 MOV R6#250

D2 DJNZ R6D2

DJNZ R7D1

RET 保

END 保保

表2

这样一来我看调用延时程序延时的时间都是相同的大致都是0.13S)如果我提出这样的要求灯亮后延时时间为0.13S灯灭灯灭后延时0.1秒灯亮如此循环这样的程序还能满足要求吗不能怎么办课们能把延时程序改成这样(见表2)调用则见表2中的主程也就是先把一个数送入30H在子程序中R7中的值并不固定而是根据30H单元中传过来的数确定这样就能满足要求

 

   从这里我们能得出结论在数据传递中要找到被传递的数很多时候这个数并不能直接给出需要变化这就引出了一个概念如何寻也作数我们把寻也作数所在单元的地址称之为寻址在这里我们直接使用数所在单元的地址找到了操作数所以称这种办法为直接寻址除了这种办法之外还有一种如果我们把数放在工作寄存器中从工作寄存器中寻找数据则称之为寄存器寻址例MOV AR0就是将R0工作寄存器中的数据送到累加器A中去提一个问题我们知道工作寄存器就是内存单元的一部份如果我们选择工作寄存器组0则R0就是RAM的00H单元那么这样一来MOV A00H和MOV AR0不就没什么区别了吗课什么要加以区别呢的确这教指令执行的结果是完全相同的都是将00H单元中的内容送到A中去但是执行的过程不一样执行第一条指令需要2个周期而第二条则只需要1个周期第一条指令变成最终的目标码要两个字节E5H 00H而第二条则只要一个字节E8h就能了

 

  这么斤斤计较不就差了一个周期吗如果是12M的晶体震荡器的话也就1个微秒时间了一个字节又能有多少

   不对如果这条指令只执行一次也许无所谓但一条指令如果执行上1000次就是1毫秒如果要执行1000000万次就是1S的误差这就很可观了单片机做的是实时控制的事所以必须如此斤斤计较字节数同样如此

再来提一个问题现在我们已知寻也作数能通过直接给的方式立即寻址和直接给出数所在单元地址的方式直接寻址这就够了吗

看这个问题要求从30H单元开始取20个数分别送入A累加器

   就我们目前掌握的办法而言要从30H单元取数就用MOV A30H那么下一个数呢是31H单元的怎么取呢还是只能用MOV A31H那么20个数不是得20条指令才能写完吗这里只有20个数如果要送200个或2000个数那岂不要写上200条或2000条命令?这未免太笨了吧为什么会出现这样的纯且为我们只会把地址写在指令中所以就没办法了如果我们不前地址直接写在指令中而前地址放在另外一个寄存器单元中根据这个寄存器单元中的数值决定该到哪个单元中取数据比如当前这个寄存器中的值是30H那么就到30H单元中去取如果是31H就到31H单元中去取就能解决这个问题了怎么个解决法呢既然是看的寄存器中的值那么我们就能通过一定的办法让这里面的值发生变化比如取完一个数后将这个寄存器单元中的值加1还是执行同一条指令可是取数的对象却不一样了不是吗通过例程来得吧

MOV R7#20

MOV R0#30H

LOOPMOV A@R0

INC R0

DJNZ R7,LOOP

    这个例程中大部份指令我们是能看懂的第一句是将立即数20送到R7中执行完后R7中的值应当是20第二句是将立即数30H送入R0工作寄存器中所以执行完后R0单元中的值是30H第三句这是看一下R0单元中是什么值把这个值作为地址取这个地址单元的内容送入A中此时执行这条指令的结果就相当于MOV A30H第四句没学过就前R0中的值加1因此执行完后R0中的值就是31H第五句学过将R7中的值减1看是否等于0不等于0则转到标号LOOP处继续执行因此执行完这句后将转去执行MOV A@R0这句话此时相当于执行了MOV A31H因为此时的R0中的值已是31H了如此直到R7中的值逐次相减等于0也就是循环20次为止就实现了我们的要求从30H单元开始将20个数据送入A中

这也且种寻找数据的办法由于数据是间接地被找到的所以统之为间址寻址注意在间址寻址中只能用R0或R1存放等寻找的数据

发表评论告诉好友收藏此文关闭窗口

文章评论

ձһhƬձƵ ձƵɫwww ձƵ:ɫ