1 关于并行I/O接口的读引脚和读锁存器指令的区别
例如,当P1口的P1.0引脚外接一个发光二极管LED的阳极,LED阴极接地。
若想查看一下单片机刚才向P1.0脚输出的信息是0还是1,不能直接从P1.0脚读取,因为单片机刚才向P1.0输出的信息若是1,则LED导通点亮,此时P1.0引脚就为0电平,如果直接读引脚,结果显然错误。
正确的做法是读D锁存器的Q端状态,那里储存的才是前一时刻送给P1.0的真实值。也就是说,凡遇读取P1口前一状态以便修改后再送出的情形,都应当读锁存器的Q端信息,而不是读取引脚的信息。
当P1口外接输入设备时,要想P1口引脚上反映的是真实的输入信号,必须要设法先让该引脚内部的场效应晶体管截止才行,否则当场效应晶体管导通时,P1口引脚上将永远为低电平,无法正确反映外设的输入信号。让场效应晶体管截止,就是用指令给P1口的相应位送一个1电平,这就是在读引脚之前,一定要先送出1的原因。
指令MOV C,P1.0读的是P1.0脚,同样指令MOV A,P1也是读引脚指令,读引脚指令之前一定要有向P1.0写1的指令。
而指令CPL P1.0则是读锁存器,也即读-修改-写指令,它会先读P1.0的锁存器的Q端状态,接着取反,然后再送到P1.0引脚上。而指令ANL P1,A也是读锁存器命令。类似的读-修改-写指令举例如下:
INC P1
XRL P3,A
ORL P2,A
ANL P1,A
CPL P3.0
2 关于操作数的字节地址和位地址的区分问题
如何区别指令中出现的字节变量和位变量?
例如,指令MOV C,40H和指令MOV A,40H两条指令中源操作数40H都是以直接地址形式给出的,40H是字节地址还是位地址?对于助记符相同指令,观察操作数就可看出。
显然前条指令中的40H肯定是位地址,因为目的操作数C是位变量。
后条指令的40H是字节地址,因为目的操作数A是字节变量。
3 关于累加器A与ACC的书写问题
累加器可写成A或ACC,区别是什么?
ACC汇编后的机器码必有一个字节的操作数是累加器的字节地址E0H,A汇编后则隐含在指令操作码中。
例如,INC A的机器码,查表是04H。
如写成INC ACC后,则成了INC direct的格式,再查表,对应机器码为05H E0H。在对累加器A直接寻址和累加器A的某一位寻址时要用ACC,不能写成A。
例如,指令POP ACC不能写成POP A;指令SETB ACC.0不能写成SETB A.0。
4 书写2位十六进制数据前要加0
经常遇到必须在某些数据或地址的前面多填一个前导0。
由于部分十六进制数是用字母来表示的,而程序内的标号也常用字母表示,为了将标号和数据区分开,几乎所有的汇编语言都规定,凡是以字母开头(对十六进制数而言,就是A~F开头)的数字量,应当在前面添加一个数字0。(www.xing528.com)
至于地址量,它也是数据量的一种,前面也应该添加0。
例如:
MOV A,#0F0H;F0以字母开头的数据量
MOV A,0F0H;F0以字母开头的地址量
如不加前导0,就会把字母开头的数据量当作标号来处理,从而出错并不能通过汇编。
操作数为工作寄存器或特殊功能寄存器时,允许用工作寄存器和特殊功能寄存器的代号表示。
例如,工作寄存器用R7~R0,累加器用A(或ACC)表示。另外,工作寄存器和特殊功能寄存器也可用其地址来表示,如累加器A可用其地址E0H来表示。
表3-27是一段源程序的汇编结果。可查表手工汇编,来验证下面的汇编结果是否正确。机器码从1000H单元开始存放。
表3-27 源程序及汇编结果
例3-29:班级成绩存在片内以30H为首址的单元中,统计该班及格、不及格人数(R1装≥60分的人数,R2装<60分的人数,R7装班级人数)。
程序段如下:
MOV R0,#52H
MOV R7,#23H
AAA:MOV A,@R0
CJNE A,#60,XU60
INC R1;=60
SJMP DEND
XU60:JNC DU60
INC R2;<60
SJMP DEND
DU60:INC R1;>60
DEND:DEC R0
DJNZ R7,AAA
END
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。