学习单元一 解剖单片机I/O口

在学习情景一的学习单元三中,通过学习单片机控制LED指示灯的电路模型对单片机如何控制外部器件有了一个比较浅显、比较粗糙的感性认识。例如,我们说单片机内部的电子开关状态(闭合还是断开)决定了单片机引脚输出的是低电平0还是高电平1,而电子开关的状态是由指令控制的。下面通过解剖单片机P0、P1、P2和P3口的内部结构来进一步深入了解电子开关的结构和控制原理。

一、I/O口的内部结构和工作原理

1.P1口

从前面的学习我们了解到单片机的四个端口中只有P1口没有第二种功能,而P0口、P2口和P3口都有第二种功能。由此看来,好像只有P1口比较“单纯”,比较“简单”。事实的确如此,P1口的内部结构最简单,用途也单一,仅作数据I/O口使用。P1口结构如图3-1所示。

图3-1 P1口的内部结构

图中“引脚P1.X”的意思是这个结构代表P1.0~P1.7任意一个引脚,所以P1口每一个引脚结构都是相同的。P1口内部主要由D型锁存器(方形,也称P1.X锁存器)、两个三态门缓冲器(三角形)、场效应管T和内部上拉电阻组成。D型锁存器也称为D锁存器,是一种常用的锁存器,在“写锁存器”信号的时序控制下,D型锁存器输出端Q与输入端D的信号相同,而输出端与D的信号相反。例如“内部总线”向输入端D输入1,当“写锁存器”信号到来时,输出端Q也输出1,输出0。而D端输入0,则Q端和端输出分别为0和1。

两个三态门缓冲器作信号的缓冲,并通过“读锁存器”和“读引脚”两个控制信号来使能三态门。例如“内部总线”向锁存器的输入端D送入一个数据1,在“写锁存器”信号到来后,锁存器的输出端Q也输出一个1,如果这时“读锁存器”信号到来,对应的三态门打开,数据1就能通过缓冲器而进入“内部总线”上。

场效应管的工作原理与三极管类似,它也有3个引脚:栅极G、漏极D和源极S。当栅极G为高电平时,场效应管导通,引脚P1.X相当于与地线相连,于是P1.X口上为低电平;反之栅极G为低电平时场效应管截止,P1.X口通过上拉电阻与Vcc相连,所以P1.X口为高电平。这里场效应管相当于一个反相器。

P1口作为数据I/O口使用时,有输出、读引脚和读锁存器三种工作方式。三种工作方式由相应的单片机指令区分。

(1)输出工作方式(数据输出)。当P1口作数据输出时,实质是单片机引脚输出高电平或低电平,一般执行数据输出指令如“MOV P1, #data”,单片机的CPU发出“写锁存器”信号加在P1锁存器时钟端CL,与单片机内部数据总线相连的D端数据取反后出现在Q端,经场效应管反相后出现在P1引脚上,即P1引脚上电平状态与P1锁存器输出数据“#data”保持一致。例如,当输出数据“#data”的某个数据位“bit”(在单片机指令中,数据“#data”为1个字节,代表8个二进制数据“bit”)为“1”时,该数据位出现在内部数据总线上,于是相应的P1.X口为高电平;反之当数据位bit为“0”时,相应的P1.X口为低电平。

(2)读引脚工作方式(数据输入)。单片机在读引脚数据时,实质是单片机读取引脚电平状态(高电平或低电平),一般执行以I/O口为源操作数的指令如“MOV A, P1”,此时CPU发出“读引脚”信号加在对应的三态门控制端,三态门打开,P1.X引脚上的数据(高电平1或低电平0)经三态门进入内部数据总线,并送到累加器A,于是可以通过指令判断累加器A的数据来判断P1.X引脚的输入信号是高电平1还是低电平0。此时P1.X引脚输入数据不经过P1锁存器,因此输入时无锁存功能。

注意:当P1口执行读引脚操作时,必须保证场效应管截止。若场效应管导通,则从P1引脚上输入的信号被场效应管短路。因此,为使场效应管截止,必须先用输出指令向P1锁存器写“1”,使为“0”,效应管截止。由于在读引脚数据时还必须附加这样一个预备动作,P1被称为“准双向”I/O口。向P1锁存器写“1”可用“MOV P1, #0FFH”、“ORL P1, #0FFH”等指令。

(3)读锁存器工作方式。单片机有一些“读—修改—写”指令,简称“读—改—写”指令,如上述“ORL P1, #0FFH”指令。该指令的执行过程分三步:首先CPU发出“读锁存器”信号加在对应的三态门控制端,三态门打开,P1锁存器中的数据经三态门送到内部数据总线,然后在ALU(Arithmetic Logic Unit,算术逻辑单元,简称ALU)中进行算术逻辑运算,最后将运算结果送回P1锁存器。除上述ORL指令外,这类指令还有ANL、XRL、JBC、CPL、SET等,执行这类指令时CPU直接读锁存器而不是读端口引脚。采用读锁存器方式是因为从端口引脚上读入的数据不一定能真正反映锁存器的状态,二者在某些情况下并不完全一致。

2.P3口

学习了P1口的内部结构和工作原理后,接下来再看稍微复杂一些的P3口内部结构,如图3-2所示。

图3-2 P3口的内部结构

P3口与P1口结构相似。从前面表2-1知道P3口除了具有通用数据I/O口功能以外还有第二种功能,所以P3口比P1口多出了一个“第二输出信号”和“第二输入信号”。“第二输出信号”和P3锁存器的输出端Q通过一个与非门及场效应管与外部引脚连接。这样,如果“内部总线”向P3锁存器D端输入1时,根据与非门的逻辑关系,与非门的输出端(即场效应管的栅极G)则反相跟随“第二输出信号”。由于场效应管的功能也是一个反相器,因而经过两次反相后,引脚P3.X上电平状态与“第二输出信号”始终保持一致。同样的道理,当“第二输出信号”为1时,引脚P3.X上电平状态与P3锁存器的数据始终保持一致。

(1)通用数据I/O口。P3口作为通用I/O口使用时,其内部的“第二输出信号”保持为高电平,此时P3口的用途和使用方法与P1口相同。

(2)第二种功能。当P3口的某一位作为第二功能输出使用时,CPU将该位锁存器置“1”,使与非门只受“第二输出信号”的控制,“第二输出信号”经与非门和场效应管二次反向后输出在该位的引脚上。

当P3口的某一位作为第二功能输入使用时,该位的“第二输出信号”和锁存器自动置“1”,场效应管截止,该位引脚上的信号经缓冲器送入“第二输入信号”线,CPU在“读引脚”之前就把第二功能的输入信号读走。

3.P0口

在前面的学习中已了解到P0口有两种功能,一是作通用数据I/O口,二是复用数据总线/低8位地址总线。图3-3是P0口的内部结构,与P1口相比其特点是多出了一个多路开关MUX,这个开关由一个内部“控制信号”控制,以选通地址或数据。图中的场效应管T1、T2组成输出驱动器,与门、非门和多路开关MUX构成控制电路。对于初学者来说,理解与记忆这些复杂的端口结构有点困难,所以现在只需要有个大致的印象即可,以后接触多了就比较容易掌握。

图3-3 P0口的内部结构

(1)通用数据I/O口。P0口作为通用输入/输出口使用时,相应的指令使“控制信号”电平为“0”,这有两个作用:一是封锁与门,使与门输出为“0”,场效应管T1截止,输出级为开漏输出;二是多路开关MUX接通P0锁存器端和场效应管T2。此时,P0口的用途和使用方法与P1口类似。

需要注意的是,在P0口作数据输出时,由于T1截止,输出级处于开漏状态,要使“1”信号正常输出,必须外接上拉电阻,上拉电阻的阻值一般为4.7~10kΩ

(2)复用数据/地址总线。在总线扩展应用中,CPU访问外部存储器时,P0口分时复用数据总线/低8位地址总线。此时,相应的指令使“控制信号”电平为“1”,多路开关MUX接通非门输出端和场效应管T2,同时打开与门。

当P0口用作地址或数据总线输出时,地址或数据信号同时作用于与门和反相器,分别驱动T1和T2,由此在引脚上得到相同的地址或数据信号。例如,若“地址/数据”信号为“1”,则与门输出“1”,T1导通,同时反相器输出“0”,T2截止,P0口引脚输出“1”。若“地址/数据”信号为“0”,则与门输出“0”,T1截止,同时反相器输出“1”,T2导通,P0口引脚输出“0”。

当P0口用作数据总线输入时,CPU使T1和T2均截止,引脚上的数据经三态门进入内部数据总线。

需要注意的是,地址线是8位一起自动输出的,不能像I/O口线那样逐位定义。

4.P2口

P2口与P0口有类似的功能和结构,一是作通用数据I/O口,二是作地址总线高8位。图3-4是P2口的内部结构,其特点也是多出了一个多路开关MUX,这个开关由一个内部“控制信号”控制,以选通地址或数据。

图3-4 P2口的内部结构

(1)通用数据I/O口。P2口作为通用输入/输出口使用时,多路开关接通P2锁存器Q端。此时,P2口的用途和使用方法与P1口相同。

(2)地址总线。在总线扩展应用中,多路开关MUX接通“地址信号”,此时P2口输出地址总线的高8位,并与P0口输出的低8位地址一起构成16位的地址线,从而可以在单片机外部寻址64K的程序存储器或数据存储器。

同样需要注意的是,高8位地址线是8位一起自动输出的,不能像I/O口线那样逐位定义。

从以上4个I/O口的结构图中得知,P1、P2、P3口内部具有上拉电阻,而P0口是开漏结构(由两个场效应管组成)。在应用P0~P3口时,要注意以下几点:

(1)每一个I/O口引脚都可以独立地做输入口或输出口使用。P0口做I/O口使用要加上拉电阻,而其余口可不加上拉电阻。

(2)在总线扩展应用中,P0口用于低8位地址/数据总线,P2口用于高8位地址总线。但P0和P2作地址或数据总线连接外部存储器时不能同时再独立地做输入口或输出口。

(3)任何一个I/O口作为输入端口使用时,必须让I/O口内部的场效应管处于截止状态,这样从I/O口输入的信号才能正常地从输入缓冲器中被内部总线读走。所以需要用指令把对应I/O口的锁存器写“1”,以关闭场效应管。

(4)P0口内部没有上拉电阻,只有一个上拉用的场效应管结构。它作为输出端口时为开漏结构。由于没有上拉电阻,端口电平不会被拉低,所以是一个纯粹的双向口。P1、P2和P3口内部虽然都有上拉电阻,但端口电平仍然能被外部输入的低电平信号拉低,所以P1、P2和P3口也被称为“准双向口”。

(5)单片机复位时P0~P3锁存器各位数据均为“1”,因为单片机的复位操作会把高电平“1”写到每一个I/O口的锁存器中。

(6)P0~P3口的驱动能力都有限。P0口能驱动8个LS TTL门电路,而P1、P2、P3只能驱动4个。

(7)P3口常用于第二功能。P0口和P2口的第二功能很少用。

二、I/O口的抽象结构

图3-5所示为P1.X口的抽象结构。这个示意图极大简化了图3-1的实际结构,甚至模糊了实际结构中的相互关系。例如图3-1中输入缓冲电路和输出驱动电路分别由缓冲器和场效应管担任,而到了图3-5时,输入缓冲和输出驱动都被简单说成“驱动”,并且这两部分与锁存器的关系也被简化了许多。

图3-5 P1.X口的抽象结构

这样做行吗?当然可以。还是再比较一下图3-1和图3-5。前者显示出4根数据线:读锁存器、内部总线、写锁存器和读引脚。这4根数据线与单片机内部结构中的总线相连。于是在图3-5中就用一根“总线”来表示这4根数据线,说明锁存器与单片机内部结构中的某总线相连。很明显,当一根线表示实际存在的多根线时,这条线被加粗了。这样,以后凡是遇到一根加粗的线条,应该立刻知道它代表多根线。因为图3-5中的总线代表了实际中的4根数据线,所以,为节省时间、提高效率,在国际单片机系统开发会议上,只需要说“引脚P1.X的状态通过总线读入单片机中”就可以了。既然国际单片机系统开发会议上青睐一个比图3-1更模糊的、更抽象的说法,于是本书也不再讨论像图3-1那么详细的结构了,取而代之,以图3-5为抽象模型来讨论。

图3-5只描述了P1口中的某一个I/O口的抽象模型。在系统开发中,通常以整个P1口为讨论对象,所以,进行进一步的抽象,得到了图3-6所示的P1口抽象结构。其中使用了更粗的线来表示总线,线上的双向箭头表示该总线可以双向传输数据。P1口的8个I/O引脚保留用单独的双向数据线表示。

图3-6 P1口的抽象结构