2.8.1 P0口的结构
P0口由一个输出锁存器、一个转换开关MUX、两个三态输入缓冲器、输出驱动电路和一个与门、一个反相器组成,如图2-24所示。图中控制信号C的状态决定转换开关的位置。当C=0时,开关处于图中所示位置;当C=1时,开关拨向反相器输出端位置。
图2-24 P0口的位结构
1.P0口用作通用I/O口(C=0)
当系统不进行外部程序存储器扩展时,P0可用作通用I/O口。在这种情况下,单片机硬件自动使控制C=0,MUX开关接向锁存器的反相输出端。另外,与门输出的“0”使输出驱动器的上拉场效应管VT1处于截止状态。因此,输出驱动级工作在需要外接上拉电阻的漏极开路方式。
P0作为输出口时,CPU执行P0口的输出指令,内部数据总线上的数据在“写锁存器”信号的作用下由D端进入锁存器,经锁存器的反相端送至场效应管VT2,再经VT2反相,最终在P0.X引脚出现的数据与内部总线的数据正好一致。
P0作为输入口时,数据可以读自口的锁存器,也可以读自口的引脚。这时要根据输入操作采用的是“读锁存器”指令还是“读引脚”指令来决定。
CPU在执行“读-修改-写”类输入指令时(如ORL P0,A),内部产生的操作信号是“读锁存器”,使得锁存器Q端数据进入内部数据总线,在与累加器A进行逻辑运算之后,结果送回P0的口锁存器并出现在引脚上。读口锁存器可以避免因外部电路原因使原口引脚的状态发生变化而造成的误读(例如,用一根口线驱动一个晶体管的基极,在晶体管的射极接地的情况下,当向口线写“1”时,晶体管导通,并把引脚的电平拉低到0.7 V。这时若从引脚读数据,会把状态为“1”的数据误读为“0”。若从锁存器读,则不会读错)。
CPU在执行MOV类输入指令时(如MOVA,P0),内部产生的操作信号是“读引脚”。这时一定要注意,在执行该类输入指令前要先给锁存器写入“1”,目的是使场效应管VT2截止,使引脚处于悬浮状态,可以作为高阻抗输入。否则,P0口在作为输入方式之前曾向锁存器输出过“0”,VT2导通会使引脚钳位在“0”电平上,使输入高电平“1”无法读入。所以,P0口在作为通用I/O口时,属于准双向口。
2.P0口用作地址/数据总线(C=1)
当系统进行外部程序存储器扩展(即)或进行外部程序存储器扩展(外部RAM传送使用MOVX@DPTR或MOVX @Ri类指令)时,P0口用作地址/数据总线。在这种情况下,单片机内硬件自动使C=1,MUX开关接向反相器的输出端,这时与门的输出由地址/数据总线的状态决定。
CPU在执行输出指令时,低8位地址信息和数据信息分时地出现在地址/数据总线上。若地址/数据总线的状态为“1”,则场效应管VT1导通、VT2截止,引脚状态为“1”;若地址/数据总线的状态为“0”,则场效应管VT1截止、VT2导通,引脚状态为“0”。因此,P0.X引脚的状态正好与地址/数据线的信息相同。
CPU在执行输入指令时,首先低8位地址信息出现在地址/数据总线上,P0.X引脚的状态与地址/数据总线的地址信息相同。然后,CPU自动地使转换开关MUX拨向锁存器,并向P0口写入FFH,同时“读引脚”信号有效,数据经缓冲器进入内部数据总线。
由此可见,P0口作为地址/数据总线时是一个真正的双向口。