I2C(內部集成電路)是一種應用非常廣泛的總線協議,MCU和很多芯片之間的數據通信都基于I2C實現,包括十分常見的EEPROM芯片AT24系列等。
I2C總線由串行時鐘線SCL和串行數據線SDA組成,在MCU作為I2C主機開發時,SCL和SDA對應的GPIO引腳都需要配置為開漏輸出模式(Open Drain Output Mode),否則I2C總線的通信就要出問題。
作者隨便找了幾個不同廠商的MCU芯片關于I2C配置方面的代碼,如下所示:



毫無疑問,全部配置為開漏輸出模式。
那么,大家有深入研究過為什么MCU的I2C引腳要配置為開漏輸出模式嗎?這有什么講究嗎?
首先,我們來說說GPIO的開漏輸出是什么意思吧!
大家都知道,在MCU的多種GPIO配置模式中,有一種是開漏輸出模式。在這種配置中,是沒有PMOS晶體管的,而NMOS晶體管的漏極保持在浮空狀態。
因此,這個時候漏極連接的GPIO引腳狀態是不穩定的,一般需要在引腳輸出上外接一個上拉電阻(4.7KΩ或者10KΩ),即輸出高電平時,NMOS管關閉,通過上拉電阻將電平拉到高,輸出低電平時,NOMS管導通,引腳拉到GND變為低電平,如下圖所示:

因此,開漏輸出模式的高電平信號由外部上拉電阻的VDD電源決定,可以適配不同的電壓信號,比如3.3V或者5V,而不需要額外的電平轉換電路。
綜上所述,開漏模式由于其靈活性和對外部電路的依賴性,在需要與其他設備共享通信線或進行電平轉換的場合中非常有用。
接著,我們再來說說I2C引腳配置為開漏輸出的原因吧!
我們都知道,I2C總線是支持多主多從的拓撲結構的,之所以支持,就和這個開漏輸出的技術密不可分。由前文可知,開漏電路只能輸出邏輯0,無法輸出邏輯1,需要外部上拉電阻將電平拉高到供電電壓,所以這種設計使得多個設備可以共享這兩條總線,然后通過上拉電阻實現電平的穩定?。
當多個主設備同時嘗試發送信號時,總線會通過上拉電阻保持高電平,避免信號沖突;只有當某個主設備將對應的引腳拉低時,才能控制總線,通俗地說,就是通過“線與”的邏輯保證任何一個主設備拉低總線時,總線整體即為低電平。

反過來說,如果配置為推挽輸出模式(Push-Poll),則可能會因為同時有多個設備試圖訪問和控制總線而導致信號沖突,甚至會因為短路原因而導致設備損壞。
另外,在對功耗有一定要求的系統里,這種設計也是非常好的。因為開漏結構使得每個設備在沒有數據通信時幾乎不消耗電流,只有在需要通信時才通過上拉電阻與總線連接,從而達到了降低系統整體功耗的目的。
此外,采用開漏結構設計的兩根信號線,在抗干擾性能方面也不錯,使得I2C總線能夠被應用于噪聲環境當中。
考慮到在GPIO模式當中,普通輸出、普通輸入和模擬輸入這幾種模式是大家用的比較多,也是比較熟悉的,而開漏模式相對使用可能較少的原因,作者就以I2C總線為例簡單介紹了開漏模式,希望大家以后在使用中可以注意區分和應用。

END
作者:dffzh