I2C總線(Inter IC BUS)是PHILIPS公司推出的雙向兩線串行通信標準。由于它具有接口少,、通信效率高等優(yōu)點,,現(xiàn)已得到廣泛的應(yīng)用\[1~3\]。它除了可以進行簡單的單主節(jié)點通信外,,還可以應(yīng)用在多主節(jié)點的通信系統(tǒng)中,。在多主節(jié)點通信系統(tǒng)中,如果兩個或者更多的主節(jié)點同時啟動數(shù)據(jù)傳輸,,總線具有沖突檢測和仲裁功能,,保證通信正常進行并防止數(shù)據(jù)破壞。現(xiàn)在許多微控制器(MCU)都具有I2C總線接口,能方便地進行I2C總線設(shè)計,。對于沒有I2C總線接口的MCU,,可以采用兩條I/O接口線進行模擬\[2,3\],。目前,,一些介紹模擬I2C的資料主要講的是在單主節(jié)點系統(tǒng)中進行的通信,這使得模擬I2C總線的應(yīng)用具有一定的局限性,。本文根據(jù)總線仲裁的思想,,提出一種多主節(jié)點通信的思想及實現(xiàn)流程。
1 I2C總線系統(tǒng)簡介[1~3]
I2C總線系統(tǒng)是由SCL(串行時鐘)和SDA(串行數(shù)據(jù))兩根總線構(gòu)成的,。該總線有嚴格的時序要求,,總線工作時,由串行時鐘線SCL傳送時鐘脈沖,,由串行數(shù)據(jù)線SDA傳送數(shù)據(jù),。總線協(xié)議規(guī)定,,各主節(jié)點進行通信時都要有起始,、結(jié)束、發(fā)送數(shù)據(jù)和應(yīng)答信號,。這些信號都是通信過程中的基本單元,。總線傳送的每1幀數(shù)據(jù)均是1個字節(jié),,每當發(fā)送完1個字節(jié)后,,接收節(jié)點就相應(yīng)給一應(yīng)答信號。協(xié)議規(guī)定,,在啟動總線后的第1個字節(jié)的高7位是對從節(jié)點的尋址地址,,第8位為方向位(“0”表示主節(jié)點對從節(jié)點的寫操作,;“1”表示主節(jié)點對從節(jié)點的讀操作),其余的字節(jié)為操作數(shù)據(jù),。圖1列出I2C總線上幾個基本信號的時序,。
圖1中包括起始信號,、停止信號、應(yīng)答信號,、非應(yīng)答信號以及傳輸數(shù)據(jù)“0”和數(shù)據(jù)“1”的時序,。起始信號就是在SCL線為高時SDA線從高變化到低;停止信號就是在SCL線為高時SDA線從低變化到高,;應(yīng)答信號是在SCL為高時SDA為低,;非應(yīng)答信號相反,是在SCL為高時SDA為高。傳輸數(shù)據(jù)“0”和數(shù)據(jù)“1”與發(fā)送應(yīng)答位和非應(yīng)答位時序圖是相同的,。
圖1 I2C總線上基本信號的時序
圖2表示了一個完整的數(shù)據(jù)傳送過程,。在I2C總線發(fā)送起始信號后,發(fā)送從機的7位尋址地址和1位表示這次操作性質(zhì)的讀寫位,,在有應(yīng)答信號后開始傳送數(shù)據(jù),,直到發(fā)送停止信號。數(shù)據(jù)是以字節(jié)為單位的,。發(fā)送節(jié)點每發(fā)送1個字節(jié)就要檢測SDA線上有沒有收到應(yīng)答信號,,有則繼續(xù)發(fā)送,否則將停止發(fā)送數(shù)據(jù),。
圖2 一次完整的數(shù)據(jù)傳送過程
2 I2C總線的仲裁
在多主的通信系統(tǒng)中,。總線上有多個節(jié)點,,它們都有自己的尋址地址,,可以作為從節(jié)點被別的節(jié)點訪問,同時它們都可以作為主節(jié)點向其他的節(jié)點發(fā)送控制字節(jié)和傳送數(shù)據(jù),。但是如果有兩個或兩個以上的節(jié)點都向總線上發(fā)送啟動信號并開始傳送數(shù)據(jù),,這樣就形成了沖突。要解決這種沖突,,就要進行仲裁的判決,,這就是I2C總線上的仲裁。
I2C總線上的仲裁分兩部分:SCL線的同步和SDA線的仲裁,。SCL同步是由于總線具有線“與”的邏輯功能,,即只要有一個節(jié)點發(fā)送低電平時,總線上就表現(xiàn)為低電平,。當所有的節(jié)點都發(fā)送高電平時,,總線才能表現(xiàn)為高電平。正是由于線“與”邏輯功能的原理,,當多個節(jié)點同時發(fā)送時鐘信號時,,在總線上表現(xiàn)的是統(tǒng)一的時鐘信號。這就是SCL的同步原理,。
SDA線的仲裁也是建立在總線具有線“與”邏輯功能的原理上的,。節(jié)點在發(fā)送1位數(shù)據(jù)后,比較總線上所呈現(xiàn)的數(shù)據(jù)與自己發(fā)送的是否一致,。是,,繼續(xù)發(fā)送;否則,,退出競爭,。圖3中給出了兩個節(jié)點在總線上的仲裁過程,。SDA線的仲裁可以保證I2C總線系統(tǒng)在多個主節(jié)點同時企圖控制總線時通信正常進行并且數(shù)據(jù)不丟失??偩€系統(tǒng)通過仲裁只允許一個主節(jié)點可以繼續(xù)占據(jù)總線[1],。
圖3是以兩個節(jié)點為例的仲裁過程。DATA1和DATA2分別是主節(jié)點向總線所發(fā)送的數(shù)據(jù)信號,,SDA為總線上所呈現(xiàn)的數(shù)據(jù)信號,,SCL是總線上所呈現(xiàn)的時鐘信號。當主節(jié)點1,、2同時發(fā)送起始信號時,,兩個主節(jié)點都發(fā)送了高電平信號。這時總線上呈現(xiàn)的信號為高電平,,兩個主節(jié)點都檢測到總線上的信號與自己發(fā)送的信號相同,,繼續(xù)發(fā)送數(shù)據(jù)。第2個時鐘周期,,2個主節(jié)點都發(fā)送低電平信號,,在總線上呈現(xiàn)的信號為低電平,仍繼續(xù)發(fā)送數(shù)據(jù),。在第3個時鐘周期,,主節(jié)點1發(fā)送高電平信號,而主節(jié)點2發(fā)送低電平信號,。根據(jù)總線的線“與”的邏輯功能,,總線上的信號為低電平,這時主節(jié)點1檢測到總線上的數(shù)據(jù)和自己所發(fā)送的數(shù)據(jù)不一樣,,就斷開數(shù)據(jù)的輸出級,,轉(zhuǎn)為從機接收狀態(tài)。這樣主節(jié)點2就贏得了總線,,而且數(shù)據(jù)沒有丟失,,即總線的數(shù)據(jù)與主節(jié)點2所發(fā)送的數(shù)據(jù)一樣,而主節(jié)點1在轉(zhuǎn)為從節(jié)點后繼續(xù)接收數(shù)據(jù),,同樣也沒有丟掉SDA線上的數(shù)據(jù),。因此在仲裁過程中數(shù)據(jù)沒有丟失。
圖3 兩個主節(jié)點的仲裁過程
3 多主通信的原理及其實現(xiàn)流程
多主通信就是在總線上有多個節(jié)點,。這些節(jié)點既可以作為主節(jié)點訪問其他的節(jié)點,,也可以作為從節(jié)點被其他節(jié)點訪問。當有多個節(jié)點同時企圖占用總線時,,就需要總線的仲裁。對于模擬I2C總線系統(tǒng),,怎樣實現(xiàn)總線的仲裁是現(xiàn)在研究模擬I2C總線系統(tǒng)的難點,。文獻\[4\]提出在系統(tǒng)中增加1根BUSY線,,在占用總線之前先檢測BUSY線,看總線是否被占用,。若總線空閑,,則設(shè)置BUSY線并向總線上傳送數(shù)據(jù);否則,,接收數(shù)據(jù),,直到總線空閑時才占有總線。這種實現(xiàn)多主通信的方法有兩個缺點:① 因為I2C最大的優(yōu)點就是接口少,、效率高,,這樣做不僅增加了使用資源而且減少了I2C總線的優(yōu)勢;② 當主節(jié)點數(shù)比較多時,,等待時間比較長,,效率不高。本設(shè)計根據(jù)總線的仲裁原理,,提出一種基于延時比較的仲裁方法,。當主節(jié)點想要占用總線時,先檢測總線上是否空閑,,如果總線是空閑的就發(fā)送數(shù)據(jù),。在發(fā)送數(shù)據(jù)的同時,將總線上的數(shù)據(jù)接收并與發(fā)送的數(shù)據(jù)進行比較,。如果不同,,說明總線上同時還存在其他節(jié)點,于是就退出,;否則,,一直到發(fā)送完數(shù)據(jù)。這種方法既體現(xiàn)了I2C總線的高效性,,同時還具有良好的擴展性,。
圖4 多主通信流程
圖4給出了基于延時比較的多主通信流程,其中MCU作為從節(jié)點部分的流程在圖5中給出,。在節(jié)點發(fā)送起始信號之前先要檢測一下總線上是否為空閑狀態(tài)(BUSY是否為0),。這里使用的檢測方法是,持續(xù)檢測一段時間看總線上的電平是否一直為高,,若是說明總線上為閑狀態(tài),,否則說明有其他的節(jié)點正在使用總線,要等一段時間再發(fā)送,。當總線空閑時,,發(fā)送起始信號,接著發(fā)送要訪問的從節(jié)點的地址字節(jié),。每發(fā)送1位數(shù)據(jù)就接收比較1次,,看發(fā)送和接收的是否一致,,若是則繼續(xù),否則跳出到從節(jié)點的接收狀態(tài),。如果沒有產(chǎn)生沖突,,MCU作為主節(jié)點繼續(xù)發(fā)送數(shù)據(jù),直到任務(wù)結(jié)束,,然后發(fā)送停止信號并返回,。如果數(shù)據(jù)不一樣,MCU將跳轉(zhuǎn)到從節(jié)點狀態(tài),。由于在跳轉(zhuǎn)到從節(jié)點接收狀態(tài)的過程中累加器(ACC)和工作寄存器(Ri)的數(shù)據(jù)沒有發(fā)生變化,,所以數(shù)據(jù)沒有丟失,作為從節(jié)點可以繼續(xù)接收總線上的數(shù)據(jù),。這樣整個通信的過程沒有中斷,,數(shù)據(jù)也沒有丟失。
圖5 從節(jié)點部分的流程
圖5給出了從節(jié)點的流程,。進入從節(jié)點時,,要將BUSY置為高,說明MCU現(xiàn)在正在工作,,不能完成其他的任務(wù),。在MCU作為從節(jié)點完成接收任務(wù)后,要將BUSY置為低,。MCU在接收到尋址字節(jié)后與自己的地址字節(jié)進行比較,。如果是訪問自己的就進入到下面的接收程序,否則跳出,。在訪問自己的時候,,還要判斷主節(jié)點是讀取數(shù)據(jù)還是寫數(shù)據(jù),以便進入相應(yīng)的程序,。在寫字節(jié)的子程序中,,從節(jié)點每發(fā)送1個字節(jié)的數(shù)據(jù)后都要察看是否有應(yīng)答信號(ACK),有則說明數(shù)據(jù)接收到了,;否則要跳出等待,,重新發(fā)送。在讀字節(jié)的子程序中,,每接收1個字節(jié)的數(shù)據(jù)就要發(fā)送1個應(yīng)答信號(ACK),,以示接收正常,否則主節(jié)點將停止繼續(xù)發(fā)送,。在現(xiàn)有的資料中,,關(guān)于從節(jié)點的原理和源代碼比較少,這里給出作為從節(jié)點時寫字節(jié)子程序的源代碼,。由于篇幅有限其他的子程序沒有列出,。
4 部分源代碼
本節(jié)是在MCU多主通信中的部分源代碼,。多主通信的實現(xiàn)中有幾個難點和重點,。一是在作為主節(jié)點時的寫字節(jié)子程序,,里面要包括發(fā)送的每位數(shù)據(jù)和總線的數(shù)據(jù)進行比較并做出判斷。如果數(shù)據(jù)不同,,要跳出并進入從節(jié)點的狀態(tài),。由于子程序返回主程序時改變的只是PC的值而累加器(ACC)和工作寄存器(Ri)里面的值是不變的,因此MCU進入從機狀態(tài)后繼續(xù)接收總線剩下的數(shù)據(jù),,這樣總線的數(shù)據(jù)并沒有丟失,。二是作為
從節(jié)點時的寫字節(jié)的子程序。由于時鐘線是由主節(jié)點的MCU控制的,,所以怎樣根據(jù)SCL線來讀取SDA線的數(shù)據(jù)是其中的一個難點,。三是在具有子地址的從節(jié)點關(guān)于是寫字節(jié)還是讀字節(jié)時的判斷。如果是寫字節(jié)時主節(jié)點會給出新的起始信號,,并再次發(fā)送從節(jié)點的地址數(shù)據(jù),。這時從節(jié)點需要做出判斷是讀取數(shù)據(jù)還是寫數(shù)據(jù),并進入相應(yīng)的子程序,。這里給出以上三個重點和難點的子程序的源代碼,,以供讀者參考。這些源代碼經(jīng)實踐證明都是正確的,。
主節(jié)點的寫字節(jié)子程序:
其中的NOP可根據(jù)時鐘的快慢自己加減
WRBYTE:MOV R0,#08H
CLR BUSY;將BUSY值清零
WLP: RLC A;取數(shù)據(jù)位
JC WR1
SJMP WR0;判斷數(shù)據(jù)位
WLP1: DJNZ R0,WLP
NOP
OUT1: RET
WR1: SETB SDA;發(fā)送1
NOP
SETB SCL
MOV C,SDA;判斷是否與發(fā)送的數(shù)據(jù)相同
JC GOON
SETB BUSY
AJMP OUT1
GOON: NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR0: CLR SDA;發(fā)送0
NOP
SCL
NOP
NOP
NOP
NOP
NOP
CLR
SCL
SJMP WLP1
從節(jié)點的寫字節(jié)子程序(返回為ACK):
SWRBYTE:MOV R0,#08H
WAGAIN: RRC A
MOV B,#37H
WWAIT1: JB SCL,WWAIT1;等待SCL為低
JC WR1;判斷是發(fā)送“1”還是發(fā)送“0”
SETB SDA;發(fā)送“1”
AJMP COM
WR1: CLR SDA;發(fā)送“0”
COM: DJNZ R0,WWAIT2;判斷是否發(fā)送完畢
WWAIT3: JNB SCL,WWAIT3;發(fā)送完畢等待應(yīng)答信號
WWAIT4: JB SCL,WWAIT4
WWAIT5: JNB SCL,WWAIT5
CLR ACK
JB SDA,ST0
SETB ACK
ST0: RET;返回
WWAIT2: JNB SCL,WWAIT2;等待SCL為高
SJMP WAGAIN
從節(jié)點的讀字節(jié)同時判斷是否有起始信號的子程序,。如果有起始信號,則轉(zhuǎn)為寫字節(jié)子程序:
SRDBYTE:MOV R0,#08H
SETB 20H;設(shè)置標志位判斷是讀還是寫
SETB SDA;釋放總線
RWAITJ: JNB SCL,RWAITJ;等待SCL為高
MOV C,SDA;從總線上讀取數(shù)據(jù)
RRC A;存入累計器
DEC R0
MOV C,ACC.7;判斷是否為起始信號
JNC RWAITJ1;為低繼續(xù)讀取數(shù)據(jù)
REWAIT: JNB SCL,RWAITJ1;開始判斷是否為起始信號
JB SDA,REWAIT
CLR 20H;是,,則清標志位并返回
AJMP SjRDOUT
RWAITJ1:JB SCL,RWAITJ1;等待SCL為低
RWAITJ3:JNB SCL,RWAITJ3;等待SCL為高
MOV C,SDA
RRC A
DJNZ R0,RWAITJ2
SjRDOUT:RET
RWAITJ2:JB SCL,RWAITJ2;等待SCL為低繼續(xù)讀數(shù)據(jù)
SJMP RWAITJ3
5 總結(jié)
根據(jù)總線協(xié)議中的仲裁原理,,提出的基于延時比較的模擬I2C多主通信的方法,不僅能夠體現(xiàn)了I2C總線的高效性,,而且還具有良好的擴展性,。它使普通不具有I2C接口的MCU可以應(yīng)用在多主通信的系統(tǒng)中,既增加了普通MCU的使用范圍,,又突破了模擬I2C總線的應(yīng)用局限性,,為I2C總線的推廣起到了積極的作用。
參考文獻
1 The I2CBus SpecificaTIon, Version 2.1. January, 2000. http://www.philips.com/
2 張昆,邱揚,劉浩. 基于CPLD的系統(tǒng)中I2C總線的設(shè)計. 電子技術(shù)應(yīng)用,,2003(11)
3 何立民. I2C總線應(yīng)用系統(tǒng)設(shè)計. 北京:北京航空航天大學出版社,,1995
4 張冬梅,藩仕彬,何為民. 模擬I2C總線多主通信的通用軟件包. 單片機與嵌入式系統(tǒng)應(yīng)用, 2003(12)