下面将按指令的5大功能分类来介绍各条指令。在学习指令系统时,应注意:
(1)指令的格式、功能。
(2)操作码的含义,操作数的表示方法。
(3)寻址方式,源、目的操作数的范围。
(4)对标志位的影响。
(5)指令的适用范围。
(6)指令的长度和执行时间。
3.1.5.1 数据传送类指令(5种/共29条)
数据传送包括单片机内部RAM与特殊功能寄存器(简称SFR)、外部RAM以及与ROM之间的数据传送。这类指令见表3-2,它共有29条。
表3-2 数据传送类指令
续表
分类:内部存储器间传送、外部数据存储器与A间传送、程序存储器向A传送、数据交换和堆栈操作5种。
格式:操作码<dest>,<src>;
功能:(目的地址)←或↔(源地址),源操作数传到目的操作数或者内容互换。这种指令只是改变数据存放位置,不改变数据值,且单方向传送时源地址单元的内容不变。
寻址范围:累加器A、片内RAM、SFR、片外RAM。
对PSW的标志位的影响:不影响标志位Cy、AC和OV,但若目的操作数存入A中,将会影响奇偶标志位P。
图3-7 内部存储器间传送关系
1.内部存储器间传送(共16条)
内部存储器间传送指令用于内部RAM、SFR之间的数据传送,共16条,内部数据传送指令的传送关系如图3-7所示。
格式:MOV<dest>,<src>
其中,<dest>表示目的操作数,<src>表示源操作数。
功能:是将源字节内容传送到由目的字节所指定的单元中,且不改变源字节的内容(相当于“复制”,而不是“搬家”)。
范围:源、目的操作数均在片内RAM、SFR中。
分类:按目的操作数不同,还可进一步分为下面5小类:
(1)以累加器A为目的操作数的指令(共4条)。
MOV A,<src>
其中,<src>包括Rn、@Ri、direct、#data。它们具体分别为:
功能是把源操作数内容送累加器A,源操作数有寄存器寻址、直接寻址、间接寻址和立即数寻址等方式。
(2)以Rn为目的操作数的指令(共3条)。
MOV Rn,<src>
其中,<src>包括A、direct、#data。它们具体分别为:
功能是把源操作数送入当前寄存器区的R0~R7中的某一寄存器。
(3)以直接地址direct为目的操作数的指令(共5条)。
MOV direct,<src>
其中,<src>包括A、Rn、@Ri、direct、#data。它们具体分别为:
功能是把源操作数送入直接地址指定的存储单元。direct、direct1、direct2指的是内部RAM或SFR地址。
(4)以间接寄存器@Ri为目的操作数的指令(共3条)。
MOV@Ri,<src>
其中,<src>包括A、direct、#data。它们具体分别为:
功能是把源操作数内容送入R0或R1指定的存储单元中。
(5)16位数传送指令(共1条)。
功能是把16位立即数送入DPTR,用来设置数据存储器的地址指针。
注意:2)、3)、4)、5)均不影响标志位,只有1)影响PSW中的P标志位,不影响其他标志位。
【例3-2】 试说明下列每条指令的功能。
【例3-3】 设内部RAM(40 H)=50H,(50 H)=20 H,(15 H)=00 H,(P1)=0DBH,分析以下程序执行后各单元及寄存器、P2口的内容。
执行上述指令后的结果为:(R0)=40H,(R1)=(A)=50 H,(B)=20 H,(50 H)=(P1)=(P3)=0DB H,(15H)=25H。
【例3-4】 发光二极管及8段显示管的显示。如图3-8所示,P1口上接了8个发光二极管,实际上它们对应于共阳极8段显示管的8个段。
图3-8 发光二极管及8段显示管的显示
指令MOV P1,#0FEH;(P1)←11111110B,只有P1.0引脚上接的发光二极管得到正向偏置电压,其他7个引脚上接的发光二极管无偏置电压。因此,此指令执行后,可使P1.0上的发光二极管点亮,而其他发光二极管不亮。
指令MOV P1,#00 H;(P1)←00000000B,P1口上8个二极管均被点亮,因此,8段显示管就显示“8”的形状。同理,指令MOV P1,#0F8H执行后会显示“7”。指令MOV P1,#88H执行后会显示“A”。
2.外部RAM与A间传送(共4条)
CPU与外部数据存储器之间进行数据传送时,必须使用外部传送指令,只能通过累加器A,采用R0、R1和DPTR这3个寄存器间接寻址方式完成。指令特征是MOVX,MOV的后面“X”表示单片机访问的是片外RAM存储器或I/O接口。
指令格式:MOVX A,<src>
MOVX<dest>,A
其中,<src>、<dest>包括@DPTR、@Ri(R0,R1)。
对PSW标志位的影响:MOVX A,<src>指令只影响PSW中的P标志位,不影响其他标志位;MOVX<dest>,A指令不影响标志位。
分类:这类指令共有下面4条指令。
说明:当采用16位的DPTR间接寻址时,可寻址整个64KB片外RAM空间,高8位地址(DPH)由P2口输出,低8位地址(DPL)由P0口输出。而采用Ri(i=0,1)进行间接寻址时,隐含着外部RAM地址的高8位,而该高8位地址是由P2口输出,低8位地址由Ri寄存器的内容提供并经P0口锁存后输出,即真正外部RAM的16位地址为(P2)(Ri),此时只可寻址片外256个单元的RAM。
注意:在执行前两条读指令时,读信号(P3.7)有效(低电平);而当执行后两条写指令时,写信号(P3.6)有效(低电平)。
【例3-5】 试分析指令的执行结果。
即将数据30H写入到外部RAM9010H地址中。
3.程序存储器ROM向A传送(即查表指令)(共2条)
MCS-51单片机对程序存储器的访问之一是读程序中表格数据或常数,专用于这一操作的指令有两条,称为查表指令。两条指令是在MOV的后面加C,“C”是CODE的第一个字母,即代码的意思。执行上述两条指令时,单片机的引 脚信号(程序存储器读)有效。
指令格式:MOVC A,@A+DPTP;(A)←((A)+(DPTR))
MOVC A,@A+PC ;(PC)←(PC)+1,(A)←((A)+(PC))
由于ROM只读不写,因此传送为单向,从ROM中读出数据到A中。两条查表指令均采用基址加变址间接寻址方式。
两条指令的功能完全相同,但使用中存在着差异:
(1)偏移量的计算方法不同。采用DPTR作为基地址寄存器,查表地址为(A)+(DPTR)。而采用PC作为基地址寄存器,查表地址为(A)+(PC)+1。因此,采用DPTR作为基地址寄存器,A为欲查数值距离表首地址的值;采用PC作为基地址寄存器,A的值必须预先设置为:
A的值=表首地址-当前指令的PC值-1。
(2)查表的位置要求不同。采用DPTR作为基地址寄存器,查表结果只与DPTR及A的内容有关,与该指令存放的地址及常数表格存放的地址无关。因此,表格的大小和位置可以在64K ROM中任意安排,一个表格可以为各个程序块公用,使用方便,故称为远程查表。
采用PC作为基地址寄存器,不改变SFR及PC的状态,根据A的内容就可以取出表格中的常数。但表格只能存放在该条查表指令后面的256个单元之内,且注意如果MOVC指令与表格之间有n个字节距离时,则需先在A上加上相应的立即数n。因此,表格的大小受到限制,而且表格只能被一段程序所利用,故称为近程查表。
【例3-6】 试分析指令的执行结果。
即将ROM的9020H地址单元的内容(由于地址9020H在0000H开始的4KB/8KB空间之外,故一定是外部ROM而非内部ROM)读出后送到外部RAM的9010 H地址中。
【例3-7】 试分析指令的执行结果。
即查表后将ROM表格中表项序号为02H处的常数32H取出送入累加器A中。
4.数据交换指令(共5条)
这组指令的功能是将累加器A的内容与源操作数的内容相互交换,或A的高低4位互换,或A的低4位与源操作数的低4位互换。源操作数有寄存器寻址、直接寻址和寄存器间接寻址等方式。
(1)字节交换指令(共3条)。
指令格式:XCH A,<src>;(A)←→<src>
其中,<src>包括Rn、@Ri、direct。它们分别为:
(2)半字节数据交换指令(共2条)。
【例3-8】 设(R0)=30 H,(30 H)=4AH,(A)=28H,分别执行下列指令:
结果为(A)=84 H,(30)=2AH,(R0)=30 H。
5.堆栈操作指令(2条)
内部RAM中设定一个后进先出(Last In First Out,简称LIFO)的区域,称为堆栈。在SFR中有一个堆栈指针SP,指示堆栈的栈顶位置。堆栈操作有进栈和出栈两种。因此,在指令系统中相应有两条堆栈操作指令。
功能:实现RAM单元数据送入栈顶或由栈顶取出数据送至RAM单元。第1条进栈指令(或称压栈指令)是先将栈指针SP加1,再把直接地址direct(用00 H~FFH形式表示的)中的内容送到SP指示的内部RAM单元中。第2条出栈指令(或称弹栈指令)是先将SP指示的栈顶单元的内容送入直接寻址direct字节中,再把SP减1。
特点:堆栈操作指令是一种特殊的数据传送指令,它根据SP中的栈顶地址进行数据操作。堆栈操作指令的实质是以栈指针SP为间址寄存器的间址寻址方式。堆栈区应避开使用的工作寄存器区R0~R7、字节地址20H~2FH的位寻址区(位地址00~7FH),以及其他需要使用的数据区,系统复位后SP的初值为07H。为了避免重叠,一般初始化时要重新设置SP。
适用场合:用于执行中断、子程序调用、参数传递等程序的断点保护和现场保护。
注意:堆栈操作指令是直接寻址指令,直接地址不能是寄存器名,因此应注意指令的书写格式。
【例3-9】 试分析指令的执行结果。
执行结果:(0AH)=34H,(0BH)=12 H,(SP)=0BH。
执行过程示意图如图3-9所示。
图3-9 进栈示意图
图3-10 出栈操作过程
【例3-10】 试分析指令的执行结果。
①MOV SP,#32H ;(SP)=32H
②MOV 31H,#23H;(31H)=23H
执行结果:(DPTR)=(DPH)(DPL)=0123 H,(SP)=30 H。
执行过程示意图如图3-10所示。
【例3-11】 若在外部程序存储器中2000H单元开始依次存放0~9的平方值,数据指针(DPTR)=3A00 H,用查表指令取得2003 H单元的数据后,要求保持DPTR中的内容不变。
完成上述功能的程序为:
执行结果:(A)=09 H,(DPTR)=3A00H。注意:由于堆栈采用后进先出的管理原则,为了保证现场数据不变,保护现场的顺序应与恢复现场的顺序相反。
3.1.5.2 算术运算类指令(5种/共24条)
算术运算类指令就是用于实现加法、减法、乘法和除法等算术运算的指令。这类指令见表3-3。它共有24条,又可分为5种情况。
表3-3 算术运算类指令
续表
分类:加法指令、带进位/借位的加法/减法指令、加1/减1指令、乘法/除法指令、十进制调整指令。
格式:操作码<dest>,<src>;
操作码<dest>
功能:双操作数指令通过两个操作数进行加、减、乘和除法算术运算,目的操作数<dest>一定是累加器A,源操作数<src>为Rn、@Ri(片内RAM)和#data;单操作数指令只有一个操作数<dest>,它来源于A、Rn、@Ri(片内RAM)、#data和DPTR,用于实现自身数据的加1、减1运算。
此外,MCS-51算术运算指令一般是针对8位二进制无符号数的,如要进行带符号或多字节二进制数运算,需编写具体的运算程序,通过执行程序实现。
寻址范围:A、Rn、DPTR、@Ri(仅针对片内RAM)和#data。
对PSW标志位的影响:一般对进位Cy、辅助进位AC、溢出OV这3种标志有影响。但增1和减1指令不影响这些标志。若目的操作数存入A中,将会影响奇偶标志位P。
1.加法指令(共4条)
MCS-51单片机中设置了两个8位数据的加法指令。加法指令可用于无符号或带符号的两个8位数据加法运算。
指令格式:ADD A,<src>;(A)←(A)+<src>
其中,<src>包括Rn、@Ri、direct、#data。它们分别为:
功能:8位加法指令的一个加数总是来自累加器A,而另一个加数可由寄存器寻址、直接寻址、寄存器间接寻址和立即数寻址等不同的寻址方式得到。加的结果总是放在累加器A中。
对PSW标志位的影响:ADD对PSW中的所有标志位均产生影响。
【例3-12】 (A)=53H,(R0)=FCH,执行指令ADD A,R0的运算式为:
结果:(A)=4FH,Cy=1,AC=0,OV=0,P=1(A中1的位数为奇数)。注意:(OV)=(Cy)⊕(C7.6)即Cy内容和第6位向第7位的进位C7.6(或称为Cy-1)做“异或”运算。由于位6和位7同时有进位,所以标志位OV=0。
【例3-13】 两个8位无符号数相加。将片内RAM的50H、51H地址中的内容相加,结果送片内RAM的52H地址和进位Cy中。试通过具体指令分析程序所实现功能。参考程序为:
2.带进位/借位的加法/减法指令(共8条)
MCS-51单片机中设置了带进位或借位两个8位数据的加法或减法指令。它们用于实现多字节数相加、减法运算,通过进位/借位标志Cy来保证低位字节的进位/借位加/减到高位字节上。带进位加法/减法指令可用于无符号或带符号的两个数据加法/减法运算。
指令格式:
(1)ADDC A,<src>;带借位的加法指令,(A)←(A)+<src>+(Cy)
其中,进位标志位Cy也与参加法运算,实际上是3个数相加,<src>包括Rn、@Ri、direct、#data。它们分别为:
(2)SUBB A,<src>;带借位的减法指令,(A)←(A)-<src>-(Cy)
其中,进位标志位Cy也与参减法运算,实际上是3个数相减,<src>包括Rn、@Ri、direct、#data。它们分别为:
注意:MCS-51指令系统中无不带借位的减法指令,欲实现不带借位的减法计算,可以通过两条指令组合来实现纯减法功能,即应先置Cy=0,再用带借位的减法指令SUBB实现计算。即:
CLR C
SUBB A,源操作数
对PSW标志位的影响:ADDC、SUBB对PSW中的所有标志位均产生影响。
【例3-14】 (A)=C9H,(R2)=54 H,Cy=1,执行指令SUBB A,R2的运算式为:
结果:(A)=74H,Cy=0,AC=0,OV=1。
【例3-15】 两字节数相减,设被减数存放在30H和31 H单元,减数存放在40 H和41 H单元,差存放在50 H和51 H单元,若高字节有借位则转OVER2处执行。参考程序为:
3.加1/减1指令(共9条)
MCS-51单片机中设置了8位数据的加1(也称增量)、减1(也称减量)指令。
指令格式:
(1)INC<dest>;<dest>←<dest>+1
其中,<dest>即是源操作数又是目的操作数(即只有1个操作数),包括A、Rn、direct、@Ri、DPTR。它们分别为:
(2)DEC<dest>;<dest>←<dest>-1
其中,<dest>即是源操作数又是目的操作数(即只有1个操作数),包括A、Rn、direct、@Ri。它们分别为:
功能:
1)INC指令:[目的]←[目的]+1。指定的单元的内容加1。注意:若该字节的内容为FFH(前4条指令)/FFFFH(后1条指令),加1后将溢出,结果为00H(前4条指令)/0000H(后1条指令),但不影响进位标志。
2)DEC指令:[目的]←[目的]-1。指定的单元的内容减1。注意:若原来为00 H,减1后下溢为FFH,不影响标志位(P标志除外)。
对PSW标志位的影响:除了INC/DEC A指令操作影响P标志位、INC/DEC指令影响PSW的各个标志位外,其他操作均不影响PSW的各标志位。
4.乘法/除法指令(共2条)
MCS-51单片机设置有8位无符号的乘法、除法指令各1条。
指令格式:
(1)MUL AB ;8位无符号乘法操作,(B)(A)←(A)×(B)。
(2)DIV AB ;8位无符号除法操作,商(A)←(A)/(B),余数(B)。
功能:
(1)MUL指令把累加器A中的8位无符号数和寄存器B中的8位无符号数相乘,16位乘积的低8位放在(A)中,高8位放在(B)中,如果乘积大于255,则(OV)=1;否则(OV)=0。进位标志总为0,即(Cy)=0。
(2)DIV指令把累加器中的8位无符号数除以寄存器B中的8位无符号数,商的整数部分存(A)中,余数部分存寄存器B中。若除数(B)原来为00 H,则操作结果不定,且(OV)=1,否则(OV)=0。进位标志总为0(Cy)=0。
特点:乘法、除法指令在MCS-51指令系统中执行时间最长,均为4个机器周期指令。
【例3-16】 试分析指令的执行结果。
结果:(B)=32H,(A)=00H,标志:(Cy)=0,(OV)=1
5.十进制调整指令
MCS-51单片机设有1条对两个8位压缩型BCD码数据进行二进制加法规则运算的修正指令。但MCS-51单片机没有BCD码减法、乘法和除法的修正指令。
指令格式:DA A;源操作数只能在A中,调整后的结果重新存入A中。
功能:跟在加法指令ADD或ADDC后面,对A中运算结果的十进制数进行BCD码修正,使它调整为压缩的BCD码数,以完成十进制加法运算功能。其执行的规则是:
(1)若(A)3~0>9或(AC)=1,则(A)3~0←(A)3~0+6。
(2)若(A)7~4>9或(Cy)=1,则(A)7~4←(A)7~4+6。
(3)除此之外,A原数不变。
说明:在调整之前参与加法运算的两个数必须是压缩BCD码数(1个字节存放两位BCD码),和数也为压缩BCD码数。两个压缩BCD码数据按二进制数相加后必须经本指令调整才能得到正确的压缩BCD码数据之和。
注意:此指令不能对减法、乘法和除法指令进行修正。BCD码减法必须采用BCD补码运算法则,变减法为补码加法(被减数补码+减数的补码,减数的补码=9AH-减数),然后对其进行十进制调整来实现。MCS-51单片机无法对BCD码乘法和除法进行修正。
十进制调整问题。对BCD码加法运算,只能借助于二进制加法指令。但二进制数加法原则(逢二进一)上并不适于十进制数的加法运算(逢十进一),一般都会产生错误结果。例如:
上述的BCD码运算中:(a)结果正确;(b)结果不正确,因为BCD码中没有1111这个编码;(c)结果不正确,正确结果应为17,而运算结果却是11。
因此,二进制数加法指令不能完全适用于四位二进制编码中十进制数的加法运算,要对结果做有条件的修正,这就是所谓的十进制调整问题。
【例3-17】 对BCD码加法65+58→123,进行十进制调整。参考程序如下:
结果为(A)=23H,(Cy)=1。由上可见,65+58=123(BCD码),结果正确。
3.1.5.3 逻辑运算类指令(3种/共24条)
MCS-51的逻辑运算指令分为逻辑与(ANL)、逻辑或(ORL)、逻辑异或(XRL)、逻辑非(CPL)、清0(CLR)和移位操作。它们又可分为双操作数指令、单操作数指令两种。逻辑运算类指令见表3-4。它共有24条,又可分为3种。
分类:逻辑与/或/异或、逻辑非/清0和移位共3种。
格式:
(1)操作码<dest>,<src>
(2)操作码A
功能:双操作数据指令用于对<dest>、<src>两个8位数据进行逻辑与(ANL)、或(ORL)、异或(XRL)3种操作。单操作数据指令对累加器A中的8位数据进行求反(非)(CPL)、清0(CLR)、4种移位(RL/RLC/RR/RRC)操作。
寻址范围:双操作数的逻辑运算指令的寻址方式见图3-11所示。而单操作数据指令的寻址方式只能是寄存器寻址,且寄存器一定是累加器A。
图3-11 双操作数的逻辑运算指令的寻址方式
表3-4 逻辑运算类指令
续表
对PSW中标志位的影响:除了两条带进位的循环移位指令外(RLC、RRC),其余均不影响PSW中的各标志位。但当目的操作数是A时,将影响奇偶校验位P。
1.逻辑与/或/异或运算指令(共18条)
指令格式:
(1)ANL/ORL/XRL A,<src>
其中,<src>包括Rn、@Ri、direct、#data。它们分别为:
(2)ANL/ORL/XRL direct,<src>
其中,<src>包括A、#data。它们分别为:
功能:在指定的变量之间以位为基础进行逻辑与(ANL)、或(ORL)、异或(XRL)操作,结果存放到目的变量所在的寄存器或存储器中。逻辑与、或、异或运算的算子(即操作符)常用符号“∧”、“∨”、“⊕”来表示,由于逻辑与、或的运算规则与乘法、加法类似,也常借用“·”、“+”来表示逻辑与、或的运算符。但要注意算术运算与逻辑运算完全是两类意思不同的运算。
对PSW标志位的影响:不影响PSW中的各标志位,但当目的操作数是A时,将影响奇偶校验位P。特点及适用场合:
(1)逻辑与操作是两个二进制数中只要一个为0,则“逻辑与”之后结果为0。逻辑与可用于操作数的某些位清0(这些位与“0”),某些位不变(这些位与“1”)。
(2)逻辑或操作是两个二进制数中只要一个为1,则“逻辑或”之后结果为1。逻辑或可用于操作数的某些位置1(这些位或“1”),某些位不变(这些位或“0”)。
(3)逻辑异或操作是两个二进制数中若相同(0,0或者1,1),则“逻辑异或”之后结果为0;若相反(0,1或者1,0),则“逻辑异或”之后结果为1。逻辑异或可用于某些位取反(这些位异或“1”),操作数的某些位不变(这些位异或“0”)。
注意:当用逻辑与、或、异或指令修改一个并行I/O口输出内容时,则原始值将从该输出口的锁存器中读取,而不是从该输出口的引脚上读取。
【例3-18】 计算下列与、或、异或3条指令的运算结果。
(1)(A)=07H,(R0)=0FDH,执行指令ANL A,R0;
(2)(P1)=05 H,(A)=33 H,执行指令ORL P1,A;
(3)(A)=90H,(R3)=73H,执行指令XRL A,R3。
它们的运算式分别为:
【例3-19】 编程将21H单元的低3位和20H单元中的低5位合并为一个字送30H单元,要求(21 H)的低3位放在高位上。
2.累加器A清零/取反(共2条)
指令格式:
功能:
1)CLR指令将累加器A的内容8位二进制数都清零,即(A)=00 H。
2)CPL指令将累加器A的内容8位二进制数逐位取反,即(A)←()。
特点:可以节省存储空间,提高程序执行效率。
对PSW标志位的影响:不影响Cy、AC、OV标志位,但CLR A指令会影响的P标志位,而CPL A指令不影响P标志位。
3.累加器A循环移位操作(共4条)
MCS-51单片机的循环移位指令共有不带进位的循环左、右移位和带进位的循环左、右移位指令4条。
指令格式:
(1)RL A;左循环移位
(2)RR A;右循环移位
(3)RLC A;带进位左环移指令
(4)RRC A;带进位右环移指令
功能:它们的功能可用图3-12来描述。
(1)RL A使累加器A中的内容逐位向左循环移1位,且位7循环移入位0。(www.xing528.com)
(2)RR A使累加器A中的内容逐位向右循环移1位,且位0循环移入位7。
(3)RLC A使累加器A的内容(8位)同进位标志Cy的内容(1位)一起向左循环移1位。
(4)RRC A使累加器A的内容(8位)同进位标志Cy的内容(1位)一起向右循环移1位。
对PSW标志位的影响:4条指令的结果都是存入A中,因此都会影响P标志位;RL/RR不影响Cy、AC、OV标志位,但RLC/RRC是带Cy一起循环移位的,因此它们会影响Cy标志位。
特点:只能对累加器A进行循环移位。RL A累加器A中的数据逐位左移1位相当于原来8位无符号的内容乘2,而RR A累加器A中逐位右移1位相当于原来8位无符号的内容除以2。
图3-12 循环移位指令示意图
【例3-20】 对累加器A进行乘4运算。
左循环移位“RL A”也常用于实现乘2n(如乘2、4、8等)运算。当需要对累加器A进行乘4运算时,如果A小于3FH,可用下面两条左循环移位指令来完成。
RL A ;1字节、2个机器周期,左循环移位1次,相当于乘2
RL A ;1字节、2个机器周期,再左循环移位1次
上面两条指令执行时间需要4个机器周期,代码长度为2字节。上面的运算也可直接用下面的乘法来实现。
MOV B,#04H ;3字节、2个机器周期
MUL AB ;1字节、4个机器周期
通过上面乘法实现同样的功能需要6个机器周期,代码长度为4字节。
因此,采用左循环移位指令与采用乘法指令相比,其速度更快、代码更短。
图3-13 例3-21的电路图
【例3-21】 利用MCS-51单片机的P1口输出控制LED的发光,电路连接如图3-13所示。编程实现使累加器A中的数据循环送P1口,并使用P2.0输出指示进位标志。
该程序逐位将A中的最低位移入进位位C,并由P2.0输出。如果反复调用该程序,并且在每次调用之间加上一定的延时,就会形成“跑马灯”的效果。
3.1.5.4 控制转移类指令(4种/共17条)
为了控制程序的执行方向,微机都设置了控制转移指令。控制转移指令用来改变程序计数器PC的值,使PC有条件的或者无条件的或者通过其他方式,从当前的位置转移到一个指定的地址单元去,从而改变程序的执行方向。MCS-51单片机提供了17条控制转移指令。控制转移类指令见表3-5。它共有17条,又可分为4种,分别是:无条件转移、条件转移(判断跳转)、子程序调用及返回和空操作共4种。
功能:改变程序计数器PC中的内容,控制程序执行的流向,实现程序分支转向。
对PSW标志位的影响:除了CJNE影响PSW的进位标志位Cy外,其余均不影响PSW的各标志位。
表3-5 控制转移类指令
1.无条件转移(共4条)
MCS-51单片机中设有4种无条件转移指令,它们能实现无条件的程序转移,其功能类似于C语言中的“goto”功能。
指令格式:
(1)LJMP addr16;长转移指令,3字节,(PC)←addr15~0。
(2)AJMP addr11;绝对转移指令,2字节,(PC)←(PC)+2,PC10~0←addr11。
(3)SJMP rel;相对(短)转移指令,2字节,(PC)←(PC)+2+rel。
(4)JMP@A+DPTR;间接转移(散转)指令,单字节,(PC)←(DPTR)+(A)。
功能:
(1)LJMP addr16转移的目的地址是一个16位常数,它直接将指令中的16位常数装入PC中,使程序无条件地转移到指定的地址处执行。最长区域为64KB。
(2)AJMP addr11的指令机器码为A10 A9 A8 00001和A7~A0两个字节,该指令把指令中给出的addr11(A 10~A0)作为转移目的地址的低11位码,而把AJMP指令的下一条指令的首地址(即PC当前值加2)的高5位作为转移目的地址的高5位(PC)15~11拼装新的16位转移目的地址。
(3)SJMP rel执行时在PC加2(本指令为2个字节)之后,把指令的带符号8位二进制补码数的偏移量rel(范围-128~+127)加到PC上,并计算出目的地址。
(4)JMP@A+DPTR目的地址由DPTR的16位无符号数(基址)与A中8位无符号数(变址)内容之和形成控制程序转移的目的地址。给A赋予不同值,即可实现多分支转移。
说明及注意点:
(1)使用转移指令时,指令中的地址或偏移量均可采用标号来表示目的地址,在执行前被汇编程序自动计算编译成实际的二进制地址。例如,
(2)指令的转移范围:在执行当前转移指令后的PC值的基础上。
1)长转移指令LJMP:64KB,简称“长跳”。
2)绝对转移指令AJMP:2KB,简称“中跳”。
只能在64KB存储区的整段2KB区域转移,即转移地址必须与PC当前值加2形成的地址PC在同一个2KB区域内(即高5位地址码A 15~A 11相同)。整段2KB区域为0000 H~03FFH,0400H~07FFH,…,FC00 H~FFFFH。
需注意,目标地址必须与AJMP指令的下一条指令首地址的高5位地址码A 15~A 11相同,否则将混乱。
3)相对(短)转移指令SJMP:-128~+127(8位补码表示范围字节),简称“短跳”。
4)间接(散)转移指令JMP:64KB,简称“散跳”。
(3)相对(短)转移指令SJMP rel中地址偏移量的计算:
rel=转移目标地址-转移指令地址(当前PC值)-2
(4)MCS-51单片机没有专门设置暂停指令(暂停当前的程序,并不是真的停机),但它可用原地踏步来实现暂停功能。例如,HERE:SJMP HERE或写为SJMP$。
上面两条指令功能完全等价,其中符号“$”用于表示该转移指令操作码本身所在的地址。
(5)JMP@A+DPTR间接转移(散转)指令常用于实现程序的多个分支转移(散转)程序结构中,它可以在程序的运行过程中,动态地决定程序的分支走向,即构成所谓散转程序。此时,DPTR为转移目的的起始地址,A为转移目的的偏移量。
(6)在编程中,经常使用短转移指令SJMP和相对转移指令AJMP,以便生成浮动代码,并不经常使用长转移指令LJMP。
【例3-22】 设PC当前值为0123H,试分析执行在此地址处的指令LJMP 3456 H的过程,如图3-14所示。
图3-14 LJMP指令的执行过程
在PC的当前地址0123H开始的连续3个单元存放指令的操作码和操作数,存放顺序是:02 H(操作码),34 H(转移地址常数高字节),56 H(转移地址常数低字节)。指令执行时,将转移地址分别装入PCH和PCL。即转移到地址3456H处,执行该处的指令序列。
【例3-23】 编写按键值处理的键盘程序。
2.条件转移(判断跳转)(共8条)
MCS-51单片机中设有4种条件转移指令,它们能实现带条件的程序转移,在规定的条件满足时进行程序转移,否则程序往下顺序执行。其功能类似于C语言中的“IF<条件>THEN”功能。
指令格式:
(1)JZ rel ;判零转移,2个字节。若(A)=0则转移(PC)←(PC)+2+rel,;若(A)≠0则顺序执行(PC)←(PC)+2
(2)JNZ rel ;判非零转移,2个字节。若(A)≠0则转移(PC)←(PC)+2+rel,;若(A)=0则顺序执行(PC)←(PC)+2
(3)CJNE<dest>,<src>,rel ;比较不相等转移指令,3字节。
;若<dest>=<src>,则程序继续执行,(PC)←(PC)+3
;若<dest>><src>,则程序转移,(PC)←(PC)+rel+3,Cy←0
;若<dest><<src>,则程序转移,(PC)←(PC)+rel+3,Cy←1
当目的操作数<dest>为A时,源操作数<src>为#data、direct;当目的操作数<dest>为Rn、@Ri时,源操作数为#data。4条指令分别是:
(4)DJNZ<dest>,rel
减1不为0转移指令,2个字节。<dest>←<dest>-1。若<dest>≠0,则转移(PC)←(PC)+2+rel;若<dest>=0,则不转移(PC)←(PC)+2。
当目的操作数<dest>为Rn、direct时。2条指令分别是:
DJNZ Rn,rel ;n=0~7
DJNZ direct,rel
指令功能:
(1)JZ如果累加器(A)=00 H,则执行转移。
(2)JNZ如果累加器(A)≠00H,则执行转移。
(3)CJNE比较前两个无符号8位操作数大小,如果值不相等则转移,并转向目的地址。CJNE指令是把比较与条件转移两种功能结合在一起的指令。它是先通过两操作数的减法实现比较大小,影响Cy标志位,再根据Cy标志进行转移。
注意,该指令不保存最后的差值,两个操作数的内容不变。通常利用CJNE指令的比较操作和它对标志位的影响来实现程序的多分支结构。对应分支程序如图3-15所示。
图3-15 CJNE操作示意图
(4)DJNZ具有减1判非0则转移的功能。它是把减1与条件转移两种功能结合在一起的指令。它一般用于控制程序循环,实现按循环次数控制循环的目的。通过预先装入循环次数,以减1后是否为“0”作为转移条件,即可实现按次数控制循环功能。
指令的转移范围:条件转移指令均为相对转移指令,只能“短跳”,不能“长跳”或“中跳”,因此指令的转移范围十分有限。转移目的地址在以下一条指令首地址为中心的256B范围内(-128~+127)。rel的取值范围是在执行当前转移指令后的PC值基础上(当前PC值+2或3,其中2或3为当前转移指令的字节数)的-128~+127(用补码表示)。可以采用符号地址表示,偏移量rel的计算方法:
rel=转移目标地址-转移指令地址(当前PC值)-2或3
若要实现64KB范围内的转移,则可以借助于一条长转移指令的过渡来实现。
对PSW标志位影响:除CJNE指令只影响进(借)位标志Cy以外,其他指令不影响PSW中的标志位。
【例3-24】 在内部RAM的40 H地址单元中,有1字节符号数,编写求其绝对值后放回原单元的程序。
带符号数在微算中以补码形式存放,例如-6,存放在内部RAM中为0FAH,求补后得6。参考程序为:
【例3-25】 在内部RAM中从60H单元开始的连续单元依次存放了一串字符,该字符串以回车符为结束标志,要求测试该字符串的长度。参考程序为:
【例3-26】 将内部RAM从DATA单元开始的15个8位无符号数相加,相加结果送SUM单元保存(假设相加结果不超过8位)。
假设相加的结果不超过8位二进制数,则相应的参考程序为:
【例3-27】 设片内RAM的20 H单元的内容为:(20H)=x7x6x5x4x3x2x1x0,把该单元内容反序后放回20H单元,即为:(20H)=x0x1x2x3x4x5x6x7。
可以通过先把原内容带进位右移一位,低位移入Cy中,然后左移一位,Cy中的内容移入,通过8次处理即可,由于8次过程相同,可以通过循环完成,移位过程当中必须通过累加器来处理。设20 H单元原来的内容先通过R3暂存,结果先通过R4暂存,R2作循环变量。
另外,由于片内RAM的20H单元在位寻址区,这一问题还可以通过位处理方式来实现。参考程序为:
3.子程序调用及返回指令(共4条)
定义:具有完整功能的程序段定义为子程序,供主程序调用。
功能:供主程序在需要时调用。子程序可以在程序中反复多次使用,以简化源程序的书写。
主程序与子程序之间的调用关系如图3-16(a)所示,两级子程序嵌套的示意图如图3-16(b)所示。
图3-16 主程序与子程序之间的调用关系
为了实现主程序对子程序的一次完整调用,必须有子程序调用指令和子程序返回指令。子程序调用指令在主程序中使用,而子程序返回指令则是子程序的最后一条指令。调用与返回指令是成对使用的。
MCS-51单片机中设置了4条子程序调用与返回指令。
指令格式:
(1)LCALL addr16;绝对长调用指令,3字节。
其中,addr16为16位地址,实际编程时可以用符号地址。可以在64KB范围以内调用子程序。
(2)ACALL addr11;绝对短调用指令,2字节。
其中,addr11为11位地址,实际编程时可以用符号地址。并且只能在2KB范围以内调用子程序。ACALL addr11与AJMP指令类似,为兼容MCS-48的CALL指令而设,不影响标志位。
(3)RET;子程序返回指令。(PC)15~8←((SP)),(SP)←(SP)-1,(PC)7~0←((SP)),(SP)←(SP)-1。
(4)RETI;中断子程序返回指令,(PC)15~8←((SP)),(SP)←(SP)-1,(PC)7~0←((SP)),(SP)←(SP)-1。
指令功能:
(1)长调用指令LCALL。LCALL addr16可调用64KB范围内程序存储器中的任何一个子程序。执行时,先把PC加3获得下一条指令的地址(断点地址),并压入堆栈(先低位字节,后高位字节),堆栈指针加2。然后转移到指令中addr16所指定的地方执行。其操作相当于两条堆栈推入“PUSH”指令再加上1条长跳转“LJMP”指令功能的组合,即为:
(2)绝对短调用指令ACALL。ACALL addr11的指令编码为A10 A 9 A8 10001 A 7~A0两个字节,它可在2KB区域内的绝对调用。其操作相当于两条堆栈推入“PUSH”指令再加上1条中跳转“AJMP”指令功能的组合,即为:
指令的操作过程为:
(3)子程序返回指令RET。RET将自动返回到调用指令的下一条指令处继续执行主程序,也就是把调用开始时压入堆栈保存的返回地址从堆栈中弹出并送入PC中。其操作相当于两条堆栈弹出“POP”指令功能的组合,即为:
其具体操作为:
(4)中断服务子程序返回指令RETI。RETI用于中断服务子程序后面,作为中断服务子程序的最后一条指令,它的功能是返回主程序中断的断点位置,继续执行断点位置后面的指令。它的功能与RET指令相似,不同之处是该指令清除了中断响应时被置1的内部中断优先级寄存器的中断优先级状态(该寄存器由CPU响应中断时置位,指示CPU当前是否处理高级或低级中断),表示CPU已退出该中断的处理状态,其他相同。其操作相当于两条堆栈弹出“POP”指令功能的组合,即为:
说明及注意点:
(1)子程序调用指令LCALL或ACALL的功能必须具有自动把程序计数器PC中的断点地址保护到堆栈中,且将子程序入口地址自动送入程序计数器PC中的功能;(中断服务)子程序返回指令RET或RETI的功能必须具有自动把堆栈中的断点地址恢复到程序计数器PC中的功能。此外,子程序调用时应注意入口参数设置,子程序返回时应注意出口参数的传递。
(2)LCALL指令的调用的子程序位置(即转移范围)可以是64KB程序存储空间的任一位置,可实现“长调”;ACALL指令的调用的子程序位置(即转移范围)指令的调用的子程序位置(即转移范围)只可与ACALL指令的下一条指令必须在同一个2KB内,子程序地址必须与ACALL指令下一条指令的16位首地址中的高5位地址相同,可实现“中调”。
(3)LCALL与ACALL功能类似,只是两者指令长度和转移范围不相同。实际上,ACALL完全可以用LCALL取代,MCS-51单片机中还保留ACALL指令的原因是为了与之前生产的MCS-48单片机指令兼容(这种机型的ROM地址为12位)。
(4)使用LCALL和ACALL两条子程序调用指令时,指令中的16位或11位地址均可采用标号来表示目的地址,只有在执行前才被汇编程序自动计算编译成实际的二进制地址。
(5)RET指令必须与调用指令(LCALL或ACALL)成对出现,RET指令通常放于子程序的最后一条指令位置,用于实现返回到主程序。此外,还可用RET指令来实现程序转移,即先将转移位置的地址用两条PUSH指令入栈,低字节在前,高字节在后,然后执行RET指令,执行后程序转移到相应的位置去执行。
(6)RETI的具体操作与RET指令基本相同,只是RETI在执行后,在转移之前还将先清除中断的优先级触发器。RET适用于从子程序返回,而RETI适用于从中断服务程序返回。无论是RET还是RETI都是子程序执行的最后一条指令。
(7)RETI和RET指令的最大不同在于它们的转移方式不一样。子程序调用是受主程序控制的,即有指令ACALL或LCALL来调用;而中断转移是由外部因素决定的,即外部中断是在主程序的执行过程中随机产生的,因此中断返回主程序(RETI)的地址名是固定的,它是检测到中断请求的当前指令的下一条指令地址。而子程序的返回(RET)地址是事先已知的。
在MCS-51系统中,中断都是硬件中断,无软件中断调用指令。硬件中断时,由一条长转移指令使程序转移到中断服务程序的入口位置,在转移之前,由硬件将当前的断点地址压入堆栈保存,以便于以后通过中断返回指令返回到断点位置后继续执行。
对PSW标志位的影响:这类指令对PSW中的标志位无任何影响。
【例3-28】 试分析指令的执行过程。
具体执行过程如图3-17所示。
执行结果:(SP)=09H,(08H)=06H,(09H)=20H,(PC)=4567H。
【例3-29】 设计节日灯,通过P1.0~P1.7控制8个发光二极管,先亮1灯,隔1s闪烁10次,然后左移1位闪10次,如此循环。如图3-18所示。
参考程序为:
图3-17 LCALL操作执行过程
图3-18 例3-29的硬件结构与软件流程图
4.空操作指令(共1条)
MCS-51单片机设置了1条不做任何操作,但需用1个机器周期的“空操作”指令。
指令格式:NOP ;(PC)←(PC)+1
功能:不执行任何操作,消耗了1个机器周期,常用于软件延时或在程序可靠性设计中用来稳定程序。
特点:NOP占据一个单元的存储空间,除了使PC的内容加1外,CPU不产生任何操作结果,只是消耗了一个机器周期。
对PSW标志位的影响:对PSW中的标志位无任何影响。
说明:该指令主要用于程序延时,还可用于修改调试程序,用来填充修改后剩余的少量地址空间。
3.1.5.5 布尔处理类指令(位操作指令)(4种/共17条)
MCS-51单片机设有一个功能相对独立的位处理机(即布尔处理机),因而其具有较强的位处理功能。位操作指令在单片机指令系统占有重要地位,这是因为单片机在控制系统中主要用于控制线路通断,继电器的吸合与释放等。因此,MCS-51单片机的8位机内部还保留了完整的1位机系统,它除了具有1位的硬件外,还具有1位的软件指令,即提供了位寻址功能和位操作指令。布尔处理类指令见表3-6。这类指令共17条,可分为4种。
分类:可分为位传送、位逻辑与/或/非运算、位清零/置位、位条件转移共4类。
表3-6 布尔处理类指令
特点:位操作的操作数不是字节,而是字节中的某个位,每位的取值只能取0或1。位操作是以进位标志Cy作为位累加器,可以实现布尔变量的传送、运算和控制转移等功能。
寻址范围:前面已述,位寻址区包括两块,一块是片内RAM字节地址为20H~2FH的位寻址区(低128位的位地址,00H~7FH),另一块是SFR中的11(51子系列)/12(52子系列)个可位寻址特殊功能寄存器中的83(51子系列)/92(52子系列)个可寻址位(高128位的位地址,80H~FFH)。
位地址的表达方式:前面已述,位寻址只能采用直接位寻址bit,但为了方便用户使用,它可用多种方式来表达,编译程序最终都会把它们翻译转换成直接位地址。它们的表示方法有:直接位地址方式(如0AFH)、特殊功能寄存器名.位序号(如PSW.3)、字节地址.位序号(如0D0 H.0)、位名称方式(如F0)和用户定义名称等几种方式。
1.位数据传送指令(共2条)指令格式
(1)MOV C,bit ;(Cy)←(bit)
(2)MOV bit,C ;(bit)←(Cy)
指令功能:把源操作数指定的位变量送到目的操作数指定处。一个操作数必须为进位标志Cy,另一个可以是任何直接寻址位bit。
特点:在可寻址位与位累加器Cy之间进行的。不能在两个可寻址位之间直接进行传送。
对PSW标志位的影响:MOV C,bit指令会影响进位标志Cy,不影响其他标志;而MOV bit,C一般不影响任何标志位,除非bit本身就是PSW中的标志位。
【例3-30】 将30 H位地址的内容传送到20 H位地址中,并保留标志位Cy的值。
MOV 10H,C ;用10H位单元暂存Cy的内容
MOV C,30H ;(Cy)←(30H)
MOV 20H,C ;(20H)←(Cy)
MOV C,10H ;(Cy)←(10H)恢复原值
2.位逻辑运算指令(共6条)指令格式:
(1)操作码C,<SRC>
其中,操作码包括ANL(逻辑位“与”)、ORL(逻辑位“或”);<SRC>包括bit、/bit。它们分别为:
(2)CPL<dest> ;<dest>←<dest>
其中,CPL表示取反(即逻辑位“非”),<dest>包括Cy、bit。它们分别为:
指令功能:
(1)ANL C,bit指令直接寻址位bit与进位标志位Cy(位累加器)进行“逻辑与”运算,结果送回到Cy中。
(2)ANL C,/bit指令先对直接寻址位bit求反,然后与位累加器Cy进行“逻辑与”运算,结果送回到Cy中。
(3)ORL C,bit指令是直接寻址位bit与位累加器Cy进行“逻辑或”运算,结果送回到Cy中。
(4)ORL C,/bit指令先对直接寻址位bit求反,然后与位累加器Cy进行“逻辑或”运算,结果送回到Cy中。
(5)CPL C指令是把位累加器Cy内容取反再送回Cy中。
(6)CPL bit指令是把直接寻址位bit内容取反再送回bit中。
对PSW标志位的影响:一般都不影响标志位。但若目标操作数为C,则会影响Cy;或若目标操作数为bit且bit本身就是PSW中的标志位,则会影响该标志。
说明:
(1)ANL C,/bit“基本”相当两条指令CPL bit和ANL C,bit的组合,而ORL C,/bit“基本”相当两条指令CPL bit和ORL C,bit的组合。但需注意的是这两条指令的执行前、后,bit的内容并没有被取反,bit内容保持不变,仅是在逻辑位“与”、“或”运算时,需把bit取反为。
(2)位逻辑操作指令用于位逻辑操作,还可用于对组合逻辑电路的模拟。采用位操作指令进行组合逻辑电路的设计比采用字节型逻辑指令节约存储空间,运算操作十分方便。
(3)MCS-51没有提供逻辑位异或运算指令,当需要做逻辑位异或运算时,可通过逻辑位与、或指令得到,因为。
3.位清零/置位指令(共4条)指令格式:
(1)CLR<dest>;<dest>←0
其中,<dest>包括Cy、bit。
(2)SETB<dest>;<dest>←1
其中,<dest>包括Cy、bit。它们分别为:
对PSW标志位的影响:一般都不影响标志位。但若目标操作数为C,则会影响Cy;或若目标操作数为bit且bit本身就是PSW中的标志位,则会影响该标志。
4.位条件控制转移指令(共5条)
特点:以位的状态作为实现程序转移的判断条件。指令格式:
(1)以进位标志位Cy内容为条件的转移指令:
1)JC rel ;若(Cy)=1,则转移(PC)←(PC)+2+rel,否则顺序执行。
2)JNC rel ;若(Cy)=0,则转移(PC)←(PC)+2+rel,否则顺序执行。
(2)以位地址bit内容为条件的转移指令:
1)JB bit,rel;若(bit)=1,则转移(PC)←(PC)+3+rel,否则顺序执行。
2)JNB bit,rel;若(bit)=0,则转移(PC)←(PC)+3+rel,否则顺序执行。
3)JBC bit,rel;若(bit)=1,则转移(PC)←(PC)+3+rel,且(bit)←0,否则顺序执行。
它们的功能如图3-19所示。
对PSW标志位的影响:只有JBC bit,rel指令中bit本身就是PSW中的标志位,则会影响该标志。其他4条指令不影响标志位。
注意:
(1)JNC指令为JC判断条件相反指令,JB指令为JNB判断条件相反指令,JC与CJNE指令相配合,能够实现三分支结构。JNC与CJNE指令相配合也能实现三分支结构。
(2)JB bit,rel与JBC bit,rel两指令的功能类似,只是JBC bit,rel还多做1个操作,即若bit=1时不但要转移,还要把寻址位bit清0。因此,JBC bit,rel相当于JB bit,rel再加上CLR bit的两条指令组合。
【例3-31】 利用位操作指令,模拟图3-20所示硬件逻辑电路的功能。
参考程序为:
图3-19 位条件转移指令
图3-20 硬件逻辑电路图
3.1.5.6 某些指令的说明
111条汇编指令已经介绍完毕。由于指令条数多,不应采用“死记硬背”的方法来学习指令系统,而应在程序的编写中多加练习,在实践中不断掌握和巩固常用的指令。另外,应该学会熟练地查阅MCS-51单片机的指令表,正确地理解各条指令的功能及特性并正确地使用这些指令。
MCS-51单片机的指令系统中还有几个细节问题说明如下。
1.十六进制数据前要加“0”问题
MCS-51单片机的指令中,通常会在某些数据或地址的前面多填一个前导“0”,这是为什么呢?
由于十六进制数A~F是用字母来表示的,而指令的标号也常用字母表示,为了把将标号和数据两者区分开来,一般汇编语言都规定,凡是以字母开头的十六进制数字量的前面都需添加一个数字“0”。由于地址量也是数据量的一种,因此,以字母开头的十六进制地址的前面也应该添加“0”。如果不加前导“0”,低版本的汇编语言编译程序可能会把字母开头的数据当作标号来处理,从而导致出错或者不能通过汇编。目前,高版本的汇编语言编译程序一般已不需加前导“0”了。
例如:MOV A,#0E5 H和MOV A,0E5 H;以字母开头的数据量“E5”和以字母开头的地址量“E5”前面都加了前导“0”。
2.操作数的字节地址和位地址的区分问题
MCS-51单片机是如何把指令中字节变量和位变量区分开来的呢?
例如,指令“MOV A,50 H”与指令“MOV C,50 H”两条指令中的源操作数都是以直接地址50 H形式给出,那么50 H到底是字节地址还是位地址呢?
实际上,对于这两条助记符相同指令,观察操作数就可容易地看出:“MOV A,50H”指令的“50 H”是字节地址,因为目的操作数A是字节变量;“MOV C,50 H”指令中的“50H”肯定是位地址,因为目的操作数C是位变量。
3.累加器A与Acc(或ACC)的书写问题
MCS-51单片机的指令中,累加器可写成A或Acc(或ACC),区别是什么?
有些指令累加器可写成A或Acc都可以,但写成“A”汇编后则隐含在指令操作码中,而写成“Acc”汇编后的机器码必有1个字节的操作数是累加器的字节地址E0H。例如:“INC A”的机器码是04H;而写成“INC Acc”后,则成了“INC direct”的格式,对应机器码为“05 H和E0 H”。
一般对累加器A直接寻址和累加器A的某1位寻址要用“Acc”,不能写成“A”。例如:指令“POP Acc”不能写成“POP A”;指令“SETB Acc.0”也不能写成“SETB A.0”。
4.并行I/O口P0~P3的“读引脚”和“读锁存器”指令的区别问题
当指令的目标操作数为P0~P3口时,也就是通过某条指令来修改一个并行I/O口输出内容时,则原始值将从该输出口的锁存器中读取,而不是从该输出口的引脚上读取。
例如,指令“CPL P1.7”则是“读锁存器”,也即“读—修改—写”指令,它会先读P1.7的锁存器的Q端状态,接着取反,然后再送到P1.7引脚上。再如,指令“ANL P1,A”也是“读锁存器”命令。类似的“读—修改—写”指令还有:“INC P1”、“XRL P3,A”、“ORL P2,A”、“ANL P1,A”等。
而对指令“MOV C,P1.7”读的却是P1.7脚,同样对指令“MOV A,P1”也是读引脚指令。注意,读引脚指令之前一定要有向该引脚(如P1.7)写入高电平“1”的指令。
下面再举一个简单实例。当P1口的P1.7引脚外接一个发光二极管LED的阳极,LED的阴极接地。若想查看一下单片机刚才向P1.7脚输出的信息是0还是1,如何做呢?
不能直接从P1.7脚读取,因为单片机刚才向P1.7输出的信息如果是1的话,则LED导通点亮,此时P1.7引脚就为0电平,如果直接读引脚,结果显然错误。
正确的做法是读D锁存器的Q端状态,那里储存的才是前一时刻送给P1.7的真实值。就是说,凡遇“读取P1口前一状态以便修改后再送出”的情形,都应当“读锁存器”的Q端信息,而不是读取引脚的信息。
当P1口外接输入设备时,要想P1口引脚上反映的是真实的输入信号,必须要设法先让该引脚内部的场效应管截止才行,否则当场效应管导通时,P1口引脚上将被箝位在低电平“0”,无法正确反映外设的输入信号。为此,应让场效应管截止,就是用指令给P1口的相应位送一个高电平“1”,这就是为什么读引脚之前,一定要先送出“1”的原因。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。