一、P0口

一、P0口

P0口的口线逻辑电路如图2-16所示。

图2-16 P0口某位逻辑结构

电路中包含一个数据输出锁存器、两个三态数据输入缓冲器、一个数据输出的驱动电路和一个输出控制电路。输出驱动电路由上拉场效应管(FET)T1和驱动场效应管T2组成,其工作状态受控制电路“与”门、反相器和转换开关MUX控制。当对P0口进行写操作时,由锁存器和驱动电路构成数据输出通路。由于通路中已有输出锁存器,因此数据输出时可以与外设直接连接,而不需要再加数据锁存电路。

考虑到P0口既可以作为通用的一般I/O口进行数据输入/输出,也可以作为单片机系统的地址/数据线使用,为此在P0口的电路中有一个转换开关MUX。在CPU控制端C的作用下,转换开关MUX可以分别接通锁存器输出端或反相器的地址/数据线。

(一)P0口作为一般I/O口使用

当89C51单片机组成的系统没有外扩存储器,CPU对片内存储器和I/O口读/写(执行MOV指令或=1时执行MOVC指令)时,硬件电路自动使控制线C=0,封锁“与”门,使T1管截止。开关MUX处于拨向输出端位置,它把输出级T2与锁存器的端接通。同时,因场效应管T1处于截止状态,输出级漏极开路,所以,应外接上拉电阻,才能有高电平输出。

1.P0口用作输出口

当CPU向端口输出数据(执行输出指令)时,写脉冲加在D锁存器的CP端,这样,内部总线输出的数据经D触发器取反后出现在端上,又经输出级T2反相,出现在P0端口上。这是一般的数据输出情况。

2.P0口用作输入口

当P0口作为输入口使用时,应区分“读引脚”和“读端口”这两种情况。为此,在端口电路中有两个用于读入的三态缓冲器。

所谓“读引脚”就是读芯片引脚的数据,这时使用锁存器下方的数据缓冲器2,由“读引脚”信号把缓冲器2打开,使端口引脚上的数据经缓冲器2通过内部总线读进来。使用传送指令(如“MOV A,P0”)进行读端口操作都是属于这种情况。

“读端口”是指通过锁存器上面的缓冲器1读锁存器Q端的状态。在端口已处于输出状态的情况下,Q端与引脚信号的状态是一致的,这样安排的目的是为了适应对端口进行“读—修改—写”操作指令的需要。

89C51有几条输出指令功能特别强,属于“读—修改—写”指令。例如,执行一条“ANL P0,A”指令的过程是:CPU不直接读引脚上的数据,而是先读P0口D锁存器中的数据;当“读锁存器”信号有效时,三态缓冲器1开通,Q端数据送入内部总线和累加器A中的数据进行逻辑“与”操作;结果送回P0端口锁存器。此时,引脚的状态和锁存器的内容(Q端状态)是一致的。

对于“读—修改—写”指令,直接读锁存器而不是读端口引脚是为了避免错读引脚上的电平信号。例如,用一根端口引脚线去驱动一个晶体管的基极,当向此端口线写1时,三极管导通,并把端口引脚上的电平拉低,这时CPU如要从引脚读取数据,则会把此数据(应为“1”)错读为“0”;若从锁存器读取而不是读引脚,则读出的应该是正确的数值“1”。

当指令中的目的操作数是端口或端口的某位时,常使用表2-9所列出的指令。

表2-9 I/O端口常用指令

另外,从图2-16中还可以看出,在读入端口引脚数据时,由于输出驱动T2并接在引脚上,如果T2导通,就会将输入的高电平拉成低电平,从而产生误读。所以,在进行输入操作前,应先向端口锁存器写入“1”,使锁存器=0,从而使T2截止,故称为准双向端口。又因为控制线C=0,因此T1也截止,故引脚处于悬浮状态,作为高阻抗输入。

(二)P0口作为地址/数据总线使用

P0口作为单片机系统的地址/数据总线使用_时,比作为一般I/O口应用要简单。当CPU对片外存储器读/写(执行MOVX指令或=0时执行MOVC指令)时,内部硬件电路自动使控制线C=1,开关MUX拨向反相器输出端。这时,P0口可作为地址/数据总线端口分时使用,并且又分为两种情况。

1.P0口用作输出口

在扩展系统中用P0口分时输出低8位地址和数据信息,此时由CPU内部发出控制信号,打开控制电路的“与”门,并使开关MUX拨向反相器输出端,这样CPU内部地址/数据信息经反相器与驱动场效应管T2栅极反向接通输出。

由于P0口内无内部上拉电阻,其输出驱动器上的上拉场效应管T1仅限于访问外部存储器时输出“1”(地址或数据)时使用;其余情况下,上拉场效应管T1截止。这时由于输出驱动电路上、下两个FET处于反相,形成推拉式电路结构(T1导通时上拉,T2导通时下拉),使负载能力大为提高。所以只有P0口的输出可驱动八个LS型TTL负载。

2.P0口用作输入口

这种情况是在“读引脚”信号有效时打开输入缓冲器2,使数据信号直接从引脚通过输入缓冲器2进入内部总线。

综上所述,P0口既可作为一般I/O端口(用89C51/8751时)使用,又可作地址/数据总线使用。作I/O输出时,输出级属开漏电路,必须外接10kΩ上拉电阻,才有高电平输出;作I/O输入时,必须先向对应的锁存器写入“1”,使T2截止,不影响输入电平。当P0口被地址/数据总线占用时,就无法再作I/O口使用了。