1、MCS-51 单片机通常有 4 个 8 位 I/O 端口, 向各端口的写数据均写入到对应端口的锁存器中, 但对各端口的读操作却有两个方式:读锁存器和读引脚 1 读-修改- 写操作Pn(指 P0,P1,P2,P3)在 51 汇编语言中是特殊的标识符,既代表 Pn 端口引脚,又代表 Pn 锁存器(Pn SFR)。在MCS-51 指令系统中有些指令读锁存器的值, 有些指令则读引脚上的值。读锁存器指令是从锁存器中读取一个值并进行处理, 把处理后的值(原值或已修改后的值) 重新写入锁存器中。这类指令称为读 -修改-写指令, 表 1 列举了有该功能的指令 当目的操作数是 Pn 端口或 Pn 端口的某一位时
2、. 该指令读取锁存器的值.这些指令的一个共同特点, 就是要先并行读入 Pn 锁存器(非 Pn 端口引脚)中的值,作一定的修改,然后再写入谚端口的锁存器。表 1 中晶后三条指令读-修改- 写关系不够明显。实际上它们的执行过程序是:先将Pn 的 8 位锁存器内容一起读人,再对指定位进行修改, 然后又 8 位一起写入锁存器。对于读-修改- 写指令。直接读锁存器而不是读端口引脚, 是因为从引脚上读出的数据不一定能真正反映锁存器的状态 例如:若用 Pn 的某一位引脚直接驱动一个 NPN 三极管的基极,当向此端口写“1” 时, 三极管导通并把端口引脚的电平钳位约 0.7 V (对于硅管) 这时,CPU 若
3、从此引脚读取数据. 会把该数据( 应为 1)错读为 0;若直接从锁存器读取, 则读出正确的数据。理解了 Pn 的特殊性及读 -修改-写指令后, 就不难理解指令 PUSH Pn 的含义了。它的执行过程是:读 Pn引脚(非读 Pn嫫?的值, 然后将此数值压入堆栈 以下是一段测试程序:ORG 1000H1000 75A07F MOV P2,#7FH1003 7900 MOV R1,#00H1005 74FF MOV A,#0FFH1007 COA0 PUSH P21009 D0A0 POP P2100B F3 MOVX R1,A100C 22 RET这段程序原意是将 FFH 立即数存人外部 RAM
4、地址为 7F00 的单元中 , 但具体的运行结果与这段程序是在片内或片外被执行有密切关系。若在片内,结果与程序原意一致;若在片外,MCU 执行这段片外程序后 结果却把 FFH 错误地送到了外部 RAM 的 1000H 地址去。为什么会出错?因为在执行片外程序时, 出现在P2 端口引脚上的数据是 PCH (程序指针的高 8 位,此时为 10H),在执行 PUSH P2 指令时.读取 P2 引脚上的数据是 10H.所以将 10H 压入堆栈,紧跟的 POP P2 指令是将当前栈顶数据 10H 弹出并写入 P2 锁存器,然后执行的 MOVX R1,A 指令,将 A 中的数据写入P2R1(此时 P2RI
5、=1000H)地址中 有兴趣的读者可以尝试一下。2 可靠读取 Pn 锁存器中数据的方法上述程序并无实际运行意义, 在这里只是引出如何可靠地读取 Pn 锁存器中的数据问题。在 MCS51 指令系统中并没有一条指令可以让汇编程序员直接读取 Pn 锁存器的数据。在表 1 中只有 JBC Pn.Y,Label 可以较快速地获取 Pn 锁存器第 Y 位的值。由于篇幅关系,本文只介绍 P2 锁存器的操作,其他锁存器的操作可参照 P2 写出 下面是获取 P2 锁存器值的子程序。GetSfrP2:PUSH IE ;保护中断允许寄存器CLR EA ;禁止所有中断MOV A.#0FFHJBC P2.0,$+5;P
6、2 锁存器位 0 为 1 则清 0 并跳;转到$+5 地址(JBC P2.1,$+5)CLR ACC.0 ;否则 ACC.0 清为 0JBC P2.1,$+5CLR ACC.1JBC P2.2,$+5CLRACC2JBC P2.3,$+5CLR ACC 3JBC P2.4,$+5CLR ACC 4JBC P2.5,$+5CLRACC 5JBC P2.6,$+5CLR ACC.6JBC P2.7,$+5CLR ACC.7MOV P2,A ;恢复 P2 锁存器原值POPIE ;恢复中断允许寄存器RET另外也可在 RAM 中建立各 Pn 锁存器的映像.通过专用程序对 Pn 锁存器进行操作 这样就可以
7、在不对引脚状态有任何影响的情况下,快速可靠地读取与 Pn 锁存器一致的数值。以在内部 RAM 中建立 P2 映像为例:EP2 Data 60H ; P2 锁存器映像WriteSfrP2: MOV EP2,A ;将 A 写人 P2 锁存器映像MOV P2,A ;将 A 写人 P2 锁存器RETReadSfrP2: MOV A,EP2 ;将 P2 锁存器映像写入 ARET如果确信读 P2 端口时的值都等于 P2 锁存器中的值,则可以用 51 单片机地址指针及其应用的操作方法,简单地 PUSHP2 和 POP P2 指令来保护和恢复现场程序段中使用的 P2 锁存器以上三种读取 Pn 锁存器值的方法, 第二种方法,即在 RAM 中建立 Pn 锁存器映像的方法,存取速度较快,适台 MCS-51 的任何工作方式 ,在读过程中不会对 Pn 锁存器及端口引脚状态有任何干扰,是三种方法中最好的。