1. 程式人生 > >微控制器小白學步系列(二十) IO口原理

微控制器小白學步系列(二十) IO口原理

IO口操作是微控制器實踐中最基本最重要的一個知識,本篇花了比較長的篇幅介紹IO口的原理。也是查閱了不少資料,確保內容正確無誤,花了很長時間寫的。IO口原理原本需要涉及很多深入的知識,而這裡盡最大可能做了簡化方便理解。這樣對於以後解決各種IO口相關的問題會有很大的幫助。

IO口等效模型是本人獨創的方法,通過此模型,能有效的降低對IO口內部結構理解的難度。並且經查閱資料確認,這種模型和實際工作原理基本一致。

==========================================

前面說了很多東西,不少人或許已經迫不及待的想要實際操作微控制器了。IO口作為微控制器與外界通訊最主要的手段,是微控制器學習最基本也最重要的一個知識。前面我們程式設計實現了IO口點亮LED的實驗,本篇繼續對IO口相關知識進行介紹。

為了更好的學習IO口操作,有必要了解一下IO口的內部結構和相關概念。這些知識對於後續的學習很有幫助,重點是理解,完全不需要刻意去記。不記得就回來再看看就行了,用得多了自然就記住了。

官方資料(最權威準確)

我們說過,要了解一個晶片,最準確有效的方法,是檢視官方給出的晶片手冊等資料。但是初學微控制器,直接看晶片手冊資料恐怕很難弄明白,尤其是看到一堆英文、陌生的電路、名詞術語,如果是我,一定也會抓狂的。但是這裡我還是給出一張從Atmel官方的《Atmel 8051 Microcontrollers Hardware Manual》中擷取的圖片。

給出這張圖片並不是為了打擊大家學習熱情,而是希望大家能明白,我們所見過的各種微控制器資料到底是怎麼來的,到底是否準確,這一切都可以通過官方資料弄清楚,對於大家以後深入學習一些東西有一定的幫助。

第二功能簡介

上圖正是官方給出的權威的51微控制器IO口結構圖。可以看出,微控制器的四組IO口內部結構各不相同,原因是有些IO口有第二功能,入門篇裡面提到過。

還記得這張管腳圖嗎?括號中標註的就是IO口的第二功能名稱。除了P1以外,每個介面都有第二功能。介紹微控制器系統模組時,我提到51微控制器有預留擴充套件儲存器的介面,正是圖中的P0和P1的第二功能(同時還要用到29、30等管腳)。因為用的不多,涉及知識也比較深入,就不做具體研究了。順便一提,其實這裡我們看到的AD0~AD7,就是用於並行口的。而P3口的第二功能,就包括串列埠等,後面學到了還會具體介紹。

IO口等效電路

由於深入理解IO口的原理涉及到很多電路甚至微機原理相關知識,這裡只做簡化介紹,能滿足絕大多數情況下的需要。作為普通IO口使用時,四個IO口的工作原理基本一致。

下面的圖是從前面圖中的P1電路中裁剪出來的,也是我們需要理解的關鍵。

右邊的P1.X表示P1的一個IO口,如P1.0;電阻右邊寫的英文是內部上拉電阻的意思,之所以叫上拉電阻,是因為電阻的一端接在VCC上。下面的三角形表示接地,相當於GND。除此之外,最關鍵的一個器件是下面這個。

這個器件的本質是電晶體,起到電子開關的作用(如果想深入瞭解,可以學習類比電路相關的知識,或者等到原理篇中介紹)。上面的電路可以大致等效成下圖。注意,這樣的結構只是一個IO口,整個微控制器中有32個這種結構。

圖中的R為阻值10k的上拉電阻,S是由前面的電晶體等效的電子開關。藍色框中的部分在微控制器內部。

S的開關狀態由CPU控制。當用程式設定P1.0管腳為低電平時,電子開關S閉合。實際上電子開關S閉合時,兩端還有很小的電阻。根據分壓原理,P1.0上會有一個很低的電壓,近似0V,已經可以視為低電平了。當設定管腳為高電平時S斷開,P1.0通過10k上拉電阻接到VCC上。如果用電壓表測量,因為電壓表內阻很大,所以可以得出其電壓值為高電平。

IO口的輸出:點亮LED

前面介紹了點亮第一個LED的程式和電路。程式如下:

#include <reg52.h>

sbit LED = P1^0;

void main()

{

    LED = 0;

    while(1);

}

電路關鍵部分如下,VCC通過1k電阻連線到LED正極,LED負極接到P1.0口:

在微控制器執行LED=0的時候,電子開關S就由CPU控制而閉合,P1.0上輸出低電平。電流通過1k電阻和LED流入P1.0,再經過S流入GND,LED兩端有合適的電壓於是點亮。結合微控制器內部IO口等效電路,整個電路如下圖

灌電流與拉電流

在上面的例子中,P1.0輸出低電平點亮LED。能不能反過來,P1.0輸出高電平點亮LED呢?我們可以考慮電路連線成下面這樣,並在程式中編寫LED=1。

當執行LED=1時,S斷開。電流通過10k上拉電阻R從P1.0流出,並進入LED。由於上拉電阻的阻值太大,電流太小,導致LED不亮,或者亮度很微弱。所以通常不採用這種方法。

這兩種方法,前者電流從外部流入微控制器內部,我們稱之為灌電流接法;後者電流方向相反,稱為拉電流接法。對比可以看出,對於51微控制器,灌電流接法電流較大,拉電流接法由於受到上拉電阻限制,電流較小。

在實際當中灌電流的最大電流也是有限的,因為電子開關S中能通過的電流有限。根據STC官方的晶片手冊,對於STC微控制器,建議單個IO口灌電流建議不超過20mA,所有IO口灌電流之和不超過55mA,否則容易燒壞IO口。而拉電流大小隻有230uA左右。

上拉電阻/下拉電阻/高阻態

拉電流是從上拉電阻流出來的,能否提高拉電流大小呢?答案是可以。我們只需要在微控制器外部再新增一個上拉電阻,就可以增大拉電流,並且能成功點亮LED,如下圖所示。

圖中的電路,相當於R和R0並聯了,整個上拉電阻的阻值減小了。但是這樣做有個缺陷。在這個電路中,當微控制器輸出低電平時,S閉合,此時電流從VCC通過上拉電阻和S流入GND。此時雖然LED熄滅了,但是卻有較大電流通過上拉電阻而浪費掉。所以上拉電阻過大,會導致驅動力不足,而上拉電阻過小,又會在輸出低電平時浪費電能。

上拉電阻的作用是什麼呢?對電路瞭解多一點的人很快能發現,如果沒有上拉電阻,IO口就無法輸出高電平,也就是下圖這樣的。開關閉合時能輸出低電平,但是開關斷開時,P1.0就懸空了,什麼也沒連線。這時IO口的電壓就是不確定的了,這種狀態無法判斷它是低電平還是高電平,叫做高阻態。很巧的是,微控制器的P0口確實就沒有上拉電阻,而其他三組IO口都有上拉電阻。所以當P0輸出高電平,並且沒有外接上拉電阻時,就是高阻態,不能正常輸出高電平。後面我會通過具體例子來讓大家感受一下高阻態。

注:雖然P1.0似乎是同時連線到CPU的IO輸入端了,即圖中寫著“輸入”的綠色箭頭,但是這部分電路只有在讀取管腳輸入的時候才會導通,並且是單向的。

27094082 拷貝.png

上拉電阻的存在,將原本的高阻態轉變成了高電平,也因此得名。和上拉電阻相對應的,還有下拉電阻,區別在於下拉電阻另一端不是連線VCC而是接到GND。

IO口的輸入

IO口之所以叫IO口(IO=Input/Output),意味著它既可以輸出又可以輸入。前面講的都是IO口的輸出,下面講IO口的輸入。IO口的輸出我們通過LED來介紹,而IO口的輸入我們則通過開關來說明。在很多微控制器中,IO的輸入和輸出需要通過電路切換,而對於51微控制器來說,輸入和輸出使用的是同一套電路,也就是上面我們分析的電路。

圖中的S0是一個單刀雙擲開關,往上切換可以將P1.0接到VCC,往下切換可以接到GND。讀取時CPU會通過特定電路獲取圖中橙色導線上的電平。我們想要實現的效果是,讓CPU讀取P1.0埠的電平,從而獲得開關S0的狀態。

當S斷開時,CPU通過獲取P1.0上的電平可以知道外部開關S0的狀態,從而執行相應的操作。

而S閉合時,S0往下切換,P1.0確實是低電平。而S保持閉合且S0往上切換時,VCC通過S0和S直接接到GND就短路了。此時電子開關S通過大量電流,可能會燒壞微控制器。於是我們添加了電阻R0。S仍然保持閉合,S0往上切換。此時P1.0仍然是低電平,於是CPU無法判斷外部開關S0的狀態,如下圖。

總結起來就是在讀取IO口電平時,應先設定輸出高電平(即斷開S),再讀取資料。這個規則適用於所有IO口。

類似的,還可以讀取單刀單擲開關(或按鍵開關)的狀態,讀取前先設定輸出高電平,電路圖如下。

上面這種電路需要依賴上拉電阻才能工作。P0口由於沒有上拉電阻,需要在外部新增一個上拉電阻(因為如果沒有上拉電阻,並且S和S0都斷開時,IO口變成高阻態,讀取的電平結果不確定,於是無法正確判斷S0的開關狀態)。

雙向IO口/準雙向IO口

標準雙向IO口的特點有兩條:

1、在輸出模式下,可以輸出高低電平;

2、在輸入模式下,如果沒有接外部電路,應呈現高阻態。

對於51微控制器的P1、P2、P3口,由於有內部上拉電阻,輸入模式下不可能出現高阻態,所以稱之為準雙向IO口。而P0口作為IO口工作時,如果不加上拉電阻就無法輸出高電平;而加了上拉電阻,輸入時又不會出現高阻態,所以也是準雙向IO口。

備註1:51微控制器的P0口如果工作在第二功能狀態下,則是雙向IO口。初學時具體原理不需要研究的很透徹,下面一段對此進行分析,僅供有興趣的讀者參考。

對照官方的完整IO口結構圖,P0口內部有上下兩個電晶體。當P0口工作在IO口模式下,上面那個電晶體斷開,可以直接忽略,前面的等效電路就沒有考慮上面那個電晶體。而當P0口工作在第二功能狀態下,兩個電晶體都可以工作。如果上面的電晶體斷開,下面的導通,就輸出低電平;反之上面的導通下面的斷開,就輸出高電平並且不需要上拉電阻;如果兩個電晶體都斷開,則可以作為輸入,並且在沒有外界電路時呈現高阻態。所以是雙向IO口。

備註2:關於雙向IO口和準雙向IO口的概念存在一定爭議,這裡的介紹綜合了網上多方面的觀點,被多數人所接受。

線與邏輯

如果把兩個微控制器IO口連線在一起會發生什麼現象呢?下面就是我們的電路圖。

當設定兩個IO口都輸出低電平,即S和S1都閉合時,總體是低電平;而當設定其中一個IO口輸出低電平另一個輸出高電平時,即S或S1閉合,此時兩個IO口上都會呈現低電平。只有當P1.0、P1.1都輸出高電平,即S和S1都斷開時,才會呈現高電平。

可以簡單表述成:兩個IO口連線在一起,僅當P1.0與P1.1都設定輸出高電平時,兩者接線上才會呈現高電平。這就是所謂的線與邏輯。不僅是兩個,如果是很多的這樣的IO口連在一起,只有所有IO都設定輸出高電平,接線上才會呈現高電平。線與邏輯會在後面的矩陣鍵盤中使用到。

總結

最後總結起來,主要就是下面幾點。內容有點多,但是實際上常用的只有其中的幾點。再次強調,不需要刻意去記,明白了原理,用多了自然就記住了。

1、灌電流比拉電流能通過更大的電流;點亮LED一般用灌電流方式

2、上拉電阻越小,拉電流輸出能力越大,但輸出低電平時越費電

3、讀取IO口前,要先設定輸出高電平

4、P0作為輸出,需外接上拉電阻

5、按鍵開關作為輸入時,接在IO口和GND之間,另外需要上拉電阻

6、51微控制器的四個IO口在普通IO狀態下都是準雙向口

7、51微控制器IO口遵從線與邏輯

=======================================================

《微控制器小白學步》系列教程(原名《微控制器入門指南》)介紹

本系列教程從最基本的入門知識開始,逐步深入介紹微控制器系統設計,內容包括:
1、入門篇:微控制器等基本概念、各種電子設計基本知識
2、思想篇:微控制器/計算機系統設計的工程思想
3、學習篇:微控制器學習過程、方法和技巧,以51微控制器為例介紹,並推廣到其他微控制器
4、應用篇:遵循規範的工程方法,設計微控制器系統例項(計劃設計的系統有:計算器、電子錶、密碼鎖、簡易手機,具體看有沒有時間再確定)
5、原理篇:從類比電路、數位電路開始,逐步深入介紹微控制器/計算機系統原理,並自行設計簡易的CPU(由於個人水平有限,這部分沒有把握寫好,具體內容視情況而定)

教程特點

1、技術知識點全面,從入門到精通

包含了各種基本知識,尤其是對微控制器基本概念的介紹、為什麼要用微控制器等,在很多同類書籍教程中都被忽略了。同時也包含了一些深入的知識,包括原理篇考慮對微控制器的基本原理進行介紹,有助於深入理解微控制器。

本系列教程以51微控制器為例進行介紹。通過51介紹完微控制器的基本知識,我會再把430進行簡要介紹,尤其是對比兩者之間的優缺點,讓大家很快感受到430的巨大優勢,而學習51正好為快速瞭解430打下了堅實的基礎。

2、除了微控制器知識,還有思想、方法、技巧的介紹

本系列教程中,介紹微控制器各種模組程式設計知識的主要是學習篇,而學習篇只是整個教程的一部分。在學習篇中我會貫穿各種方法技巧,如何理解一些模組功能,怎麼看時序圖,嚴格遵守工程思想進行程式設計,程式發生了錯誤怎麼除錯等等。而在思想篇中會總體介紹很多重要的思想,為後面的學習做好準備工作。

3、知識先後順序的設計

微控制器學習過程中,涉及大量的知識,而且很多知識之間相互依賴,關聯很強。

本系列教程對知識的先後順序進行比較明確的規劃,盡最大可能符合人的認知過程。但是實際規劃時發現,無論怎麼調整知識的順序,總有一些知識之間相互依賴,關係複雜。例如開始講IO口的時候肯定會提到暫存器,而暫存器這個詞的理解,需要深厚的背景知識。但是這些背景知識在沒有進行實踐的時候也很難理解。

初學者常常就會在這樣的地方感覺疑惑不解,不知所措。而每次遇到類似這樣的知識,我會向初學者指出,應該如何對待。這個知識是應該自己去學習補充,還是等到學完原理篇再做理解,而現在又應該怎麼去看待這個名詞。

4、語言通俗易懂

本系列教程力求語言通俗易懂,而不會用一堆新手不懂的詞語去解釋另一個不懂的詞語。但是受限於個人語言表達能力,可能有些地方表述的比較繁瑣,或者不清楚,希望大家能夠幫忙指出。

其他問題

如果覺得我寫的對你有幫助,歡迎多多反饋,包括寫的不正確、不合理、不太明白都可以指出來,這樣方便我對其進行完善。