您的位置 首页 IOT

51单片机指令详解

数据传递类指令以累加器为目的操作数的指令MOVA,RnMOVA,directMOVA,@R…

数据传递类指令

    以累加器为意图操作数的指令

      MOV A,Rn

      MOV A,direct

      MOV A,@Ri

      MOV A,#data

  榜首条指令中,Rn代表的是R0-R7。第二条指令中,direct便是指的直接地址,而第三条指令中,便是咱们方才讲过的。第四条指令是将当即数data送到A中。

下面咱们经过一些比方加以阐明:

      MOV A,R1 ;将作业寄存器R1中的值送入A,R1中的值坚持不变。

      MOV A,30H ;将内存30H单元中的值送入A,30H单元中的值坚持不变。

      MOV A,@R1 ;先看R1中是什么值,把这个值作为地址,并将这个地址单元中的值送入A中。如碑文指令前R1中的值为20H,则是将20H单元中的值送     入A中。

      MOV A,#34H ;将当即数34H送入A中,碑文完本条指令后,A中的值是34H。

    以寄存器Rn为意图操作的指令

      MOV Rn,A

      MOV Rn,direct

      MOV Rn,#data

      这组指令功用是把源地址单元中的内容送入作业寄存器,源操作数不变。

    以直接地址为意图操作数的指令

      MOV direct,A 例: MOV 20H,A

      MOV direct,Rn MOV 20H,R1

      MOV direct1,direct2 MOV 20H,30H

      MOV direct,@Ri MOV 20H,@R1

      MOV direct,#data MOV 20H,#34H

    以直接地址为意图操作数的指令

      MOV @Ri,A 例:MOV @R0,A

      MOV @Ri,direct MOV @R1,20H

      MOV @Ri,#data MOV @R0,#34H

    十六位数的传递指令

      MOV DPTR,#data16

      8051是一种8位机,这是仅有的一条16位当即数传递指令,其功用是将一个16位的当即数送入DPTR中去。其间高8位送入DPH(083H),低8位送入DPL(082H)。例:MOV DPTR,#1234H,则碑文完了之后DPH中的值为12H,DPL中的值为34H。反之,假如咱们分别向DPH,DPL送数,则成果也相同。如有下面两条指令:MOV DPH,#35H,MOV DPL,#12H。则就适当于碑文了MOV DPTR,#3512H。

    累加器A与片外RAM之间的数据传递类指令

      MOVX A,@Ri

      MOVX @Ri,A

      MOVX #9; A,@DPTR

      MOVX @DPTR,A

阐明:

      1)在51中,与外部存储器RAM打交道的只能够是A累加器。一切需求送入外部RAM的数据必需求经过A送去,而一切要读入的外部RAM中的数据也必需经过A读入。在此咱们能够看出内外部RAM的差异了,内部RAM间能够直接进行数据的传递,而外部则不可,比方,要将外部RAM中某一单元(设为0100H单元的数据)送入另一个单元(设为0200H单元),也有必要先将0100H单元中的内容读入A,然后再送到0200H单元中去。

      2)要读或写外部的RAM,当然也有必要要知道RAM的地址,在后两条指令中,地址是被直接放在DPTR中的。而前两条指令,咱们Ri(即R0或R1)仅仅一个8位的寄存器,所以只供给低8位地址。咱们有时扩展的外部RAM的数量比较少,少于或等于256个,就只需求供给8位地址就够了。

      3)运用时应当首要酿制读或写的地址送入DPTR或Ri中,然后再用读写指令。

      例:将外部RAM中100H单元中的内容送入外部RAM中200H单元中。

        MOV DPTR,#0100H

        MOVX A,@DPTR

        MOV DPTR,#0200H

        MOVX @DPTR,A

    程序存储器向累加器A传送指令

        MOVC A,@A+DPTR

        本指令是将ROM中的数送入A中。本指令也被称为查表指令,常用此指令来查一个已做好在ROM中的表格(相似C言语中的指针)

    阐明:

        此条指令引出一个新的寻址办法:变址寻址。本指令是要在ROM的一个地址单元中找出数据,明显有必要知道这个单元的地址,这个单元的地址是这样确认的:在碑文本指令立脚点DPTR中有一个数,A中有一个数,碑文指令时,将A和DPTR中的数加起为,就成为要查找的单元的地址。

        1)查找到的成果被放在A中,因而,本条指令碑文前后,A中的值不用定相同。

           例:有一个数在R0中,要求用查表的办法确认它的平方值(此数的取值规模是0-5)

            MOV DPTR,#TABLE

            MOV A,R0

            MOVC A,@A+DPTR

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

        设R0中的值为2,送入A中,而DPTR中的值则为TABLE,则终究确认的ROM单元的地址便是TABLE+2,也便是到这个单元中去取数,取到的是4,明显它正是2的平方。其它数据也能够类推。

        标号的实在含义:从这个当地也能够看到另一个问题,咱们运用了标号来代替具体的单元地址。事实上,标号的实在含义便是地址数值。在这儿它代表了,0,1,4,9,16,25这几个数据在ROM中寄存的起点方位。而在曾经咱们学过的如LCALL DELAY指令中,DELAY 则代表了以DELAY为标号的那段程序在ROM中寄存的开始地址。事实上,CPU正是经过这个地址才找到这段程序的。

          能够经过以下的比方再来看一看标号的含义:

            MOV DPTR,#100H

            MOV A,R0

            MOVC A,@A+DPTR

            ORG 0100H.

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

            假如R0中的值为2,则终究地址为100H+2为102H,到102H单元中找到的是4。这个能够看懂了吧?

            那为什么不这样写程序,要用标号呢?不是添加疑问吗?

            答:假如这样写程序的话,在写程序时,咱们就有必要确认这张表格在ROM中的具体的方位,假如写完程序后,又想在这段程序前刺进一段程序,那么这张表格的方位就又要变了,要改ORG 100H这句话了,咱们是常常需求批改程序的,那多费事,所以就用标号来代替,只需一编译程序,方位就主动发生变化,咱们把这个费事事交给核算机指PC机去做了。

    仓库操作

      PUSH direct

      POP #9; direct

      榜首条指令称之为推入,便是将direct中的内容送入仓库中,第二条指令称之为弹出,便是将仓库中的内容送回到direct中。推入指令的碑文进程是,首要将SP中的值加1,然后把SP中的值当作地址,将direct中的值送进以SP中的值为地址的RAM单元中。例:

        MOV SP,#5FH

        MOV A,#100

        MOV B,#20

        PUSH ACC

        PUSH B

        则碑文榜首条PUSH ACC指令是这样的:将SP中的值加1,即变为60H,然后将A中的值送到60H单元中,因而碑文完本条指令后, 内存60H单元的值便是100,相同,碑文PUSH B时,是将SP+1,即变为61H,然后将B中的值送入到61H单元中,即碑文完本条指令后,61H单元中的值变为20。

        POP指令的碑文是这样的,首要将SP中的值作为地址,并将此地址中的数送到POP指令后边的那个direct中,然后SP减1。

       接上例:

        POP B

        POP ACC

        则碑文进程是:将SP中的值(现在是61H)作为地址,取61H单元中的数值(现在是20),送到B中,所以碑文完本条指令后B中的值是20,然后将SP减1,因而本条指令碑文完后,SP的值变为60H,然后碑文POP ACC,将SP中的值(60H)作为地址,从该地址中取数(现在是100),并送到ACC中,所以碑文完本条指令后,ACC中的值是100。

      这有什么含义呢?ACC中的值原本便是100,B中的值原本便是20,是的,在本例中,确实没有含义,但在实践作业中,则在PUSH B后往往要碑文其他指令,而且这些指令会把A中的值,B中的值改掉,所以在程序的完毕,假如咱们要把A和B中的值康复原值,那么这些指令就有含义了。

      还有一个问题,假如我不用仓库,比方说在PUSH ACC指令处用MOV 60H,A,在PUSH B处用指令MOV 61H,B,然后用MOV A,60H,MOV B,61H来代替两条POP指令,不是也相同吗?是的,从成果上看是相同的,但是从进程看是不相同的,PUSH和POP指令都是单字节,单周期指令,而MOV指令则是双字节,双周期指令。更何况,仓库的效果不止于此,所以一般的核算机上都设有仓库,而咱们在编写子程序,需求保存数据时,一般也不选用后边的办法,而是用仓库的办法来完结。

        例:写出以下程序的运转成果

          MOV 30H,#12

          MOV 31H,#23

          PUSH 30H

          PUSH 31H

          POP 30H

          POP 31H

          成果是30H中的值变为23,而31H中的值则变为12。也就两者进行了数据交流。从这个比方能够看出:运用仓库时,入栈的书写次序和出栈的书写次序有必要相反,才干确保数据被送回原位,不然就要出错了。

    算术运算类指令

    1.不带进位位的加法指令

      ADD A,#DATA ;例:ADD A,#10H

      ADD A,direct ;例:ADD A,10H

      ADD A,Rn ;例:ADD A,R7

      ADD A,@Ri ;例:ADD A,@R0

      用处:将A中的值与这今后边的值相加,终究成果否是回到A中。

     例:

       MOV A,#30H

      ADD A,#10H

      则碑文完本条指令后,A中的值为40H。

    2.带进位位的加法指令

      ADDC A,Rn

      ADDC A,direct

      ADDC A,@Ri

      ADDC A,#data

      用处:将A中的值和这今后边的值相加,而且加上进位位C中的值。

      阐明:咱们51单片机是一种8位机,所以只能做8位的数学运算,但8位运算的规模只需0-255,这在实践作业中是不行的,因而就要进行扩展,一般是将2个8位的数学运算合起来,成为一个16位的运算,这样,能够表达的数的规模就能够到达0-65535。怎样兼并呢?其实很简略,让咱们看一个10进制数的比方:

        66+78。

      这两个数相加,咱们底子不在意这的进程,但事实上咱们是这样做的:先做6+8(低位),然后再做6+7,这是高位。做了两次加法,仅仅咱们做的时分并没有故意分红两次加法来做算了,或者说咱们并没有意识到咱们做了两次加法。之所以要分红两次来做,是咱们这两个数超过了一位数所能表达的范置(0-9)。

      在做低位时产生了进位,咱们做的时分是在恰当的方位点一下,然后在做高位加法是将这一点加进去。那么核算机中做16位加法时相同如此,先做低8位的,假如两数相加产生了进位,也要“点一下”做个符号,这个符号便是进位位C,在PSW中。在进行高位加法是将这个C加进去。例:1067H+10A0H,先做67H+A0H=107H,而107H明显超过了0FFH,因而终究保存在A中的是7,而1则到了PSW中的CY位了,换言之,CY就适当所以100H。然后再做10H+10H+CY,成果是21H,所以终究的成果是2107H。

    3.带借位的减法指令

      SUBB A,Rn

      SUBB A,direct

      SUBB A,@Ri

      SUBB A,#data

      设(每个H,(R2)=55H,CY=1,碑文指令SUBB A,R2之后,A中的值为73H。

      阐明:没有不带借位的减法指令,假如需求做不带位的减法指令(在做榜首次相减时),只需将CY清零即可。

    4.乘法指令

      MUL AB

      此指令的功用是将A和B中的两个8位无符号数相乘,两数相乘成果一般比较大,因而终究成果用1个16位数来表达,其间高8位放在B中,低8位放在A中。在乘积大于FFFFFH(65535)时,0V置1(溢出),不然OV为0,而CY总是0。

      例:(A)=4EH,(B)=5DH,碑文指令

      MUL AB后,乘积是1C56H,所以在B中放的是1CH,而A中放的则是56H。

    5.除法指令

      DIV AB

      此指令的功用是将A中的8位无符号数除以B中的8位无符号数(A/B)。除法一般会呈现小数,但核算机中可无法直接表达小数,它用的是咱们小学生还没触摸到小数时用的商和余数的概念,如13/5,其商是2,余数是3。除了今后,商放在A中,余数放在B中。CY和OV都是0。假如在做除法前B中的值是00H,也便是除数为0,那么0V=1。

    6.加1指令

      INC A

      INC Rn

      INC direct

      INC @Ri

      INC DPTR

      用处很简略,便是将后边方针中的值加1。例:(A)=12H,(R0)=33H,(21H)=32H,(34H)=22H,DPTR=1234H。碑文下面的指令:

      INC A (A)=13H

      INC R2 (R0)=34H

      INC 21H (21H)=33H

      INC @R0 (34H)=23H

      INC DPTR 9; ( DPTR)=1235H

      成果如上所示。

      阐明:从成果上看INC A和ADD A,#1差不多,但INC A是单字节,单周期指令,而ADD #1则是双字节,双周期指令,而且INC A不会影响PSW位,如(A)=0FFH,INC A后(A)=00H,而CY仍然坚持不变。假如是ADD A ,#1,则(A)=00H,而CY必定是1。因而加1指令并不适合做加法,事实上它主要是用来做计数、地址添加等用处。别的,加法类指令都是以A为中心的其间一个数有必要放在A中,而运算成果也有必要放在A中,而加1类指令的目标则广泛得多,能够是寄存器、内存地址、间址寻址的地址等等。

    7.减1指令

      DEC A

      DEC RN

      DEC direct

      DEC @Ri

      与加1指令相似,就不多说了。

    逻辑运算类指令:

    1.对累加器A的逻辑操作:

      CLR A ;将A中的值清0,单周期单字节指令,与MOV A,#00H效果相同。

      CPL A ;将A中的值按位取反

      RL A ;将A中的值逻辑左移

      RLC A ;将A中的值加上进位位进行逻辑左移

      RR A ;将A中的值进行逻辑右移

      RRC A ;将A中的值加上进位位进行逻辑右移

      SWAP A ;将A中的值高、低4位交流。

      例:(A)=73H,则碑文CPL A,这样进行:

      73H化为二进制为00011,

      逐位取反即为 00,也便是8CH。

      RL A是将(A)中的值的第7位送到第0位,第0位送1位,顺次类推。

      例:A中的值为68H,碑文RL A。68H化为二进制为01101,按上图进行移动。01101化为11010,即D0H。

      RLC A,是将(A)中的值带上进位位(C)进行移位。

      例:A中的值为68H,C中的值为1,则碑文RLC A

      1 01101后,成果是0 11011,也便是C进位位的值变成了0,而(A)则变成了D1H。

      RR A和RRC A就不多谈了,请咱们参阅上面两个比方自行操练吧。

      SWAP A,是将A中的值的高、低4位进行交流。

      例:(A)=39H,则碑文SWAP A之后,A中的值便是93H。怎样正好是这么前后交流呢?咱们这是一个16进制数,每1个16进位数字代表4个二进位。留意,假如是这样的:(A)=39,后边没H,碑文SWAP A之后,可不是(A)=93。要将它化成二进制再算:39化为二进制是10,也便是1,0高4位是1,低4位是0,交流后是01,也便是71H,即113。

    2.逻辑与指令

      ANL A,Rn ;A与Rn中的值按位与,成果送入A中

      ANL A,direct ;A与direct中的值按位与,成果送入A中

      ANL A,@Ri ;A与间址寻址单元@Ri中的值按位与,成果送入A中

      ANL A,#data ;A与当即数data按位与,成果送入A中

      ANL direct,A ;direct中值与A中的值按位与,成果送入direct中

      ANL direct,#data ;direct中的值与当即数data按位与,成果送入direct中。

      这几条指令的关键是知道什么是逻辑与。这儿的逻辑与是指按位与

      例:71H和56H相与则将两数写成二进制方法:

      (71H) 01

      (56H) 00100110

      成果 00100 即20H,从上面的式子能够看出,两个参加运算的值只需其间有一个位上是0,则这位的成果便是0,两个同是1,成果才是1。

      了解了逻辑与的运算规矩,成果天然就出来了。看每条指令后边的注释

      下面再举一些比方来看。

        MOV A,#45H ;(A)=45H

        MOV R1,#25H ;(R1)=25H

        MOV 25H,#79H ;(25H)=79H

        ANL A,@R1 ;45H与79H按位与,成果送入A中为 41H (A)=41H

        ANL 25H,#15H ;25H中的值(79H)与15H相与成果为(25H)=11H)

        ANL 25H,A ;25H中的值(11H)与A中的值(41H)相与,成果为(25H)=11H

      在知道了逻辑与指令的功用后,逻辑或和逻辑异或的功用就很简略了。逻辑或是按位“或”,即有“1”为1,全“0”为0。例:

        10011

       或 01101

     成果 11001

        而异或则是按位“异或”,相同为“0”,相异为“1”。例:

        10011

      异或 01101

      成果 11001

      而一切的或指令,便是将与指令中的ANL 换成ORL,而异或指令则是将ANL 换成XRL。

    

    3..逻辑或指令:

      ORL A,Rn ;A和Rn中的值按位或,成果送入A中

      ORL A,direct ;A和与间址寻址单元@Ri中的值按位或,成果送入A中

      ORL A,#data ;A和立direct中的值按位或,成果送入A中

      ORL A,@Ri ;A和即数data按位或,成果送入A中

      ORL direct,A ;direct中值和A中的值按位或,成果送入direct中

      ORL direct,#data ;direct中的值和当即数data按位或,成果送入direct中。

    4.逻辑异或指令:

      XRL A,Rn ;A和Rn中的值按位异或,成果送入A中

      XRL A,direct ;A和direct中的值按位异或,成果送入A中

      XRL A,@Ri ;A和间址寻址单元@Ri中的值按位异或,成果送入A中

      XRL A,#data ;A和当即数data按位异或,成果送入A中

      XRL direct,A ;direct中值和A中的值按位异或,成果送入direct中

      XRL direct,#data ;direct中的值和当即数data按位异或,成果送入direct中。

    操控搬运类指令

  一、无条件搬运类指令

    1.短搬运类指令

      AJMP addr11

    2.长搬运类指令

      LJMP addr16

    3.相对搬运指令

      SJMP rel

      上面的三条指令,假如要仔细剖析的话,差异较大,但初学时,可不理睬这么多,通通了解成:JMP标号,也便是跳转到一个标号处。事实上,LJMP标号,在前面的例程中咱们已触摸过,而且也知道怎样来运用了。而AJMP和SJMP也是相同。那么他们的差异安在呢?在于跳转的规模不相同。比如跳远,LJMP一下就能跳64K这么远(当然近了更没关系了)。而AJMP最多只能跳2K间隔,而SJMP则最多只能跳256这么远。原则上,一切用SJMP或AJMP的当地都能够用LJMP来代替。因而在初学时,需求跳转时能够全用LJMP,除了一个场合。什么场合呢?先了解一下AJMP,AJMP是一条双字节指令,也就说这条指令自身占用存储器(ROM)的两个单元。而LJMP则是三字节指令,即这条指令占用存储器(ROM)的三个单元。下面是第四条跳转指令。

    二、直接搬运指令

      JMP @A+DPTR

      这条指令的用处也是跳转,转到什么当地去呢?这可不能由标号简略地决议了。让咱们从一个实践的比方下手吧。

      MOV DPTR,#TAB ;将TAB所代表的地址送入DPTR

      MOV A,R0 ;从R0中取数(详见下面阐明)

      MOV B,#2

      MUL A,B ;A中的值乘2(详见下面的阐明)

      JMP A,@A+DPTR ;跳转

      TAB: AJMP S1 ;跳转表格

      AJMP S2

      AJMP S3

      运用布景介绍:在单片机开发中,常常要用到键盘,见上面的9个按键的键盘。咱们的要求是:当按下功用键A………..G时去完结不同的功用。这用程序规划的言语来表达的话,便是:按下不同的键去碑文不同的程序段,以完结不同的功用。怎样样来完结呢?

      前面的程序读入的是按键的值,如按下A键后获得的键值是0,按下B键后获得的值是1等等,然后依据不同的值进行跳转,如键值为0就转到S1碑文,为1就转到S2碑文。。。。怎样来完结这一功用呢?

      先从程序的下面看起,是若干个AJMP查办,这若干个AJMP查办终究在存储器中是这样寄存的,也便是每个AJMP查办都占用了两个存储器的空间,而且是接连寄存的。而AJMP S1寄存的地址是TAB,究竟TAB等于多少,咱们不需求知道,把它留给汇编程序来算好了。

      下面咱们来看这段程序的碑文进程:榜首句MOV DPTR,#TAB碑文完了之后,DPTR中的值便是TAB,第二句是MOV A,R0,咱们假定R0是由按键处理程序获得的键值,比方按下A键,R0中的值是0,按下B键,R0中的值是1,以此类推,现在咱们假定按下的是B键,则碑文完第二条指令后,A中的值便是1。而且按咱们的剖析,按下B后应当碑文S2这段程序,让咱们来看一看是否是这样呢?第三条、第四条指令是将A中的值乘2,即碑文完第4条指令后A中的值是2。下面就碑文JMP @A+DPTR了,现在DPTR中的值是TAB,而A+DPTR后便是TAB+2,因而,碑文此句程序后,将会跳到TAB+2这个地址持续碑文。看一看在TAB+2这个地址晒干放的是什么?便是AJMP S2这条指令。因而,立刻又碑文AJMP S2指令,程序将跳到S2处往下碑文,这与咱们的要求相符合。

      请咱们自行剖析按下键“A”、“C”、“D”……之后的状况。

      这样咱们用JMP @A+DPTR就完结了按下一键跳到相应的程序段去碑文的这样一个要求。再问咱们一个问题,为什么获得键值后要乘2?假如例程下面的一切指令换成LJMP,即:

          LJMP S1,LJMP S2……这段程序还能正确地碑文吗?假如不能,应该怎样改?

    三、条件搬运指令:

条件搬运指令是指在分量必定条件时进行相对搬运。

    1..判A内容是否为0搬运指令

      JZ rel

      JNZ rel

      榜首指令的功用是:假如(A)=0,则搬运,不然次序碑文(碑文本指令的下一条指令)。搬运到什么当地去呢?假如依照传统的办法,就要算偏移量,很费事,好在现在咱们能够借助于机器汇编了。因而这第指令咱们能够这样了解:JZ 标号。即搬运到标号处。下面举一例阐明:

      MOV A,R0

      JZ L1

      MOV R1,#00H

      AJMP L2

      L1: MOV R1,#0FFH

      L2: SJMP L2

      END

      在碑文上面这段程序前假如R0中的值是0的话,就搬运到L1碑文,因而终究的碑文成果是R1中的值为0FFH。而假如R0中的值不等于0,则次序碑文,也便是碑文 MOV R1,#00H指令。终究的碑文成果是R1中的值等于0。

      榜首条指令的功用清楚了,第二条当然就好了解了,假如A中的值不等于0,就搬运。把上面的那个比方中的JZ改成JNZ试试吧,看看程序碑文的成果是什么?

    2.比较搬运指令

      CJNE A,#data,rel

      CJNE A,direct,rel

      CJNE Rn,#data,rel

      CJNE @Ri,#data,rel

      榜首条指令的功用是将A中的值和当即数data比较,假如两者持平,就次序碑文(碑文本指令的下一条指令),假如不持平,就搬运,相同地,咱们能够将rel了解成标号,即:CJNE A,#data,标号。这样运用这条指令,咱们就能够判别两数是否持平,这在许多场合对错常有用的。但有时还想得知两数比较之后哪个大,哪个小,本条指令也具有这样的功用,假如两数不持平,则CPU还会反映出哪个数大,哪个数小,这是用CY(进位位)来完结的。假如前面的数(A中的)大,则CY=0,不然CY=1,因而在程序搬运后再次运用CY就可判别出A中的数比data大仍是小了。

      例:

        MOV A,R0

        CJNE A,#10H,L1

        MOV R1,#0FFH

        AJMP L3

        L1: JC L2

        MOV R1,#0AAH

        AJMP L3

        L2: MOV R1,#0FFH

        L3: SJMP L3

        上面的程序中有一条指令咱们还没学过,即JC,这条指令的原型是JC rel,效果和上面的JZ相似,但是它是判CY是0,仍是1进行搬运,假如CY=1,则搬运到JC后边的标号处碑文,假如CY=0则次序碑文(碑文它的下面一条指令)。

        剖析一下上面的程序,假如(A)=10H,则次序碑文,即R1=0。假如(A)不等于10H,则转到L1处持续碑文,在L1处,再次进行判别,假如(A)>10H,则CY=1,将次序碑文,即碑文MOV R1,#0AAH指令,而假如(A)<10H,则将搬运到L2处指行,即碑文MOV R1,#0FFH指令。因而终究成果是:本程序碑文前,假如(R0)=10H,则(R1)=00H,假如(R0)>10H,则(R1)=0AAH,假如(R0)<10H,则(R1)=0FFH。

        弄懂了这条指令,其它的几条就相似了,第二条是把A傍边的值和直接地址中的值比较,第三条则是将直接地址中的值和当即数比较,第四条是将间址寻址得到的数和当即数比较,这儿就不详谈了,下面给出几个相应的比方。

        CJNE A,10H ;把A中的值和10H中的值比较(留意和上题的差异)

        CJNE 10H,#35H ;把10H中的值和35H中的值比较

        CJNE @R0,#35H ;把R0中的值作为地址,从此地址中取数并和35H比较

    3.循环搬运指令

      DJNZ Rn,rel

      DJNZ direct,rel

      榜首条指令在前面的比方中有具体的剖析,这儿就不多谈了。第二条指令,仅仅将Rn改成直接地址,其它相同,也不多说了,给一个比方。

      DJNZ 10H,LOOP

  调用与回来指令

      (1)主程序与子程序 在前面的灯的试验中,咱们已用到过了子程序,仅仅咱们并没有明确地介绍。子程序是干什么用的,为什么要用子程序技能呢?举个比方,咱们数据教师安置了10道算术题,经过调查,每一道题中都包括一个(3*5+2)*3的运算,咱们能够有两种挑选,榜首种,每做一道题,都把这个算式算一遍,第二种挑选,咱们能够先把这个成果算出来,也便是51,放在一边,然后要用到这个算式时就将51代进去。这两种办法哪种更好呢?不用多言。规划程序时也是这样,有时一个功用会在程序的不同当地重复运用,咱们就能够把这个功用做成一段程序,每次需求用到这个功用时就“调用”一下。

      (2)调用及回进程:主程序调用了子程序,子程序碑文完之后有必要再回到主程序持续碑文,不能“一去不回头”,那么回到什么当地呢?是回到调用子程序的下面一条指令持续碑文(当然啦,要是还回到这条指令,不又要再调用子程序了吗?那可就没完没了了……)。

   位及位操作指令

      经过前面那些流水灯的比方,咱们现已习惯了“位”一位便是一盏灯的亮和灭,而咱们学的指令却全都是用“字节”来介绍的:字节的移动、加法、减法、逻辑运算、移位等等。用字节来处理一些数学问题,比方说:操控冰箱的温度、电视的音量等等很直观,能够直接用数值来表在。但是假如用它来操控一些开关的翻开和合上,灯的亮和灭,就有些不直接了,记住咱们前次课上的流水灯的比方吗?咱们知道送往P1口的数值后并不能立刻知道哪个灯亮和来灭,而是要化成二进制才知道。工业中有许多场合需求处理这类开关输出,继电器吸合,用字节来处理就显现有些费事,所以在8031单片机中特意引进一个位处理机制。

    一、.位寻址区

      在8031中,有一部份RAM和一部份SFR是具有位寻址功用的,也便是说这些RAM的每一个位都有自已的地址,能够直接用这个地址来对此进行操作。

字节地址

位地址

2FH

7FH

 

 

 

 

 

 

78H

2EH

77H

 

 

 

 

 

 

70

2DH

6FH

 

 

 

 

 

 

68H

2CH

67H

 

 

 

 

 

 

60H

2BH

5FH

 

 

 

 

 

 

58H

2AH

57H

 

 

 

 

 

 

50H

29H

4FH

 

 

 

 

 

 

48H

28H

47H

 

 

 

 

 

 

40H

27H

3FH

 

 

 

 

 

 

38H

26H

37H

 

 

 

 

 

 

30H

25H

2FH

 

 

 

 

 

 

28H

24H

27H

 

 

 

 

 

 

20H

23H

1FH

 

 

 

 

 

 

18H

22H

17H

 

 

 

 

 

 

10H

21H

0FH

 

 

 

 

 

 

08H

20H

07H

06H

05H

04H

03H

02H

01H

00H

图1

        内部RAM的20H-2FH这16个字节,便是8031的位寻址区。看图1。可见这儿面的每一个RAM中的每个位咱们都或许直接用位地址来找到它们,而不用用字节地址,然后再用逻辑指令的方法。

    二、能够位寻址的特别功用寄存器

      8031中有一些SFR是能够进行位寻址的,这些SFR的特点是其字节地址均可被8整除,如A累加器,B寄存器、PSW、IP(中止优先级操控寄存器)、IE(中止答应操控寄存器)、SCON(串行口操控寄存器)、TCON(定时器/计数器操控寄存器)、P0-P3(I/O端口锁存器)。以上的一些SFR咱们还不熟,等咱们解说相关内容时再作具体解说。

    三、位操作指令

      MCS-51单片机的硬件结构中,有一个位处理器(又称布尔处理器),它有一套位变量处理的指令集。在进行位处理时,CY(便是咱们前面讲的进位位)称“位累加器”。有自已的位RAM,也便是咱们刚讲的内部RAM的20H-2FH这16个字节单元即128个位单元,还有自已的位I/O空间(即P0.0…..P0.7,P1.0…….P1.7,P2.0……..P2.7,P3.0……..P3.7)。当然在物理实体上它们与本来的以字节寻址用的RAM,及端口是完全相同的,或者说这些RAM及端口都能够有两种用法。

        1..位传送指令

          MOV C,BIT

          MOV BIT,C

          这组指令的功用是完结位累加器(CY)和其它位地址之间的数据传递。

        例:MOV P1.0,CY ;将CY中的状况送到P1.0引脚上去(假如是做算术运算,咱们就能够经过调查知道现在CY是多少啦)。

          MOV P1.0,CY ;将P1.0的状况送给CY。

      2..位批改指令

          位清0指令

          CLR C ;使CY=0

          CLR bit ;使指令的位地址等于0。例:CLR P1.0 ;即便P1.0变为0

          方位1指令

            SETB C ;使CY=1

            SETB bit ;使指定的位地址等于1。例:SETB P1.0 ;使P.0变为1

          位取反指令

            CPL C ;使CY等于本来的相反的值,由1变为0,由0变为1。

            CPL bit ;使指定的位的值等于本来相反的值,由0变为1,由1变为0。

            例:CPL P1.0

            以咱们做过的试验为例,假如本来灯是亮的,则碑文本指令后灯灭,反之本来灯是灭的,碑文本指令后灯亮。

    四、位逻辑运算指令

    1..位与指令

      ANL C,bit ;CY与指定的位地址的值相与,成果送回CY

      ANL C,/bit ;先将指定的位地址中的值取出后取反,再和CY相与,成果送回CY,但留意,指定的位地址中的值自身并不发生变化。

      例:ANL C,/P1.0

      设碑文本指令前,CY=1,P1.0等于1(灯灭),则碑文完本指令后CY=0,而P1.0也是等于1。

      可用下列程序验证:

        ORG 0H

        AJMP START

        ORG 30H

        START: MOV SP,#5FH

        MOV P1,#0FFH

        SETB C

        ANL C,/P1.0

        MOV P1.1,C ;将做完的成果送P1.1,成果应当是P1.1上的灯亮,而P1.0上的灯仍是不亮。

    2..位或指令

      ORL C,bit

      ORL C,/bit

      这个的功用咱们自行剖析吧,然后对照上面的例程,编一个验证程序,看看你相得对吗?

    五、位条件搬运指令

    1..判CY搬运指令

      JC rel

      JNC rel

      榜首条指令的功用是假如CY等于1就搬运,假如不等于1就次序碑文。那么搬运到什么当地去呢?咱们能够这样了解:JC 标号,假如等于1就转到标号处碑文。这条指令咱们在上节课中已讲到,不再重复。

      第二条指令则和榜首条指令相反,即假如CY=0就搬运,不等于0就次序碑文,当然,咱们也相同了解: JNC 标号

    2..判位变量搬运指令

      JB bit,rel

      JNB bit,rel

      榜首条指令是假如指定的bit位中的值是1,则搬运,不然次序碑文。相同,咱们能够这样了解这条指令:JB bit,标号

      第二条指令请咱们先自行剖析

      下面咱们举个比方阐明:

        ORG 0H

        LJMP START

        ORG 30H

        START:MOV SP,#5FH

        MOV P1,#0FFH

        MOV P3,#0FFH

        L1: JNB P3.2,L2 ;P3.2上接有一只按键,它按下时,P3.2=0

        JNB P3.3,L3 ;P3.3上接有一只按键,它按下时,P3.3=0

        LJM P L1

        L2: MOV P1,#00H

        LJMP L1

        L3: MOV P1,#0FFH

        LJMP L1

        END

        把上面的比方写入片子,看看有什么现象………

        按下接在P3.2上的按键,P1口的灯全亮了,松开或再按,灯并不平息,然后按下接在P3.3上的按键,灯就全灭了。这像什么?这不便是工业现场常常用到的“发动”、“中止”的功用吗?

        怎样做到的呢?一开始,将0FFH送入P3口,这样,P3的一切引线都处于高电平,然后碑文L1,假如P3.2是高电平(键没有按下),则次序碑文JNB P3.3,L3查办,相同,假如P3.3是高电平(键没有按下),则次序碑文LJMP L1查办。这样就不停地检测P3.2、P3.3,假如有一次P3.2上的按键按下去了,则搬运到L2,碑文MOV P1,#00H,使灯全亮,然后又转去L1,再次循环,直到检测到P3.3为0,则转L3,碑文MOV P1,#0FFH,例灯全灭,再转去L1,如此循环不已。

        改程序还能够用JB来写 略

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/iot/265612.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部