89C51单片机的P0~P3口不是标准意义的双向口 ,他只是准双向口
你可以对照着P0口的结构图看这段话,向端口写1,就是向锁存器写1,
也就是让其口输出FF,为什么,是这样的,给锁存器写1,那么锁存器
的反向端就输出0,那么和它相接的MOS管也就在截止状态,也就是呈高
阻态,这样P0口上数据就会从读引脚的三态缓冲器上正确的输入,如果
不写1,那么锁存器上次锁存的可能为0,那么反向端有可能出现1,这样
和反向端相接的MOS管就倒通,也就是直接拉到地,那么不管你P0口上输
入什么信号都会拉成低电平,输入就错了
双向口与准双向口的区别主要是:准双向口I/O口操作时做数据输入时需
要对其置1,否则若前一位为低电平,后一位输入的电平为高则MOS管拉不起来
导致出错。而双向口则不需要做此动作,因为双向口有悬浮态。
准双向口只能有效的读取0,而对1则是采用读取非零的方式,就是读入的时候要先向接口上写1,然后再读。真正的双向口正如其名,就是真正的双向io不需要任何预操作可直接读入读出
若不先对端口置1 ,端口锁存器中原来状态有可能为0,加到输入驱动场效应管栅极的信号为1,该场效应管就导通,对地呈现低阻抗,这是即使引脚上输入的是1的信号,也会因端口的低阻抗而使信号变低,使得外加的1信号读入后不一定是1,若先执行置1操作,则可以驱动场效应管截止,引脚信号直接加到三态缓冲器,实现正确的读入,
这是芯片内部结构决定的,当需要该引脚读外部电平时先置1
楼上从基本的原理上回答的比较完整。但有些人包括我之前都不是特别的理解。
个人的理解:
1、准双向一般只能用于数字输入输出,输入时为弱上拉状态,端口只有两种状态:高或低:很好理解!
2、准双向口读外部状态前,要先锁存为1,才能读到外部正确的状态:不太理解!
(1) 什么叫锁存为1?? 就是通俗的写1吧?
我的开关直接接端口和地,之所以端口设为准双向并写1(跟悬空脚的正确处理方法完全相同!!),判断开关状态(查询非中断)只用到“if某端口=0/1”就好,没搞其他代码,也没有"等待两个时钟_nop_()",。是因为这样既简单可靠又省电,而且还省掉了外接上/下拉电阻。 若设置为“高阻输入”去判断按键状态,还得额外增加合适阻值的上拉、下拉或分压电阻,STC内部已有好几种上拉电阻可用,不是自找麻烦么。
(2) 什么叫“读取外部正确的状态”??
只用于没外接上/下拉电阻的按键或开关状态之列的识别么?
如I2C外设的2脚连接及其读写,我感觉只设双向就好,无需也不用写1,实际我也没写1,也没有"等待两个时钟_nop_()",读写都没有发现问题,是因为I2C等外设的数据线上已经有上拉电阻了么?
那么;下面例程中的“双向口读写操作”中的读部分,不知道究竟该怎么准确应用?P00 = 1读取端口前先使能内部弱上拉电阻还等待两个时钟?
P00 = 1; //读取端口前先使能内部弱上拉电阻
_nop_(); //等待两个时钟
_nop_(); //
CY = P00; //读取端口状态
...
把图片复制下用画图工具看很清晰,里面有端口功能