双向口与准双向口的区别主要是:准双向口I/O口操作时做数据输入时需要对其置1,否则若前一位为低电平,后一位输入的电平为高则MOS管拉不起来导致出错。而双向口则不需要做此动作,因为双向口有悬浮态。
准双向口就是做输入用的时候要有向锁存器写1的这个准备动作,所以叫准双向口。
真正的双向口不需要任何预操作可直接读入读出。
1:准双向一般只能用于数字输入输出,输入时为弱上拉状态(约50K上拉),端口只有两种状态:高或低。
2:双向除用于数字输入输出外还可用于模拟输入输出,模拟输入时端口通过方向控制设置成为高阻输入状态。双向端口有三种状态:高、低或高阻。
3:初始状态和复位状态下准双向口为1,双向口为高阻状态.有带些比较器的单片机,比较器的输入端只能做在双向口,不能做在准双向口.所以软件设计的第一步就是对 I/O 口的设置。
总结了一下,所谓"准"的意思,是指具有某种功能,但是又有点差别。准双向口,是说具备双向工作的能力,但是在用之前要先进行些设置(端口置1操作)。而双向口,在使用时不需要这个置1操作,可以直接双向使用(实际上是单片机自动完成了这个置1操作,只有A\\D模式才有这个功能)!所以没有"准"这个字。类比的还有8086是完全的16位cpu,而8088叫"准"16位cpu因为其数据线是8位,内核是16位的,虽然具备了16位cpu,但与16位完全体还是有点差别!"准"字就是说" 有那样的特征,但并不完全是有细微区别"的意思
点击链接——转载百度知道
点击链接——转载21IC
C51的说明书上说:”Because Ports 1, 2, and 3 have fixed internal pullups, they are sometimes called quasi-bidirectional
ports. When configured as inputs, they pull high and source current (IIL) when externally pulled low.??Port 0, on the other
hand, is considered truly bidirectional, because it floats when configured as an input. "
翻译是:因为P1、2、3有固定的内部上拉电阻,所以有时称它们为准双向口。当用做输入时被拉高,低则要靠外部电路拉低。而P0则是真双向口,因为作为输入时它是悬浮的(因为没有上拉电阻)。
不是很清晰易懂.
我很纳闷,这么重要的一个问题,为什么教科书、老师都没有好好的讲清楚,包括我自己经历的也是这样.我也是一直被这个问题捆饶了很久
.我说说我的看法:
像上面说的一样,"准"就是"基本上"的意思.
其实重点在P0口.
P0口是双向指的是它被用作地址/数据端口时,只有在这个时候,P0口才处于两个开关管推挽状态,当两个开关管都关闭时,才会出现高阻状态.
当P0口用于一般I/O口时,内部接Vcc的那个开关管是与引脚(端口)脱离联系的,这个时候,只有拉地的那个开关管起作用,P0口作为输出,是必须外接上拉电阻的,不然就无法输出高电平;如果P0口作为输入,则必须先对端口写1,使拉地的开关管断开,这个时候,如果不接上拉电阻,则是高阻状态,就是一个双向口,如果接上拉电阻,则本身输出高电平,对输入信号的逻辑无影响(注意是对逻辑无影响,对实际参数有无影响我不确定,但是我认为是有的).
双向与准双向,根本原则是双向包含了高阻这个状态,而不在于是否需要先写1或者不写,P1~P3口因为有内部上拉电阻,因此无论如何不是双向;P0口内部无上拉电阻,在处于数据/地址功能时,自动完成3态的转换,是双向,处于一般I/O口时,如果不接外部上拉,而且先向端口写了1,那么就处于高阻状态,此时,它也是一个人为的双向口,这与它处于地址/数据功能时的自动双向有区别,以及与P1~P3处于输入时输出锁存器为1是有区别的。
单片机的P0~P3端口进行输入时为什么要设置为1?
给锁存器写1,那么锁存器的反向端就输出0,那么和它相接的MOS管也就在截状态,也就是呈高阻态,这样P0口上数据就会从读引脚的三态缓冲器上正确的输入,如果不写1,那么锁存器上次锁存的可能为0,那么反向端有可能出现1,这样和反向端相接的MOS管就倒通,也就是直接拉到地,那么不管你P0口上输入什么信号都会拉成低电平,输入就错了.
为什么我输入没设置1,还是正确的呢?
一般情况下,单片机复位后P0-P3端口默认值为1,如果仅作为输入,中途不改变,无需我们先设置1.
总结了一下,所谓"准"的意思,是指具有某种功能,但是又有点差别。准双向口,是说具备双向工作的能力,但是在用之前要先进行些设置(端口置1操作)。而双向口,在使用时不需要这个置1操作,可以直接双向使用(实际上是单片机自动完成了这个置1操作,只有A\\D模式才有这个功能)!所以没有"准"这个字。类比的还有8086是完全的16位cpu,而8088叫"准"16位cpu因为其数据线是8位,内核是16位的,虽然具备了16位cpu,但与16位完全体还是有点差别!"准"字就是说" 有那样的特征,但并不完全是有细微区别"的意思
重点:
C51双向P0与P1,2,3,口这3个准双向口比,多了一个高阻态输入的“悬浮”态,这是由于P0口作为数据总线使用时,多个数据源都挂在数据总线上,当P0口不与其他数据源打交道时,需要与数据总线高阻“悬浮”隔离,而准双向I/O口则无高阻态,另外,准双向做通用I/O的输入口使用时,一定要向该口写“1”。
栗子:: STC15W配置IO口按键检测
#include "STC15W.h"
#include "intrins.h"
//选择内部晶振 30MHZ
sbit KEY1 = P3^2;//根据原理图,KEY1对应的IO口
sbit KEY2 = P3^3;//根据原理图,KEY2对应的IO口
sbit KEY3 = P3^6;//根据原理图,KEY3对应的IO口
sbit LED2 = P4^6;//看原理图,LED2对应的IO口
sbit LED1 = P4^7;//看原理图,LED1对应的IO口
void Delay100ms(void);//声明延时函数
void main(void)
{
P0M1=0;P0M0=0;P1M1=0;P1M0=0;
P2M1=0;P2M0=0;P3M1=0;P3M0=0;
P4M1=0;P4M0=0;P5M1=0;P5M0=0;//上电初始化所有IO口为普通IO
KEY1 = 1;//51单片机的普通IO口若要读取外部状态,必须先输出“1”
KEY2 = 1;//51单片机的普通IO口若要读取外部状态,必须先输出“1”
KEY3 = 1;//51单片机的普通IO口若要读取外部状态,必须先输出“1”
while(1)
{
if(KEY1 == 0)//第一次检测到 KEY1 按下
{
Delay100ms();//软件延时100ms,用于消抖
if(KEY1 == 0)//再次检测到按下信号,则认为本次按下有效
{
LED2 = 0;//点亮LED2
}
}
if(KEY2 == 0)
{
Delay100ms();
if(KEY2 == 0)
{
LED1 = 0;//点亮LED1
}
}
if(KEY3 == 0)
{
Delay100ms();
if(KEY3 == 0)
{
LED1 = 1;//关闭LED1
LED2 = 1;//关闭LED2
}
}
}
}
//软件延时
void Delay100ms(void) //@30.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 11;
j = 67;
k = 102;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}