打印
[DemoCode下载]

两位数码管动态显示汇编程序+电路图

[复制链接]
3700|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
598330983|  楼主 | 2016-5-23 19:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采用51单片机汇编语言驱动 下面是电路图:

ORG 0000H
      AJMP MAIN
   ORG 0030H

MAIN: MOV P0,#00H
   SETB P2.6
   SETB P2.7
   MOV R0,#00H
   MOV R1,#00H
   MOV R2,#888
   MOV R3,#0AH
   MOV R4,#0AH
   
   MOV DPTR,#TABLE
   
  L0: MOV A,R0
   MOVC A,@A+DPTR
   MOV P2,#040H
   MOV P0,A

   ACALL DELAY

   MOV A,R1
   MOVC A,@A+DPTR
   MOV P2,#80H
   MOV P0,A

   ACALL DELAY
   
   DJNZ R2,L0
   
   INC R0
   MOV R2,#888
   
   DJNZ R3,L0
   MOV R0,#00H
   MOV R3,#0AH
   INC R1
   DJNZ R4,L0
   AJMP MAIN

   DELAY:   ;误差 -0.868055555556us
    MOV R6,#0FBH
DL0:
    MOV R5,#04H
    DJNZ R5,$
    DJNZ R6,DL0
    RET

TABLE: DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H
    END
闲来无事学习一下,希望大家能给点儿建议,共同学习.


沙发
598330983|  楼主 | 2016-5-23 19:53 | 只看该作者
弱弱的问一句,还有多少新手学习51内核单片机的时候还用汇编的?虽然不要求会,可是能看懂就OK,还是很有用的。

使用特权

评论回复
板凳
598330983|  楼主 | 2016-5-23 19:54 | 只看该作者
有人问,在什么地方有用,那就是山寨别人的产品的时候,提出来的汇编代码修改。

使用特权

评论回复
地板
gaoyang9992006| | 2016-5-24 16:00 | 只看该作者
就大学刚学单片机的时候用了这个汇编,那时候是不学不行,要混学分的。后来再也没用过。

使用特权

评论回复
5
killer2014| | 2016-5-25 10:33 | 只看该作者
其实, 汇编和C,基本上没有啥差别了, C写的代码量大,但是编译器会自动优化, 基本上差不多。

使用特权

评论回复
6
orangebanana| | 2016-5-25 14:38 | 只看该作者
这个仿真的程序和实际的硬件电路有什么区别呢?

使用特权

评论回复
7
598330983|  楼主 | 2016-5-27 17:54 | 只看该作者
orangebanana 发表于 2016-5-25 14:38
这个仿真的程序和实际的硬件电路有什么区别呢?

区别就是实际上的电路不能直接驱动LED数码管,因为直接驱动亮度不够,需要来点三极管驱动。

使用特权

评论回复
8
稳稳の幸福| | 2016-5-29 18:05 | 只看该作者
电路图太简单了,实际上要来两个三极管驱动

使用特权

评论回复
9
734774645| | 2016-5-31 18:52 | 只看该作者
DJNZ RN,REL 是一条件转移指令,先将工作寄存器Rn中的数减“1”,判断结果是否为“0”,不为“0”程序就跳转到行标为REL的地方执行,否则,为“0”就不转移,继续执行下一条指令。

使用特权

评论回复
10
598330983|  楼主 | 2016-5-31 23:28 | 只看该作者
  算术运算类指令
    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。

使用特权

评论回复
11
598330983|  楼主 | 2016-5-31 23:29 | 只看该作者

    3.带借位的减法指令
      SUBB A,Rn
       SUBB A,direct
       SUBB A,@Ri
      SUBB A,#data
      设(每个H,(R2)=55H,CY=1,执行指令SUBB A,R2之后,A中的值为73H。
      说明:没有不带借位的减法指令,如果需要做不带位的减法指令(在做第一次相减时),只要将CY清零即可。

使用特权

评论回复
12
598330983|  楼主 | 2016-5-31 23:29 | 只看该作者
 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。

使用特权

评论回复
13
598330983|  楼主 | 2016-5-31 23:33 | 只看该作者
逻辑运算类指令:
    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化为二进制为01110011,
       逐位取反即为 10001100,也就是8CH。
      RL A是将(A)中的值的第7位送到第0位,第0位送1位,依次类推。

      例:A中的值为68H,执行RL A。68H化为二进制为01101000,按上图进行移动。01101000化为11010000,即D0H。
       RLC A,是将(A)中的值带上进位位(C)进行移位。

      例:A中的值为68H,C中的值为1,则执行RLC A
      1 01101000后,结果是0 11010001,也就是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化为二进制是10111,也就是0001,0111高4位是0001,低4位是0111,交换后是01110001,也就是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) 01110001
      (56H) 00100110
       结果 00100000 即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。例:
         10011000
        或 01100001
     结果 11111001
        而异或则是按位“异或”,相同为“0”,相异为“1”。例:
         10011000
      异或 01100001
      结果 11111001
       而所有的或指令,就是将与指令中的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……这段程序还能正确地执行吗?如果不能,应该怎么改?

使用特权

评论回复
14
598330983|  楼主 | 2016-5-31 23:34 | 只看该作者
  三、条件转移指令:
条件转移指令是指在满足一定条件时进行相对转移。
    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)调用及回过程:主程序调用了子程序,子程序执行完之后必须再回到主程序继续执行,不能“一去不回头”,那么回到什么地方呢?是回到调用子程序的下面一条指令继续执行(当然啦,要是还回到这条指令,不又要再调用子程序了吗?那可就没完没了了……)。

使用特权

评论回复
15
598330983|  楼主 | 2016-5-31 23:35 | 只看该作者
位及位操作指令
      通过前面那些流水灯的例子,我们已经习惯了“位”一位就是一盏灯的亮和灭,而我们学的指令却全都是用“字节”来介绍的:字节的移动、加法、减法、逻辑运算、移位等等。用字节来处理一些数学问题,比如说:控制冰箱的温度、电视的音量等等很直观,可以直接用数值来表在。可是如果用它来控制一些开关的打开和合上,灯的亮和灭,就有些不直接了,记得我们上次课上的流水灯的例子吗?我们知道送往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 0000H
        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
      这个的功能大家自行分析吧,然后对照上面的例程,编一个验证程序,看看你相得对吗?

使用特权

评论回复
16
598330983|  楼主 | 2016-5-31 23:35 | 只看该作者
 五、位条件转移指令
    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 0000H
        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,如此循环不已

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

249

主题

5397

帖子

22

粉丝