微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 8051单片机I/0口的读写

8051单片机I/0口的读写

时间:11-26 来源:互联网 点击:
前两天看资料,见到关于I/O口作为输入时,要先输出1的说明,有点迷惑。今天特意查了一些资料,费了半天劲,虽然还没有完全弄明白,但也算有所收获,下面就列出来,以便将来查询并进一步补充。

1、作为I/O口使用时,输入和输出原理

作I/O口使用时,在控制信号的作用下,与门关闭,V1截止,同时多路开关打向下边,与锁存器的反向输出端Q^相连。

输出数据时,“写锁存器”端发出脉冲,将“内部总线”上的数据写入输出锁存器,由Q^端控制V2,从而在引脚上反应出相应的状态。此种应用时P0端口各引脚应外接上拉电阻

输入数据时,分为读引脚和读端口两种方式。读端口的位置就是上图中的“读锁存器”,而读引脚则是上图中的“读引脚”。至于何时读端口,何时读引脚则是根据不同的指令由硬件自动完成的,这不需要我们操心。

附:

读端口的指令

读端口的指令为端口内容取反这样的“读-修改-写”指令。资料称:下面这些的指令才有Read-Modify-Write功效

ANL (logical AND, e.G., ANL P1,A)

ORL (logical OR, e.g., ORL P2,A)

XRL (logical EX-OR, e.g., XRL P3,A)

JBC (jump if bit = 1 and clear bit, e.g., JBC P1.1, LABEL)

CPL (complement bit, e.g., CPL P3.0)

INC (increment, e.g., INC P2)

DEC (decrement, e.g., DEC P2)

DJNZ (decrement and jump if not zero, e.g., DJNZ P3, LABEL)

MOV PX.Y,C(move carry bit to bit Y ofPORTX)

CLR PX.Y(clear bit Y ofPORTX)

SETB PX.Y(set bit Y ofPORTX)

读引脚的指令

如下所示,读之前应先将端口置1,即先输出1,修改锁存器的内容为1。

MOV A, P1

MOV 20H, P1

MOV R0, P1

MOV @R0, P1

2、为什么读之前要先写1?

从上图可知,如果不对端口置1,端口锁存器原来的状态有可能为0,Q端为0,Q^为1,加到场效应管极的信号为1,该场效应管就导通对地呈现低阻抗,此时即使引脚上输入的信号为1也会因端口的低阻抗而使信号拉低,使得外加的1信号读入后不一定是1,若先执行置1操作则可以使场效应管截止,引脚信号直接加到三态缓冲器中,实现正确的读入。

3、实际应用

P0、P1、P2、P3作I/0口使用时,如果要从外部读取数据,读取之前应先将端口置1。因初始化时,四个I/O均被初始化为0xFF,所以若端口在整个程序过程中无输出时,即输出锁存器的状态始终为1,则读数据时可不用手动置1。(附:参考引脚内部结构图可知,纵使锁存器D口数据在变(内部数据线),只要时钟触发端clk没有触发信号,锁存器中的内容永远都不会改变,也就是说,不管外部引脚信号如何变,也不管执行过多少次读引脚操作,端口锁存器中的内容是不会发生变化的。那么,端口内容何时变化?答曰:只要执行过一次输出,端口内容必为输出值,因为端口就是输出的数据锁存器。)

而当端口实际应用时要不停地同外部数据交换时,即又有输出又有读入时,如单片机与存储器24C16通过IIC总线相连,SCL总是由单片机输出可不用考虑,而SDA则可通过单片机向外发数据,又可以从外部读数据,假若之前发送的最后一位数据为0时,此时若再读数据,因为锁存器的状态仍为0,则之后立即读数据时就有可能出错。所以实际操作时,在发送数据代码之后,总会有一个单片机主动将SDA拉高的指令,之后再读数据时才不会出问题。(本人浅见,不一定正确)

而当P0与P2口作总线使用与外部并口连接时,应该就不会有上面的问题,因为从上图可知,当作总线使用时,在控制信号的作用下,与门导通,同时多路开关通过反向器与“地址/数据总线”连接,此时V1与V2的驱动电路形成反相,形成推拉式电路。在这种情况下输出时,可直接驱动电路,不需要接上拉电阻(因为V1导通)。而输入时,直接读引脚即可,不需置1。(因为输入时,地址/数据线上没有数据,V2应该截止(我认为的,此处存疑)。

P1_0=!P1_0在KEIL中编译后的反汇编指令为CPL 1.0;从上面所述可知为读端口指令(读-修改-写),所以可以在C中直接使用,如用作看门狗的清除脉冲和LED灯的闪烁等。

读端口指令似乎是要对内部的端口寄存器(P0~P4)进行改写时才进行的,所以说要先读端口锁存器状态,改写完后同时有锁存器输出。而读引脚指令没有改写寄存器。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top