韩彩霞
(江汉大学文理学院,湖北 武汉 430056)
我们通过如下实例来说明P0口使用中需要注意的问题。
如:在51单片机的P 0.7上接开关,P2.3上接LED,开关控制LED的点亮和熄灭(开关闭合,LED点亮;开关断开,LED熄灭)。电路如图1所示。主程序如下:
#include
sbit K1=P0^7;
sbit LED=P2^3;
voidmain(void)
{while(1)
{if(K1==0)
{LED=1; //灯亮
}
else{LED=0; //灯灭
}
}
}
图1 开关控制LED图(不接上拉电阻)
把上述程序在KeilC软件中进行编译没有错误后,生成HEX文件。然后进行proteus软件仿真。仿真结果如图2所示。
图2 开关控制LED仿真图(不接上拉电阻)
由图2(a)可以看出,当开关断开时P0.7引脚电平为灰色显示,表示是高阻抗状态(这里可以把它看作是低电平)。由图2(b)可知:仿真开始后(开关从(a)图变化到(b)图的状态)无论开关断开或闭合,LED的状态都没有变化,也就是说开关根本没有控制LED的点亮或熄灭。
下面我们把图1改成图3的形式,即在P0.7引脚上外接一个上拉电阻R1,程序没有变化,同样进行如上的proteus软件仿真,仿真结果如图3(a)、(b)所示。
图3 开关控制LED仿真图(接上拉电阻)
由图3(a)可以看出,当开关断开时P0.7引脚旁电平为红色显示,表示为高电平。由图3(b)可知:仿真开始后(开关从(a)图变化到(b)图的状态)开关断开,LED熄灭;开关闭合,LED点亮。实现了开关闭合或断开控制LED点亮或熄灭。
出现上面的情况是由于51单片机P0口内部结构决定的。
因为51单片机P0口内部没有上拉电阻,所以图2(a)中P0.7为高阻抗状态(低电平),要使开关断开P0.7呈现高电平,须外接上拉电阻,如图3所示,这样在P0口才能有真正的高电平输出。
那么是不是使用P0口时都需要外接上拉电阻呢?通过以下分析来说明这个问题。
我们把图3改成如图4所示的形式。同样进行proteus软件仿真,仿真结果如图4所示。
图4 开关控制LED 仿真图
由图4(a)和(b)可以看出,无论开关断开还是闭合,LED的状态始终没有。这是因为开关断开或闭合引脚P0.7始终是高电平。我们把图4中P0.7口上接的电阻去掉,得到图5的形式。同样进行proteus软件仿真,仿真结果如图5所示。
图5 开关控制LED仿真图
由图5我们可以看出,开关断开或闭合可以控制LED熄灭或点亮。
从以上分析可知:当使用P0口时,如需要在P0口上出现高电平时(如图3所示),才需要在P0口上外接上拉电阻。
这一点在使用51单片机P0口时一定要注意的,否则就会出现问题。
但是,对于51单片机的其它3个I/O口来说,因为它们自身内部有上拉电阻,所以就不存在以上的情况。
我们通过以下实例来分析问题。如图6所示,在P2口的P2.0和2.1分别接有开关K1和K2,在P3口的P3.0和P3.1分别接有LED1和LED2,实现把开关K1、K2的四种状态(K1、K2全闭合;K1闭合、K2断开;K1断开、K2闭合;K1、K2全断开)反应到LED1和LED2上。(即开关闭合对应的LED点亮,开关断开对应的LED熄灭)程序如下所示。
#include
voidmain(void)
{char a;
a=P2; //把开关状态读入,送给变量a(P2口作为输入口使用)
a=a&03; //保留开关状态(P2.0和P2.1)
P3=~a;//开关状态取反后送给LED(P3口作为输出口使用)}
图6 两个开关控制两个LED仿真图
由图6(在此只给出开关K1、K2的两种状态)可知:开关K1、K2的闭合断开可以控制LED1、LED2的点亮和熄灭。
把图6改成图7的形式,在P2口的P2.0和2.1分别接有开关K1和K2,在P2口的P2.2和P2.3分别接有LED1和LED2,同样完成上述的功能,即把开关K1、K2的四种状态反应到LED1和LED2上。同时,程序改成如下的形式。
#include
voidmain(void)
{char a;
a=P2; //把开关状态读入,送给变量a(P2口作为输入口使用)
a=a&03; //保留开关状态(P2.0和P2.1)
P2=~a<<2;//开关状态取反,左移两位送给LED(P2口作为输出口使用)
}
图7 两个开关控制两个LED仿真图
由图7(在此只给出开关K1、K2的两种状态)可知:开关K1、K2的闭合断开不能控制LED1、LED2的点亮和熄灭。
出现以上情况是由于在图7中P2口既作为输入口使用又作为输出口使用时,由于P2口内部结构决定,需要先给P2口输入“1”,然后才能正确读入开关的状态。我们把上述程序修改成如下形式:
#include
voidmain(void)
{char a;
P2=0xff;//P2口作为输入口使用时,先写1
a=P2; //把开关状态读入,送给变量a(P2口作为输入口使用)
a=a&03;//保留开关状态(P2.0和P2.1)
P2=~a<<2;//开关状态取反,左移两位送给LED(P2口作
为输出口使用)
}
即在程序开始增加语句:P2=0xff;(P2口作为输入口使用时,先输入1),同样进行仿真后就可以完成上述的要求。
由以上分析可知:当并行I/O口P2口同时作为输入/输出口使用时,需要先给其写“1”,但是如只作为输入或输出口使用时,不需要这样的处理。
这里只分析了51单片机P2口的情况,对于51单片机其它的I/O口是同样的,当同时作为输入/输出口时,需要先给其写“1”。
[1]彭伟.单片机C语言程序设计实例100例[M].北京:电子工业出版社,2011.
[2]姜志海.单片机的C语言程序设计及应用[M].北京:电子工业出版社,2011.
[3]梅丽凤.单片机原理及接口技术(修订本)[M].北京:清华大学出版社,2011.
[4]邹益民.单片机C语言教程[M].北京:中国石化出版社,2011.
[5]张蕊.C语言程序设计教程.武汉:华中科技大学出版社,2009.