韓彩霞
(江漢大學(xué)文理學(xué)院,湖北 武漢 430056)
我們通過如下實(shí)例來說明P0口使用中需要注意的問題。
如:在51單片機(jī)的P 0.7上接開關(guān),P2.3上接LED,開關(guān)控制LED的點(diǎn)亮和熄滅(開關(guān)閉合,LED點(diǎn)亮;開關(guān)斷開,LED熄滅)。電路如圖1所示。主程序如下:
#include
sbit K1=P0^7;
sbit LED=P2^3;
voidmain(void)
{while(1)
{if(K1==0)
{LED=1; //燈亮
}
else{LED=0; //燈滅
}
}
}
圖1 開關(guān)控制LED圖(不接上拉電阻)
把上述程序在KeilC軟件中進(jìn)行編譯沒有錯誤后,生成HEX文件。然后進(jìn)行proteus軟件仿真。仿真結(jié)果如圖2所示。
圖2 開關(guān)控制LED仿真圖(不接上拉電阻)
由圖2(a)可以看出,當(dāng)開關(guān)斷開時P0.7引腳電平為灰色顯示,表示是高阻抗?fàn)顟B(tài)(這里可以把它看作是低電平)。由圖2(b)可知:仿真開始后(開關(guān)從(a)圖變化到(b)圖的狀態(tài))無論開關(guān)斷開或閉合,LED的狀態(tài)都沒有變化,也就是說開關(guān)根本沒有控制LED的點(diǎn)亮或熄滅。
下面我們把圖1改成圖3的形式,即在P0.7引腳上外接一個上拉電阻R1,程序沒有變化,同樣進(jìn)行如上的proteus軟件仿真,仿真結(jié)果如圖3(a)、(b)所示。
圖3 開關(guān)控制LED仿真圖(接上拉電阻)
由圖3(a)可以看出,當(dāng)開關(guān)斷開時P0.7引腳旁電平為紅色顯示,表示為高電平。由圖3(b)可知:仿真開始后(開關(guān)從(a)圖變化到(b)圖的狀態(tài))開關(guān)斷開,LED熄滅;開關(guān)閉合,LED點(diǎn)亮。實(shí)現(xiàn)了開關(guān)閉合或斷開控制LED點(diǎn)亮或熄滅。
出現(xiàn)上面的情況是由于51單片機(jī)P0口內(nèi)部結(jié)構(gòu)決定的。
因?yàn)?1單片機(jī)P0口內(nèi)部沒有上拉電阻,所以圖2(a)中P0.7為高阻抗?fàn)顟B(tài)(低電平),要使開關(guān)斷開P0.7呈現(xiàn)高電平,須外接上拉電阻,如圖3所示,這樣在P0口才能有真正的高電平輸出。
那么是不是使用P0口時都需要外接上拉電阻呢?通過以下分析來說明這個問題。
我們把圖3改成如圖4所示的形式。同樣進(jìn)行proteus軟件仿真,仿真結(jié)果如圖4所示。
圖4 開關(guān)控制LED 仿真圖
由圖4(a)和(b)可以看出,無論開關(guān)斷開還是閉合,LED的狀態(tài)始終沒有。這是因?yàn)殚_關(guān)斷開或閉合引腳P0.7始終是高電平。我們把圖4中P0.7口上接的電阻去掉,得到圖5的形式。同樣進(jìn)行proteus軟件仿真,仿真結(jié)果如圖5所示。
圖5 開關(guān)控制LED仿真圖
由圖5我們可以看出,開關(guān)斷開或閉合可以控制LED熄滅或點(diǎn)亮。
從以上分析可知:當(dāng)使用P0口時,如需要在P0口上出現(xiàn)高電平時(如圖3所示),才需要在P0口上外接上拉電阻。
這一點(diǎn)在使用51單片機(jī)P0口時一定要注意的,否則就會出現(xiàn)問題。
但是,對于51單片機(jī)的其它3個I/O口來說,因?yàn)樗鼈冏陨韮?nèi)部有上拉電阻,所以就不存在以上的情況。
我們通過以下實(shí)例來分析問題。如圖6所示,在P2口的P2.0和2.1分別接有開關(guān)K1和K2,在P3口的P3.0和P3.1分別接有LED1和LED2,實(shí)現(xiàn)把開關(guān)K1、K2的四種狀態(tài)(K1、K2全閉合;K1閉合、K2斷開;K1斷開、K2閉合;K1、K2全斷開)反應(yīng)到LED1和LED2上。(即開關(guān)閉合對應(yīng)的LED點(diǎn)亮,開關(guān)斷開對應(yīng)的LED熄滅)程序如下所示。
#include
voidmain(void)
{char a;
a=P2; //把開關(guān)狀態(tài)讀入,送給變量a(P2口作為輸入口使用)
a=a&03; //保留開關(guān)狀態(tài)(P2.0和P2.1)
P3=~a;//開關(guān)狀態(tài)取反后送給LED(P3口作為輸出口使用)}
圖6 兩個開關(guān)控制兩個LED仿真圖
由圖6(在此只給出開關(guān)K1、K2的兩種狀態(tài))可知:開關(guān)K1、K2的閉合斷開可以控制LED1、LED2的點(diǎn)亮和熄滅。
把圖6改成圖7的形式,在P2口的P2.0和2.1分別接有開關(guān)K1和K2,在P2口的P2.2和P2.3分別接有LED1和LED2,同樣完成上述的功能,即把開關(guān)K1、K2的四種狀態(tài)反應(yīng)到LED1和LED2上。同時,程序改成如下的形式。
#include
voidmain(void)
{char a;
a=P2; //把開關(guān)狀態(tài)讀入,送給變量a(P2口作為輸入口使用)
a=a&03; //保留開關(guān)狀態(tài)(P2.0和P2.1)
P2=~a<<2;//開關(guān)狀態(tài)取反,左移兩位送給LED(P2口作為輸出口使用)
}
圖7 兩個開關(guān)控制兩個LED仿真圖
由圖7(在此只給出開關(guān)K1、K2的兩種狀態(tài))可知:開關(guān)K1、K2的閉合斷開不能控制LED1、LED2的點(diǎn)亮和熄滅。
出現(xiàn)以上情況是由于在圖7中P2口既作為輸入口使用又作為輸出口使用時,由于P2口內(nèi)部結(jié)構(gòu)決定,需要先給P2口輸入“1”,然后才能正確讀入開關(guān)的狀態(tài)。我們把上述程序修改成如下形式:
#include
voidmain(void)
{char a;
P2=0xff;//P2口作為輸入口使用時,先寫1
a=P2; //把開關(guān)狀態(tài)讀入,送給變量a(P2口作為輸入口使用)
a=a&03;//保留開關(guān)狀態(tài)(P2.0和P2.1)
P2=~a<<2;//開關(guān)狀態(tài)取反,左移兩位送給LED(P2口作
為輸出口使用)
}
即在程序開始增加語句:P2=0xff;(P2口作為輸入口使用時,先輸入1),同樣進(jìn)行仿真后就可以完成上述的要求。
由以上分析可知:當(dāng)并行I/O口P2口同時作為輸入/輸出口使用時,需要先給其寫“1”,但是如只作為輸入或輸出口使用時,不需要這樣的處理。
這里只分析了51單片機(jī)P2口的情況,對于51單片機(jī)其它的I/O口是同樣的,當(dāng)同時作為輸入/輸出口時,需要先給其寫“1”。
[1]彭偉.單片機(jī)C語言程序設(shè)計實(shí)例100例[M].北京:電子工業(yè)出版社,2011.
[2]姜志海.單片機(jī)的C語言程序設(shè)計及應(yīng)用[M].北京:電子工業(yè)出版社,2011.
[3]梅麗鳳.單片機(jī)原理及接口技術(shù)(修訂本)[M].北京:清華大學(xué)出版社,2011.
[4]鄒益民.單片機(jī)C語言教程[M].北京:中國石化出版社,2011.
[5]張蕊.C語言程序設(shè)計教程.武漢:華中科技大學(xué)出版社,2009.