GPIO的各種模式
GPIO管腳可以被配置為多種工作模式,其中有3種比較常用:高阻輸入、推挽輸出、開漏輸出
1. 高阻輸入(Input)

圖1.1 GPIO高阻輸入模式結構示意圖
為減少資訊傳輸線的數目,大多數計算機中的資訊傳輸線采用總線形式,即凡要傳輸的同類資訊都在同一組傳輸線,且資訊是分時傳送的。在計算機中一般有三組總線,即資料總線、位址總線和控制總線。為防止資訊互相幹擾,要求凡挂到總線上的寄存器或存儲器等,它的輸入輸出端不僅能呈現0、1兩個資訊狀态,而且還應能呈現第三個狀态----高阻抗狀态,即此時好像它們的輸出被開關斷開,對總線狀态不起作用,此時總線可由其他器件占用。三态緩沖器即可實作上述功能,它除具有輸入輸出端之外,還有一控制端。
如圖1.1所示,為GPIO管腳在高阻輸入模式下的等效結構示意圖。這是一個管腳的情況,其它管腳的結構也是同樣的。輸入模式的結構比較簡單,就是一個帶有施密特觸發輸入(Schmitt-triggered input)的三态緩沖器(U1),并具有很高的輸入等效阻抗。施密特觸發輸入的作用是能将緩慢變化的或者是畸變的輸入脈沖信号整形成比較理想的矩形脈沖信号。執行GPIO管腳讀操作時,在讀脈沖(Read Pulse)的作用下會把管腳(Pin)的目前電平狀态讀到内部總線上(Internal Bus)。在不執行讀操作時,外部管腳與内部總線之間是隔離的。
2. 推挽輸出(Output)
圖1.2 GPIO推挽輸出模式結構示意圖
推挽輸出原理:在功率放大器電路中大量采用推挽放大器電路,這種電路中用兩隻三極管構成一級放大器電路,兩隻三極管分别放大輸入信号的正半周和負半周,即用一隻三極管放大信号的正半周,用另一隻三極管放大信号的負半周,兩隻三極管輸出的半周信号在放大器負載上合并後得到一個完整周期的輸出信号。
推挽放大器電路中,一隻三極管工作在導通、放大狀态時,另一隻三極管處于截止狀态,當輸入信号變化到另一個半周後,原先導通、放大的三極管進入截止,而原先截止的三極管進入導通、放大狀态,兩隻三極管在不斷地交替導通放大和截止變化,是以稱為推挽放大器(armjishu.com)。
如圖1.2所示,為GPIO管腳在推挽輸出模式下的等效結構示意圖。U1是輸出鎖存器,執行GPIO管腳寫操作時,在寫脈沖(Write Pulse)的作用下,資料被鎖存到Q和/Q。T1和T2構成CMOS反相器,T1導通或T2導通時都表現出較低的阻抗,但T1和T2不會同時導通或同時關閉,最後形成的是推挽輸出。在推挽輸出模式下,GPIO還具有回讀功能,實作回讀功能的是一個簡單的三态門U2。注意:執行回讀功能時,讀到的是管腳的輸出鎖存狀态,而不是外部管腳Pin的狀态。
3. 開漏輸出(OutputOD)
圖1.3 GPIO開漏輸出結構示意圖
如圖1.3所示,為GPIO管腳在開漏輸出模式下的等效結構示意圖。開漏輸出和推挽輸出相比結構基本相同,但隻有下拉半導體T1而沒有上拉半導體。同樣,T1實際上也是多組可程式設計選擇的半導體。開漏輸出的實際作用就是一個開關,輸出“1”時斷開、輸出“0”時連接配接到GND(有一定内阻)。回讀功能:讀到的仍是輸出鎖存器的狀态,而不是外部管腳Pin的狀态。是以開漏輸出模式是不能用來輸入的。
開漏輸出結構沒有内部上拉,是以在實際應用時通常都要外接合适的上拉電阻(通常采用4.7~10kΩ)。開漏輸出能夠友善地實作“線與”邏輯功能,即多個開漏的管腳可以直接并在一起(不需要緩沖隔離)使用,并統一外接一個合适的上拉電阻,就自然形成“邏輯與”關系。開漏輸出的另一種用途是能夠友善地實作不同邏輯電平之間的轉換(如3.3V到5V之間),隻需外接一個上拉電阻,而不需要額外的轉換電路。典型的應用例子就是基于開漏電氣連接配接的I2C總線。
4. 鉗位二極管
GPIO内部具有鉗位保護二極管,如圖1.4所示。其作用是防止從外部管腳Pin輸入的電壓過高或者過低。VDD正常供電是3.3V,如果從Pin輸入的信号(假設任何輸入信号都有一定的内阻)電壓超過VDD加上二極管D1的導通壓降(假定在0.6V左右),則二極管D1導通,會把多于的電流引到VDD,而真正輸入到内部的信号電壓不會超過3.9V。同理,如果從Pin輸入的信号電壓比GND還低,則由于二極管D2的作用,會把實際輸入内部的信号電壓鉗制在-0.6V左右。
圖1.4 GPIO鉗位二極管示意圖
假設VDD=3.3V,GPIO設定在開漏模式下,外接10kΩ上拉電阻連接配接到5V電源,在輸出“1”時,我們通過測量發現:GPIO管腳上的電壓并不會達到5V,而是在4V上下,這正是内部鉗位二極管在起作用。雖然輸出電壓達不到滿幅的5V,但對于實際的數字邏輯通常3.5V以上就算是高電平了(armjishu.com)。
圖1.5 解決開漏模式上拉電壓不足的方法
如果确實想進一步提高輸出電壓,一種簡單的做法是先在GPIO管腳上串聯一隻二極管(如1N4148),然後再接上拉電阻。參見圖1.5,框内是晶片内部電路。向管腳寫“1”時,T1關閉,在Pin處得到的電壓是3.3+VD1+VD3=4.5V,電壓提升效果明顯;向管腳寫“0”時,T1導通,在Pin處得到的電壓是VD3=0.6V,仍屬低電平
漏極開路的分析
電力場效應管又名電力場效應半導體分為結型和絕緣栅型,通常主要指絕緣栅型中的MOS型(Metal Oxide Semiconductor FET),簡稱電力MOSFET(Power MOSFET),結型電力場效應半導體一般稱作靜電感應半導體(Static Induction Transistor——SIT)。
A:我們先來說說集電極開路輸出的結構。集電極開路輸出的結構如圖1所示,右邊的那個三極管集電極什麼都不接,是以叫做集電極開路(左邊的三極管為反相之用,使輸入為“0”時,輸出也為“0”)。對于圖1,當左端的輸入為“0”時,前面的三極管截止(即集電極C跟發射極E之間相當于斷開),是以5V電源通過1K電阻加到右邊的三極管上,右邊的三極管導通(即相當于一個開關閉合);當左端的輸入為“1”時,前面的三極管導通,而後面的三極管截止(相當于開關斷開)。
我們将圖1簡化成圖2的樣子。圖2中的開關受軟體控制,“1”時斷開,“0”時閉合。很明顯可以看出,當開關閉合時,輸出直接接地,是以輸出電平為0。而當開關斷開時,則輸出端懸空了,即高阻态。這時電平狀态未知,如果後面一個電阻負載(即使很輕的負載)到地,那麼輸出端的電平就被這個負載拉到低電平了,是以這個電路是不能輸出高電平的。
再看圖三。圖三中那個1K的電阻即是上拉電阻。如果開關閉合,則有電流從1K電阻及開關上流過,但由于開關閉和時電阻為0(友善我們的讨論,實際情況中開關電阻不為0,另外對于三極管還存在飽和壓降),是以在開關上的電壓為0,即輸出電平為0。如果開關斷開,則由于開關電阻為無窮大(同上,不考慮實際中的漏電流),是以流過的電流為0,是以在1K電阻上的壓降也為0,是以輸出端的電壓就是5V了,這樣就能輸出高電平了。但是這個輸出的内阻是比較大的(即1KΩ),如果接一個電阻為R的負載,通過分壓計算,就可以算得最後的輸出電壓為5*R/(R+1000)伏,即5/(1+1000/R)伏。是以,如果要達到一定的電壓的話,R就不能太小。如果R真的太小,而導緻輸出電壓不夠的話,那我們隻有通過減小那個1K的上拉電阻來增加驅動能力。但是,上拉電阻又不能取得太小,因為當開關閉合時,将産生電流,由于開關能流過的電流是有限的,是以限制了上拉電阻的取值,另外還需要考慮到,當輸出低電平時,負載可能還會給提供一部分電流從開關流過,是以要綜合這些電流考慮來選擇合适的上拉電阻。
如果我們将一個讀資料用的輸入端接在輸出端,這樣就是一個IO口了(51的IO口就是這樣的結構,其中P0口内部不帶上拉,而其它三個口帶内部上拉),當我們要使用輸入功能時,隻要将輸出口設定為1即可,這樣就相當于那個開關斷開,而對于P0口來說,就是高阻态了。
對于漏極開路(OD)輸出,跟集電極開路輸出是十分類似的。将上面的三極管換成場效應管即可。這樣集電極就變成了漏極,OC就變成了OD,原理分析是一樣的。
另一種輸出結構是推挽輸出。推挽輸出的結構就是把上面的上拉電阻也換成一個開關,當要輸出高電平時,上面的開關通,下面的開關斷;而要輸出低電平時,則剛好相反。比起OC或者OD來說,這樣的推挽結構高、低電平驅動能力都很強。如果兩個輸出不同電平的輸出口接在一起的話,就會産生很大的電流,有可能将輸出口燒壞。而上面說的OC或OD輸出則不會有這樣的情況,因為上拉電阻提供的電流比較小。如果是推挽輸出的要設定為高阻态時,則兩個開關必須同時斷開(或者在輸出口上使用一個傳輸門),這樣可作為輸入狀态,AVR單片機的一些IO口就是這種結構。
在平時的電路設計時我們會遇到開漏(open drain)和開集(open collector)的概念,可能大家在念書時就知道其基本的用法,而且在設計中也并未遇到過問題。但是我忽然覺得自己也對這個概念了解的并不系統。于是進行了以下總結: 所謂開漏電路的概念裡提到的“漏”就是指MOS FET的漏極,同理,開集電路中的“集”就是指三極管的集電極,開漏電路就是指以MOS FET的漏極為輸出的電路。一般的正常用法是會在漏極外部的電路添加一個上拉電阻。完整的開漏電路應該由開漏器件和開漏的上拉電阻組成。如下圖中所示:
組成開漏形式的電路有以下幾個特點:
1. 利用外部電路的驅動能力,減少IC内部的驅動。當IC内部MOSFET導通時,驅動電流是從外部的VCC流經R pull-up ,MOSFET到GND。IC内部僅需很下的栅極驅動電流。如圖1。
2. 可以将多個開漏輸出的Pin,連接配接到一條線上。形成“與邏輯”關系。如圖1,當PIN_A、PIN_B、PIN_C任意一個變低後,開漏線上的邏輯就為0了。這也是I2C,SMBus等總線判斷總線占用狀态的原理。
3. 可以利用改變上拉電源的電壓,改變傳輸電平。如圖2, IC的邏輯電平由電源Vcc1決定,而輸出高電平則由Vcc2決定。這樣我們就可以用低電平邏輯控制輸出高電平邏輯了。
4. 開漏Pin不連接配接外部的上拉電阻,則隻能輸出低電平。
5. 标準的開漏腳一般隻有輸出的能力。添加其它的判斷電路,才能具備雙向輸入、輸出的能力。
應用中需注意:
1. 開漏和開集的原理類似,在許多應用中我們利用開集電路代替開漏電路。例如,某輸入Pin要求由開漏電路驅動。則我們常見的驅動方式是利用一個三極管組成開集電路來驅動它,即友善又節省成本。如圖3。
2. 上拉電阻R pull-up的阻值決定了邏輯電平轉換的沿的速度。阻值越大,速度越低功耗越小。反之亦然!
GPIO配置
(1)GPIO_Mode_AIN 模拟輸入
(2)GPIO_Mode_IN_FLOATING 浮空輸入
(3)GPIO_Mode_IPD 下拉輸入
(4)GPIO_Mode_IPU 上拉輸入
這三種輸入電路是用那一種,要根據外圍電路來決定。
所謂高阻,可以簡單了解為輸出端處于浮空狀态(沒有電流流動),其電平随外部電平高低而定,即門電路放棄對輸出端電路的控制。而上拉就是将不确定的信号通過一個電阻嵌位在高電平,電阻同時起限流作用。下拉同理,隻不過上拉是對器件注入電流,下拉是輸出電流。至于弱上拉和強上拉,隻是上拉電阻的阻值不同,沒有什麼嚴格區分。簡言之,上拉就是在端口沒有輸入的情況下,将端口的電平穩定在高電平。
(5)GPIO_Mode_Out_OD 開漏輸出
(6)GPIO_Mode_Out_PP 推挽輸出
(7)GPIO_Mode_AF_OD 複用開漏輸出
(8)GPIO_Mode_AF_PP 複用推挽輸出
GPIO_Speed_10MHz 最高輸出速率10MHz
GPIO_Speed_2MHz 最高輸出速率2MHz
GPIO_Speed_50MHz 最高輸出速率50MHz
1.1I/O口的輸出模式下,有3種輸出速度可選(2MHz、10MHz和50MHz),這個速度是指I/O口驅動電路的響應速度而不是輸出信号的速度,輸出信号的速度與程式有關(晶片内部在I/O口 的輸出部分安排了多個響應速度不同的輸出驅動電路,使用者可以根據自己的需要選擇合适的驅動電路)。通過選擇速度來選擇不同的輸出驅動子產品,達到最佳的噪聲 控制和降低功耗的目的。高頻的驅動電路,噪聲也高,當不需要高的輸出頻率時,請選用低頻驅動電路,這樣非常有利于提高系統的EMI性能。當然如果要輸出較高頻率的信号,但卻選用了較低頻率的驅動子產品,很可能會得到失真的輸出信号。
關鍵是GPIO的引腳速度跟應用比對(推薦10倍以上?)。比如:
Ÿ 對于序列槽,假如最大波特率隻需115.2k,那麼用2M的GPIO的引腳速度就夠了,既省電也噪聲小。
Ÿ 對于I2C接口,假如使用400k波特率,若想把餘量留大些,那麼用2M的GPIO的引腳速度或許不夠,這時可以選用10M的GPIO引腳速度。
Ÿ 對于SPI接口,假如使用18M或9M波特率,用10M的GPIO的引腳速度顯然不夠了,需要選用50M的GPIO的引腳速度。
1.2 GPIO口設為輸入時,輸出驅動電路與端口是斷開,是以輸出速度配置無意義。
1.3在複位期間和剛複位後,複用功能未開啟,I/O端口被配置成浮空輸入模式。
1.4所有端口都有外部中斷能力。為了使用外部中斷線,端口必須配置成輸入模式。
1.5GPIO口的配置具有上鎖功能,當配置好GPIO口後,可以通過程式鎖住配置組合,直到下次晶片複位才能解鎖。
2、推挽輸出與開漏輸出的差別
推挽輸出:可以輸出高,低電平,連接配接數字器件;開漏輸出:輸出端相當于三極管的集電極. 要得到高電平狀态需要上拉電阻才行. 适合于做電流型的驅動,其吸收電流的能力相對強(一般20ma以内).
推挽結構一般是指兩個三極管分别受兩互補信号的控制,總是在一個三極管導通的時候另一個截止.
要實作 線與 需要用OC(open collector)門電路.是兩個參數相同的三極管或MOSFET,以推挽方式存在于電路中,各負責正負半周的波形放大任務,電路工作時,兩隻對稱的功率開關管每次隻有一個導通,是以導通損耗小,效率高。輸出既可以向負載灌電流,也可以從負載抽取電流
當端口配置為輸出時:
開漏模式:輸出 0 時,N-MOS 導通,P-MOS 不被激活,輸出0。
輸出 1 時,N-MOS 高阻, P-MOS 不被激活,輸出1(需要外部上拉電路);此模式可以把端口作為雙向IO使用。
推挽模式:輸出 0 時,N-MOS 導通,P-MOS 高阻 ,輸出0。
輸出 1 時,N-MOS 高阻,P-MOS 導通,輸出1(不需要外部上拉電路)。
簡單來說開漏是0的時候接GND 1的時候浮空 推挽是0的時候接GND 1的時候接VCC
3、在STM32中選用IO模式
(1) 浮空輸入_IN_FLOATING —浮空輸入,可以做KEY識别,RX1
(2)帶上拉輸入_IPU—IO内部上拉電阻輸入
(3)帶下拉輸入_IPD—IO内部下拉電阻輸入
(4) 模拟輸入_AIN —應用ADC模拟輸入,或者低功耗下省電。
(5)開漏輸出_OUT_OD —IO輸出0接GND,IO輸出1,懸空,需要外接上拉電阻,才能實作輸出高電平。當輸出為1時,IO口的狀态由上拉電阻拉高電平,但由于是開漏輸出模式,這樣IO口也就可以由外部電路改變為低電平或不變 。可以讀IO輸入電平變化,實作C51的IO雙向功能。
(6)推挽輸出_OUT_PP ——IO輸出0-接GND, IO輸出1 -接VCC,讀輸入值是未知的。
(7)複用功能的推挽輸出_AF_PP ——片内外設功能(I2C的SCL,SDA)
(8)複用功能的開漏輸出_AF_OD——片内外設功能(TX1,MOSI,MISO.SCK.SS)
執行個體總結:
(1)模拟I2C使用開漏輸出_OUT_OD,接上拉電阻,能夠正确輸出0和1;讀值時先
GPIO_SetBits(GPIOB, GPIO_Pin_0);拉高,然後可以讀IO的值;使用
GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0);
(2)如果是無上拉電阻,IO預設是高電平;需要讀取IO的值,可以使用
帶上拉輸入_IPU和浮空輸入_IN_FLOATING和 開漏輸出_OUT_OD;
4、IO低功耗:
關于模拟輸入&低功耗,根據STM32的低功耗AN(AN2629)及其源檔案,在STOP模式下,為了得到盡量低的功耗,确實把所有的IO(包括非A/D輸入的GPIO)都設定為模拟輸入
轉載于:https://www.cnblogs.com/zjjsxuqiang/archive/2013/02/10/2909784.html