相信從事產品規劃或是工程人員,或多或少在元件規格中會見到I2C介面的存在,也許也見過SM-Bus,兩者究竟有何差異?兩造的內在又是如何,相信是很多人想去知道的事情...
相信從事產品規劃或是工程人員,或多或少在元件規格中會見到I
2C介面的存在,也許也見過SM-Bus,兩者究竟有何差異?兩造的內在又是如何,相信是很多人想去知道的事情。一個歷經時間打不死的介面,必然有其前因與後果。有不少場合,I
2C介面也被寫成I
2C介面,是指向同樣東西。
回首1980年代初期,飛利浦半導體為了積體電路內部的連接方便,發展了兩線式(2 Wire)的雙向介面,當時將之稱作「Inter-IC」介面,簡稱I2C介面或I2C匯流排,原本的目的是為了在電視機內部讓處理器CPU晶片與周邊晶片更容易連接。我們都知道嵌入式系統的設計,連接到MCU控制器的周邊裝置往往用記憶體映射的I/O處理方式,換句話說,在線路板上的微控制器必須連接一堆的位址信號線(Address Bus)與資料信號線(Data Bus)。不用多說,必要的位址解碼線路以及額外的邏輯線路是跑不掉的,這一點對於像電視機、錄放影機或音響機器在大量生產的時候,是很不利的一面,至於多條控制線引起額外的副作用,好比說電磁干擾EMI等,也是惱人的問題。
飛利浦為了克服這個問題,座落於荷蘭Eindhoven的實驗室,最終發展出I2C介面。由於容易使用,讓積體電路之間的控制更為有效率。此介面逐漸成為產業上一個泛用的標準。目前,該公司有超過1,000種以上的元件,諸如控制器等都內建了此介面。同時,I2C介面也授權給很多知名公司使用,好比說Xicor、ST Microelectronics、英飛凌、Intel、TI、Maxim、Atmel、Analog Devices等。
意思是說,只要在晶片上納入了I2C介面,元件之間就可以直接透過該介面來彼此溝通,尤其是設計數位控制電路的時候,這個介面或許可以幫您解決不少問題。
從信號的實質面來看,I2C介面僅包含了兩條主動信號線以及一條地線,這兩條主動信號線分別是「SDA」與「SCL」,兩者皆是雙方向的傳輸信號線。
‧SDA=Serial DAta line
‧SCL=Serial CLock line
每一個連接到匯流排上的元件裝置,無論是MCU控制器、LCD驅動器或ASIC,都會擁有其唯一的位址,依據功能上的差異,每一個元件可以是傳送端或是接收端,比如說,LCD驅動器僅僅是接收端,而像一些記憶體晶片或是I/O晶片很可能是兩者具備。
正如同一般匯流排的慣例,啟動資料傳輸的一方稱之為主控端(Bus Master),非主控端的元件就是從屬端(Bus Slave),有趣的地方是,I2C介面可以是隸屬一個多重主控端(Multi-Master)的匯流排架構。
通常,微控制器MCU總是扮演著主控端的角色,如果微控制器要送資料到某一個從屬端,首先,微控制器會送出「起始」(Start)的狀態,有如告知所有連接元件的注意信號,介面上的元件就要留意有資料即將到來,接著,主控端送出要存取元件的位址,以及讀取或是寫入的資訊,若接收元件獲知是自己的位址,就必須回應認可(Acknowledge)信號,若是位址事不關己則不予理會。
一旦微控制器MCU接收到認可信號之後,才開始傳送接收資料,當完成資料傳輸之後,微控制器MCU送出「結束(Stop)」狀況,也就是表示將介面釋放出來,其他的元件可以起始新的動作。若是就介面的狀態來說,介面有起始狀態(Start)、位址狀態(Address)、認可狀態(ACK)、資料狀態與結束狀態(Stop)。
誠如前面所言,SDA與SCL皆是雙向的信號線,通常,這些信號採用開集極(Open Collector)或開源極(Open Drain)的技術。當介面處於閒置(Idle)狀態,介面信號線就呈現邏輯高(Logic HIGH)狀態,因為外部往往接一個拉高電阻,當驅動信號到介面時,晶片會驅動其輸出電晶體,將介面拉到邏輯低狀態。
不過,開集極的技巧也有一個缺點,假若介面長度太長時,因為長距離的介面在輸出驅動器上會呈現電容負載(Capacitive Load)的效應,速度會落下來(圖1)。因為,拉高電阻是被動式元件,與電容器C會產生RC常數,而影響到信號波形的外觀,當RC常數越大時,會影響到信號的迴轉率(Slew Rate),而將速度拉下來。當到了最壞的情況下時,介面上的積體電路甚至難以分別究竟是邏輯一還是邏輯零的信號狀態,信號動作自然出問題啦!
還有一個令人困擾的問題,就是當信號快速的時候,信號反射引起的負效應也是令人難以忍受的問題(圖2)。通常,IC的輸入端會用舒密特觸發(Schmitt Triggers)的電路型態,但是,嚴重的時候也難以克服這道難題,因此在電氣特性的規定就需要更為嚴謹。為了解決該問題,飛利浦半導體發展出主動式終端阻抗(Active Terminator)的方式(圖3),這種元件會包含有一對電荷幫浦(Charge Pump),您可以將其視為介面上的一個動態阻抗,如此措施的好處就是可以很快速地將寄生電容充電,一但電壓高過某個位階,高電流模式就會火速切斷輸出電流。
請仔細看圖3,只要介面維持在邏輯低的時候,電晶體C是開著,這時候由於電晶體B的柵極(Gate)也維持在低電位,因此電荷幫浦就會被關閉。
只要元件晶片釋放出匯流排,電晶體A與電晶體C就會關閉。電容將從四個電阻汲取電流開始充電,當電阻2的電壓降將會開啟電晶體B,將電阻3短路。由於電阻3的數值很小,電流上升。但很快地,電晶體B的柵極(Gate)與源極(Source)將不足夠維持開關開起,開關關閉之後,電流注入停止,這個時候就僅有外部的拉高電阻存在來克服介面上的漏電流(Leakage)問題。
I2C介面是一個多重主控端的匯流排,也就是有機會多個元件會激發傳送,如果在系統上僅有一個主控端,並不會發生什麼資料毀損的風險,除非從屬元件發生了狀況,但是若有兩個以上微控制器存在的場合,情況就可能改觀了(圖4)。
就如圖4,首先當微控制器1送出起始狀態後並送出位址資訊,此時所有的從屬元件,包括微控制器2都在等候,只要位址並不是指向微控制器2,該元件就會抑制任何活動,直到介面匯流排在停止狀態後回到閒置(Idle)的狀態。
當然只要該兩個微控制器的介面監視機能電路做得好,對於介面上的活動瞭若指掌,基本上並不會有問題產生,但是畢竟這是指理想的情況下而說的,意外的人生也同樣會發生在介面上。我們就姑且假設某一個微控制器未察覺到起始狀態,因此它依然會以為介面是處於閒置狀態,而打算開始使用介面,此時,問題就可能跟著來了。
因為,基本的疑問就是您如何知道有其他元件正在介面上傳載資料。幸好,介面的結構是「Wired AND」的型態,也就是說,只要有一個元件驅使在邏輯低,信號線就會維持在邏輯低,因此,您可以測試介面是被佔用還是閒置狀態。
當某一個主控器改變了信號狀態到邏輯高的時候,它必須去檢查是否信號線真的跑到邏輯高,萬一信號線卻呈現在邏輯低的狀況,這就表示著介面是被佔據掉,有其他元件將信號線拉低。
因此,通用的經驗法則是如果主控器並不能確定信號線確實拉高,寧可先放棄(Back Off)等候,到看見停止狀態的出現才開始傳送。
接著,我們來談談資料崩毀(Data Corruption)到底是怎麼一回事。剛前所說是指主控器不能確定SCL或SDA信號線拉高時,會喪失了匯流排使用仲裁權,也指出了送出邏輯零的元件支配了介面。然而,此種放棄的方法,對於主控器不同時運作是可行的,但是,如果兩個主控器剛剛好同時進行時,有趣的問題就出現了(圖5)。
請對照圖5,兩個微控制器MCU正針對位址為「1111001」的從屬裝置進行資料寫入模式,兩個微控制器咸認為他們擁有匯流排的使用權。MCU1要傳送資料「0101.0101」給從屬端,而MCU2要傳送資料「0110.0110」給從屬端,這時候,資料線就衝突發生了,因此,需要妥協的辦法才能夠解決。以圖5為例,MCU2先行放棄,也就是途中色塊的部分,等候到看見停止狀態的出現,才另開始傳送。從此例我們就可以學到一課,那就是匯流排使用權仲裁(Arbitration)的機制,哪一個主控端先拉低,誰就贏得優先使用權。當然啦!仲裁輸的一方唯有等待介面出現停止狀態的出現,才開始傳送。
其次,來談時脈同步(Clock Synchronization)之道。我們明瞭所有的主控端會在SCL信號線上產生其自己的時脈(Clock)在I2C介面上載送訊息。依照規定,時脈信號在高電位時,資料才具有實效性,I2C介面對於SCL信號是採用了「Wired-AND」的連接形式,當SCL信號線從邏輯高轉換到邏輯低時,所有的元件會關心邏輯低的時間,如果時脈從低電位轉換到高電位並不等於SCL信號線一定會在邏輯高,因為,有可能其他的時脈尚在低電位。如果經過所有元件關心的低電位時間,時脈信號線將釋放到高電位,第一個完成高電位時脈週期的元件,會先拉低SCL信號線,因此,可以得知SCL信號的同步,低電位乃是取決於時脈低電位時間最長的元件,而時脈高電位則是取決於時脈高電位週期最短的元件。
如此般的時脈同步機制,就可以拿來作為信號交握(Handshake)的用途。比如說,慢速元件與快速元件或是在多個主控端的場合來使用,這裡所說的慢速元件是指元件內部執行時間,好比說,EEPROM元件需要耗一點時間去寫入資料。I2C介面的同步方式是由SCL信號線來擔當,當從屬端需要主控端來等待的場合,只需將SCL信號拉低,主控端就不會產生ACK的波形。
這種手段,坦白說是存在不少的缺點。第一個能夠想到的問題就是電路設計出了問題,SCL信號線陷入困境,所有的主控端也相對地掉入僵局。當然,可以用逾時(Timeout)的方法來打破僵持不下的停頓狀況,間接地說,就是會影響到速率。
1982年首個I2C規格出現,到了1992年,I2C規格增加了快速模式(Fast Mode)以及10位元的定址方式。對於快速模式來說,實體上介面參數諸如協定、介面位階、電容負載等並沒有變更,只是將資料傳送速率拉升到400Kbps的高水準,當然約束就比較嚴謹,尤其是時序上的考量。所有支援快速模式(Fast Mode)的元件,其輸入端必須納入舒密特觸發(Schmitt Triggers)的電氣特性,可以用來抑制雜訊。輸出端緩衝器要具備斜率控制的能力,能夠讓SDA與SCL信號產生漂亮的下沿,同時,支援快速模式的元件電源關閉之際,介面上的接腳信號也必須維持在漂浮(Floating)狀態,避免妨礙到介面的正常運作,且必須適應拉高電阻的使用。通常200pF的負載情況使用被動式的電阻元件就可以了,若是200~400pF的高負載,建議採用主動式的電流源。
好比USB介面的鳳凰傳奇,I2C介面的驚人之舉就是介面速度的大躍升,增加了高速模式(High Mode),將速率提升到3.4Mbps,而且依然可以與傳統標準模式或快速模式相容。
從原本7個位元的位址增加到10個位元的定址能力,稱之為延伸定址(Extended Addressing)。符合這個新標準的晶片理所當然需要兩個位址位元組,第一個位元組包含了位址的兩個MSB以及讀出/寫入位元,第二個位元組即是位址的8個LSB。在介面上產生任何資料交易(Transaction)之前都必須先發出起始狀態。意思是說該狀態是對所有的連接的元件扮演一個通知的信號,告知即將傳送資料,因此,介面上的所有元件都在等待。當交易完成之後,也必須送出結束的狀態,也就是釋放出匯流排的使用權,讓介面回到閒置的情況下(圖6)。
有一些小細節需要去在意,一筆單獨的訊息交易允許多個起始狀態的發生,而結束狀態不管發生在哪一個時間點,一定表示傳送交易的結束。
一旦主控端送出起始狀態後,就能夠傳送一個位元組給從屬端,在起始狀態之後的第一個位元組就是從屬端的位址。但前面有提到新規格追加了10位元位址延伸定址模式,勢必有第二個位元組,如果是不支援延伸定址的元件,什麼都不必作(圖7)。
如果從屬端支援10位元延伸定址模式,就必須在主控端送出的認可(ACK)狀態之後,作出回應。請留意,無論是傳統的定址模式還是10位元延伸定址模式,第一個位元組的位元零(Bit 0)一定是定義為從屬端的存取模式。
‧邏輯1=讀取(Read)模式
‧邏輯0=寫入(Write)模式
如果從屬端被定址也認可之後,若R/W位元設定為邏輯1,就可以接收從屬端送來的一個位元組,此時,主控端會先釋放SDA信號線,因為從屬端必須擁有該信號的控制權,但是,時脈信號SCL依然還是必須由主控端來產生(圖8)。主控端產生SCL的上沿(2),讀取SDA資訊(3),然後產生SCL的下沿(4),因此,從屬端在SCL邏輯高的時間內是不能改變資料的。在圖8步驟(1)與步驟(5)期間,從屬端可以更新資料。總之,以上的順序總共執行8次完成一個位元組的載送,而且是從MSB位元開始送,至於位元組各個位元的涵義,就必須檢視從屬端元件的資料規範了(圖9)。
當一個位元組(資料或位址)送往從屬端之後,從屬端也必須做出認可(ACK)的回應(圖10)。從屬端在接收第八個位元之後,立即將SDA信號拉低,也就是主控端拉低SCL(1)表示完成位元傳送,從屬端繼續拉低SDA信號線(2),主控端會在SCL信號產生一個脈衝(3),爾後,從屬端在時脈結束之際釋放出SDA信號線(4),這時候主控端可以使用介面繼續送資料產生結束狀態。
相同的道理,當接收到從屬端送來的位元組之後,主控端元件也必須做出認可(ACK)的回應。在這個情形下,SDA與SCL信號線的掌控權完全是在主控端手上(圖11)。
當從屬端送完最後一個位元之後(1),從屬端就會釋放出SDA信號線(2),而主控端卻會將該信號拉低(3),其次,主控端在SCL信號線上產生一個脈衝(4),完成脈衝後,主控端將釋出SDA信號線,此時,從屬端就再次獲得SDA信號線的控制權。如果主控端想要停止從屬端送過來的接收,它必須能夠送出停止的狀態。
有一種情況是當主控端送完第八個位元之後,從屬端並沒有將SDA信號拉低,這種情況被視為「No ACK」的事件,但它不是一種狀態,通常意味著從屬端不在那(如果是位址)、從屬端漏掉了脈衝,或介面被Down掉了。不論是何種狀況,主控端都要對介面送出停止狀態。讓介面回歸到正常動作。
文章末了,將一些平常對於I2C介面的詢問做個條列式整理摘要,方便讀者們閱讀。
‧I2C介面的最長連接距離為何?這個問題的答案與介面上的負載相關聯,典型的應用約是9~12英尺左右。
‧若要延長I2C介面,有沒有類似中繼器(Repeater)解決方法?當然有,這是屬於電流放大器(Current Amplifier)的屬性(圖12),可以解決線長的電容負載。然而,傳送端以及接收端必須搭配使用,避免衍生困擾。
‧市面上有沒有存在獨立的I2C介面控制器?確實有,比如PCD8584或PCF8584等元件。
‧為何SCL信號線必須為雙向?理由很單純,當使用多個主控制的場合就需要了。
‧如何來追蹤I2C介面上的信號活動?市面上有一些廠商在販售監視裝置(Monitor)或是除錯工具(Debugger),可以上網查詢。
‧I2C介面與SMbus的差異究竟在哪裡?這是一個絕佳的好問題,兩者都是兩線式(2-Wire) 的介面,基本上是彼此相容的。然而,SMbus的動作速度僅有100KHz,I2C介面尚有400KHz與2MHz,因此,相容性是指有限度的相容性。
逾時(Timeout)以及最小的時脈速度,可以說是I2C介面與SMbus的最大差異。
‧I2C Bus=DC(no timeout)
‧SMBus=10kHz(35ms timeout)
其次,若仔細來觀察信號邏輯位階,兩者還是有所不同,請參閱圖13。同時,拉高電阻與電流位階(Current Level)也是個好問題,SMBus規定的沉入電流(Sink Current)為100uA~350uA,而I2C介面卻是3mA,也就間接決定了拉高電阻的可接受值。