|
出自:西漂sky的博客
沒錯,跟所有教程一樣,第一個學(xué)習(xí)的外設(shè)是LED燈。其實在下起初也很奇怪為什么所有教程的第一個實驗不是流水燈就是點亮一個LED,F(xiàn)在就個人認(rèn)為,主要原因就是LED是一個只要一個輸出引腳就可以驅(qū)動的外設(shè)元件,而且現(xiàn)象明顯,容易進一步引發(fā)學(xué)習(xí)者的學(xué)習(xí)興趣。與其叫“點亮一個LED燈”,不如叫“輸出端口的操作”。上一篇講過,單片機輸出的方式就是把IO口輸出引腳的電壓按要求改變。IO口引腳的電壓在理想的情況只能為兩個值——要么在Vcc附近,要么在GND附近。在電壓在Vcc附近的情況被視為邏輯1,電壓在GND附近的情況被視為邏輯0。
大部分的開發(fā)板/學(xué)習(xí)板的LED外設(shè)如下圖:

Vcc指電源,R2與R3分別是限流電阻,最右側(cè)LED1與LED2分別直接與IO口的引腳相連。
現(xiàn)在想想如何讓這兩個LED發(fā)光,我們知道LED全稱為發(fā)光二極管,當(dāng)正負極之間的電壓超過一定值時,發(fā)出光亮。這個定值一般在2~3V左右。LED1與LED2的電壓只能在Vcc附近和GND附近——也就是邏輯1或邏輯0。我們分類討論一下:當(dāng)LED1為邏輯1時,發(fā)光二級管的兩端電壓幾乎相同,不會導(dǎo)通,也就不會發(fā)光;當(dāng)LED1為邏輯0時,發(fā)光二極管正負極間的正向電壓較大,在電阻選取合適的情況下超過那個定值,也就會發(fā)光。于是,我們得出一個等效——LED發(fā)光=單片機輸出端口輸出邏輯0;LED不發(fā)光=單片機輸出端口輸出邏輯1。
于是,我們知道若想要D1發(fā)光,只要使標(biāo)號為LED1的輸出端口輸出邏輯0就可以了。我們假設(shè)標(biāo)號LED1的輸出端口是P1的最低位P1^0。
第一種方法,就是對IO口P1整體進行操作。若想讓最低位輸出0,那么P1要輸出的值就是1111_1110(不考慮P1的其他位)16進制就是0xFE。那么如上一章所說,只要一句語句“P1=0xFE;”就可以了。
第二種方法,就是單獨對P1的最低位操作。其本質(zhì)就是“P1^0=0;”這樣一句。但是這樣寫編譯器會報錯。原因是編譯并不認(rèn)識P1^0是個什么玩意,在進行對IO口的位單獨操作前,必須告訴編譯器P1^0是什么。于是有了這樣一個定義:
sbit P10 = P1^0;
這條語句一般是寫在main函數(shù)之外的。這個玩意看上去有點像宏定義#define,作用也像,不過作用的原理不同。sbit表示對位定義,“P10”是在下給P1最低位取得名字,這個名字可以隨便取,只要不與關(guān)鍵字沖突就行!癙1^0”表示IO口P1的第0位。這個是有固定格式的,IO口位的固定格式為“Px^y”,x是指第幾個IO口,y是指IO口的第幾位。再舉個例子:“sbitABC=P3^5;”這條語句就是把IO口P3的第5位命名為ABC。
命名后,你起的名字編譯器就可以識別了。在“sbitP10 =P1^0;”語句之后,再寫“P10=0;”,編譯器就知道你想讓被命名為P10的輸出引腳輸出邏輯0了。
現(xiàn)在來一個完整的程序:
#include<reg52.h>
sbit LED1=P1^0;
void main(void)
{
LED1=0;
for(;;);
}
想必第2和5行的意思已經(jīng)解釋的很清楚了,4和7行是大括號。第1行是頭文件,這個頭文件就像C語言中的stdio.h一樣,一般都會用到。第6行是一個死循環(huán),阻止程序結(jié)束的。對于單片機的程序,我們是不希望結(jié)束的,若是沒有無限運行的部分,需要在最后加一個死循環(huán)(想知道沒有死循環(huán)有什么后果......去掉死循環(huán)上單片機跑一下就知道了)。就這樣,IO口的基本操作就結(jié)束了,也就是說,用Px=0xyz或sbit定義+對位操作的方法,就可以自由的操作IO口的輸出了。
(如需轉(zhuǎn)載,在下感激不敬,也請注明出處)
|
|