p0口有三个功能:
1、外部扩展存储器时,当做数据(data)总线(如图1中的d0~d7为数据总线接口)
2、外部扩展存储器时,当作地址(address)总线(如图1中的a0~a7为地址总线接口)
3、不扩展时,可做一般的i/o使用,但内部无上拉电阻,作为输入或输出时应在外部接上拉电阻(后面将详细介绍)。
第三条提到了一个“上拉电阻”的名词,那么上拉电阻又是一个什么东东呢?他起什么作用呢?都说了是电阻那当然就是一个电阻啦,当作为输入时,上拉电阻将其电位拉高,若输入为低电平则可提供电流源;所以如果p0口作为输入时,处在高阻抗状态,只有外接一个上拉电阻才能有效。
(注:上图只是p0口的一位,也就是说p0口有8个相同的这样的结构)
由上图看出每个p0口都有这些元件:一个锁存器,两个三态输入缓冲器和一个输出驱动电路组成。在访问外部存储器时,p0是一个真正的双向口,当p0输出地址/数据信息时,cpu内部法控制电平“1”来打开上面的与门,又使模拟开关mux把地址/数据信息经过反相器和t1接通(我们称上面的场效应晶体管fet为t1,下面的场效应管fet为t2);输出的地址/数据信息既通过与门去驱动t1,又通过反相器去驱动t2,是两个fet构成推拉输出电路;
1.当p0口作为外部扩展存储器的数据地址总线时:
若地址数据信息为“0”,那么这个信号就使得t1截止,使t2导通(经过反反相器作用使得t2接收到的信号为“1”,根据场效应晶体管的特性,t2导通),若t2导通,那么t2的上下两个n极就导通,而发射极(下面的n极)接地信号则为“0”,这样p0口就相当于接收到了“0”信号;
若地址数据信息输入“1”,则该信号使t2截止,使t1导通,在t1导通情况下,t1的上下n极导通,使得vcc与p0相同,从而输出高电平,即“1”信号;
若从p0口输入信号,信号从引脚通过输入缓冲器进入内部总线;
2.当p0口作为一般i/o口使用时:
cpu内部发布控制信号“0”,封锁与门,使得t1截止,同时使模拟开关mux把锁存器的非q端与t2端的栅极接通;
在p0口作为输出时,由于非q端和t2的倒相作用,那么内部总线上的信息与到达p0口上的信息是同相的,只要写脉冲加到锁存器的cl端,内部总线上的信息就会p0的引脚上;
但是由于此时t2为漏极开路输出,所以要外接上拉电阻。
当p0作为输入时,由于该信号既加到t2又加到下面的三态缓冲器。现在我们假设我们刚刚输出的信号为“0”,也就是输入锁存器的数据为“0”,经过非q达到t2使t2导通,这样p0引脚上的信号就被t2钳在“0”电平上,这样就使输入的“1”无法读入。那么我们就必须在输入信号前,应该先向锁存器q端写“1”,非q就为“0”,使t2截止,这就是所谓的“准双向口”的解释。但是在访问片外存储器时,cpu会自动向锁存器q写入“1”,所以对用户而言p0口作为数据/地址总线时,是一个真正的双向口。
下面我们说一下为什么要上拉电阻,就是下面这位兄弟抱着的那个东东。
由于p0口内部没有上拉电阻,是开漏的,不管它的驱动能力多大,相当于它是没有电源的,需要外部的电路提供,绝大多数情况下p0口是必需加上拉电阻的。作为一般的i/o口时,当p0口用来驱动pnp(如上图4所示)管子的时候,就不需要上拉电阻,因为此时的低电平有效;当p0口用来驱动npn管子的时候,就需要上拉电阻的,因为此时只有当p0为1时候,才能够使后端导通。其实说白了上拉就是将不确定的信号通过一个电阻钳位在高电平!电阻同时起限流作用!上拉电阻就是从电源高电平引出的电阻接到输出端。
分两种情况讨论:
第一种,如果电平用oc(集电极开路,ttl)或od(漏极开路,cmos)输出,那么不用上拉电阻是不能工作的, 这个很容易理解,管子没有电源就不能输出高电平了。 (这个就可以解释我们这里的原因)
第二种,如果输出电流比较大,输出的电平就会降低(这是电路中已经有了一个上拉电阻的情况下,但是电阻太大,压降太高),就可以用上拉电阻提供电流分量, 把电平“拉高”。(就是并一个电阻在ic内部的上拉电阻上, 让它的压降小一点)。其实这些都是按需要,工作在线性范围的上拉电阻不能太小,当然也会用这个方式来实现门电路电平的匹配。
总结并提高下,51系列单片机的p0口作为通用i/o口使用时,内部输出电路为od(漏极开路,cmos),必须外接上拉电阻才能有高电平输出;而p1、p2、p3口内部输出电路中有上拉电阻故不需要接上拉电阻(这里的不需要接上拉电阻是相对而言的,若遇到第二种情况,就需要适当加一个上拉电阻,来减小压降)。