IIC 簡(jiǎn)介
IIC(Inter-Integrated Circuit)總線是一種由NXP(原PHILIPS)公司開(kāi)發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。多用于主控制器和從器件間的主從通信,在小數(shù)據(jù)量場(chǎng)合使用,傳輸距離短,任意時(shí)刻只能有一個(gè)主機(jī)等特性。
在 CPU 與被控 IC 之間、IC 與 IC 之間進(jìn)行雙向傳送,高速 IIC 總線一般可達(dá) 400kbps 以上。
PS:這里要注意IIC是為了與低速設(shè)備通信而發(fā)明的,所以IIC的傳輸速率比不上SPI
?
IIC的物理層
IIC一共有只有兩個(gè)總線:一條是雙向的串行數(shù)據(jù)線SDA,一條是串行時(shí)鐘線SCL
SDA(Serial data)是數(shù)據(jù)線,D代表Data也就是數(shù)據(jù),Send Data 也就是用來(lái)傳輸數(shù)據(jù)的
SCL(Serial clock line)是時(shí)鐘線,C代表Clock 也就是時(shí)鐘 也就是控制數(shù)據(jù)發(fā)送的時(shí)序的
所有接到I2C總線設(shè)備上的串行數(shù)據(jù)SDA都接到總線的SDA上,各設(shè)備的時(shí)鐘線SCL接到總線的SCL上。I2C總線上的每個(gè)設(shè)備都自己一個(gè)唯一的地址,來(lái)確保不同設(shè)備之間訪問(wèn)的準(zhǔn)確性。
IIC主要特點(diǎn):
通常我們?yōu)榱朔奖惆袸IC設(shè)備分為主設(shè)備和從設(shè)備,基本上誰(shuí)控制時(shí)鐘線(即控制SCL的電平高低變換)誰(shuí)就是主設(shè)備。**
IIC主設(shè)備功能:主要產(chǎn)生時(shí)鐘,產(chǎn)生起始信號(hào)和停止信號(hào)
IIC從設(shè)備功能:可編程的IIC地址檢測(cè),停止位檢測(cè)
IIC的一個(gè)優(yōu)點(diǎn)是它支持多主控(multimastering), 其中任何一個(gè)能夠進(jìn)行發(fā)送和接收的設(shè)備都可以成為主總線。一個(gè)主控能夠控制信號(hào)的傳輸和時(shí)鐘頻率。當(dāng)然,在任何時(shí)間點(diǎn)上只能有一個(gè)主控。
支持不同速率的通訊速度,標(biāo)準(zhǔn)速度(最高速度100kHZ),快速(最高400kHZ)
SCL和SDA都需要接上拉電阻 (大小由速度和容性負(fù)載決定一般在3.3K-10K之間) 保證數(shù)據(jù)的穩(wěn)定性,減少干擾。
IIC是半雙工,而不是全雙工 ,同一時(shí)間只可以單向通信
為了避免總線信號(hào)的混亂,要求各設(shè)備連接到總線的輸出端時(shí)必須是漏極開(kāi)路(OD)輸出或集電極開(kāi)路(OC)輸出。這一點(diǎn)在等下我們會(huì)講解
IIC的高阻態(tài)
漏極開(kāi)路(Open Drain)即高阻狀態(tài),適用于輸入/輸出,其可獨(dú)立輸入/輸出低電平和高阻狀態(tài),若需要產(chǎn)生高電平,則需使用外部上拉電阻
高阻狀態(tài):高阻狀態(tài)是三態(tài)門(mén)電路的一種狀態(tài)。邏輯門(mén)的輸出除有高、低電平兩種狀態(tài)外,還有第三種狀態(tài)——高阻狀態(tài)的門(mén)電路。電路分析時(shí)高阻態(tài)可做開(kāi)路理解。
我們知道IIC的所有設(shè)備是接在一根總線上的,那么我們進(jìn)行通信的時(shí)候往往只是幾個(gè)設(shè)備進(jìn)行通信,那么這時(shí)候其余的空閑設(shè)備可能會(huì)受到總線干擾,或者干擾到總線,怎么辦呢?
為了避免總線信號(hào)的混亂,IIC的空閑狀態(tài)只能有外部上拉, 而此時(shí)空閑設(shè)備被拉到了高阻態(tài),也就是相當(dāng)于斷路, 整個(gè)IIC總線只有開(kāi)啟了的設(shè)備才會(huì)正常進(jìn)行通信,而不會(huì)干擾到其他設(shè)備。
IIC器件地址:每一個(gè)IIC器件都有一個(gè)器件地址,有的器件地址在出廠時(shí)地址就設(shè)定好了,用戶不可以更改,比如OV7670的地址為0x42。有的器件例如EEPROM,前四個(gè)地址已經(jīng)確定為1010,后三個(gè)地址是由硬件鏈接確定的,所以一IIC總線最多能連8個(gè)EEPROM芯片。
IIC物理層總結(jié):
I2C 總線在物理連接上非常簡(jiǎn)單,分別由SDA(串行數(shù)據(jù)線)和SCL(串行時(shí)鐘線)及上拉電阻組成。通信原理是通過(guò)對(duì)SCL和SDA線高低電平時(shí)序的控制,來(lái)產(chǎn)生I2C總線協(xié)議所需要的信號(hào)進(jìn)行數(shù)據(jù)的傳遞。在總線空閑狀態(tài)時(shí),SCL和SDA被上拉電阻Rp拉高,使SDA和SCL線都保持高電平。
I2C通信方式為半雙工,只有一根SDA線,同一時(shí)間只可以單向通信,485也為半雙工,SPI和uart通信為全雙工。
主機(jī)和從機(jī)的概念:
主機(jī)就是負(fù)責(zé)整個(gè)系統(tǒng)的任務(wù)協(xié)調(diào)與分配,從機(jī)一般是通過(guò)接收主機(jī)的指令從而完成某些特定的任務(wù),主機(jī)和從機(jī)之間通過(guò)總線連接,進(jìn)行數(shù)據(jù)通訊。
發(fā)布主要命令的稱為主機(jī)
接受命令的稱為從機(jī)
半雙工和全雙工:
IIC的協(xié)議層
I2C 總線在傳送數(shù)據(jù)過(guò)程中共有三種類型信號(hào), 它們分別是:開(kāi)始信號(hào)、結(jié)束信號(hào)和應(yīng)答信號(hào)。
開(kāi)始信號(hào):SCL 為高電平時(shí),SDA 由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào):SCL 為高電平時(shí),SDA 由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
應(yīng)答信號(hào):接收數(shù)據(jù)的 IC 在接收到 8bit 數(shù)據(jù)后,向發(fā)送數(shù)據(jù)的 IC 發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)。CPU 向受控單元發(fā)出一個(gè)信號(hào)后,等待受控單元發(fā)出一個(gè)應(yīng)答信號(hào),CPU 接收到應(yīng)答信號(hào)后,根據(jù)實(shí)際情況作出是否繼續(xù)傳遞信號(hào)的判斷。若未收到應(yīng)答信號(hào),由判斷為受控單元出現(xiàn)故障。
這些信號(hào)中,起始信號(hào)是必需的,結(jié)束信號(hào)和應(yīng)答信號(hào),都可以不要。
IIC 總線時(shí)序圖
下面我們來(lái)詳細(xì)的介紹下IIC的通信協(xié)議流程:
初始(空閑)狀態(tài)
因?yàn)镮IC的 SCL 和SDA 都需要接上拉電阻,保證空閑狀態(tài)的穩(wěn)定性
所以IIC總線在空閑狀態(tài)下SCL 和SDA都保持高電平
代碼:
開(kāi)始信號(hào):
SCL保持高電平,SDA由高電平變?yōu)榈碗娖胶?,延時(shí)(>4.7us),SCL變?yōu)榈碗娖健?/p>
代碼表示:
停止信號(hào)
停止信號(hào):SCL保持高電平。SDA由低電平變?yōu)楦唠娖健?/p>
在起始條件產(chǎn)生后,總線處于忙狀態(tài),由本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備獨(dú)占,其他I2C器件無(wú)法訪問(wèn)總線;而在停止條件產(chǎn)生后,本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備將釋放總線,總線再次處于空閑狀態(tài)。
數(shù)據(jù)有效性
IIC信號(hào)在數(shù)據(jù)傳輸過(guò)程中,當(dāng)SCL=1高電平時(shí),數(shù)據(jù)線SDA必須保持穩(wěn)定狀態(tài),不允許有電平跳變,只有在時(shí)鐘線上的信號(hào)為低電平期間,數(shù)據(jù)線上的高電平或低電平狀態(tài)才允許變化。
SCL=1時(shí) 數(shù)據(jù)線SDA的任何電平變換會(huì)看做是總線的起始信號(hào)或者停止信號(hào)。
也就是在IIC傳輸數(shù)據(jù)的過(guò)程中,SCL時(shí)鐘線會(huì)頻繁的轉(zhuǎn)換電平,以保證數(shù)據(jù)的傳輸
應(yīng)答信號(hào)
每當(dāng)主機(jī)向從機(jī)發(fā)送完一個(gè)字節(jié)的數(shù)據(jù),主機(jī)總是需要等待從機(jī)給出一個(gè)應(yīng)答信號(hào),以確認(rèn)從機(jī)是否成功接收到了數(shù)據(jù),
應(yīng)答信號(hào):主機(jī)SCL拉高,讀取從機(jī)SDA的電平,為低電平表示產(chǎn)生應(yīng)答
應(yīng)答信號(hào)為低電平時(shí),規(guī)定為有效應(yīng)答位(ACK,簡(jiǎn)稱應(yīng)答位),表示接收器已經(jīng)成功地接收了該字節(jié);
應(yīng)答信號(hào)為高電平時(shí),規(guī)定為非應(yīng)答位(NACK),一般表示接收器接收該字節(jié)沒(méi)有成功。
**每發(fā)送一個(gè)字節(jié)(8個(gè)bit)**在一個(gè)字節(jié)傳輸?shù)?個(gè)時(shí)鐘后的第九個(gè)時(shí)鐘期間,接收器接收數(shù)據(jù)后必須回一個(gè)ACK應(yīng)答信號(hào)給發(fā)送器,這樣才能進(jìn)行數(shù)據(jù)傳輸。
應(yīng)答出現(xiàn)在每一次主機(jī)完成8個(gè)數(shù)據(jù)位傳輸后緊跟著的時(shí)鐘周期,低電平0表示應(yīng)答,1表示非應(yīng)答,
?
?
等待應(yīng)答信號(hào):
IIC數(shù)據(jù)傳送
數(shù)據(jù)傳送格式
SDA線上的數(shù)據(jù)在SCL時(shí)鐘“高”期間必須是穩(wěn)定的,只有當(dāng)SCL線上的時(shí)鐘信號(hào)為低時(shí),數(shù)據(jù)線上的“高”或“低”狀態(tài)才可以改變。輸出到SDA線上的每個(gè)字節(jié)必須是8位,數(shù)據(jù)傳送時(shí),先傳送最高位(MSB),每一個(gè)被傳送的字節(jié)后面都必須跟隨一位應(yīng)答位(即一幀共有9位)。
當(dāng)一個(gè)字節(jié)按數(shù)據(jù)位從高位到低位的順序傳輸完后,緊接著從設(shè)備將拉低SDA線,回傳給主設(shè)備一個(gè)應(yīng)答位ACK, 此時(shí)才認(rèn)為一個(gè)字節(jié)真正的被傳輸完成 ,如果一段時(shí)間內(nèi)沒(méi)有收到從機(jī)的應(yīng)答信號(hào),則自動(dòng)認(rèn)為從機(jī)已正確接收到數(shù)據(jù)。
IIC寫(xiě)數(shù)據(jù):
?
?
多數(shù)從設(shè)備的地址為7位或者10位,一般都用七位。
八位設(shè)備地址=7位從機(jī)地址+讀/寫(xiě)地址,
再給地址添加一個(gè)方向位位用來(lái)表示接下來(lái)數(shù)據(jù)傳輸?shù)姆较颍?/p>
0表示主設(shè)備向從設(shè)備(write)寫(xiě)數(shù)據(jù),
1表示主設(shè)備向從設(shè)備(read)讀數(shù)據(jù)
IIC的每一幀數(shù)據(jù)由9bit組成,
如果是發(fā)送數(shù)據(jù),則包含 8bit數(shù)據(jù)+1bit ACK,
如果是設(shè)備地址數(shù)據(jù),則8bit包含7bit設(shè)備地址 1bit方向
在起始信號(hào)后必須傳送一個(gè)從機(jī)的地址(7位) 1~7位為7位接收器件地址,第8位為讀寫(xiě)位,用“0”表示主機(jī)發(fā)送數(shù)據(jù)(W),“1”表示主機(jī)接收數(shù)據(jù) (R), 第9位為ACK應(yīng)答位,緊接著的為第一個(gè)數(shù)據(jù)字節(jié),然后是一位應(yīng)答位,后面繼續(xù)第2個(gè)數(shù)據(jù)字節(jié)。
IIC發(fā)送一個(gè)字節(jié)數(shù)據(jù):
IIC讀取一個(gè)字節(jié)數(shù)據(jù):
IIC發(fā)送數(shù)據(jù)
?
?
?
?
Start: IIC開(kāi)始信號(hào),表示開(kāi)始傳輸。
DEVICE_ADDRESS:: 從設(shè)備地址,就是7位從機(jī)地址
R/W:W(write)為寫(xiě),R(read)為讀
ACK:應(yīng)答信號(hào)
WORD_ADDRESS :從機(jī)中對(duì)應(yīng)的寄存器地址 比方說(shuō)訪問(wèn) OLED中的 某個(gè)寄存器
DATA: 發(fā)送的數(shù)據(jù)
STOP: 停止信號(hào)。結(jié)束IIC
主機(jī)要向從機(jī)寫(xiě)數(shù)據(jù)時(shí):
主機(jī)首先產(chǎn)生START信號(hào)
然后緊跟著發(fā)送一個(gè)從機(jī)地址,這個(gè)地址共有7位,緊接著的第8位是數(shù)據(jù)方 向位(R/W),0表示主機(jī)發(fā)送數(shù)據(jù)(寫(xiě)),1表示主機(jī)接收數(shù)據(jù)(讀)
主機(jī)發(fā)送地址時(shí),總線上的每個(gè)從機(jī)都將這7位地址碼與自己的地址進(jìn)行比較,若相同,則認(rèn)為自己正在被主機(jī)尋址,根據(jù)R/T位將自己確定為發(fā)送器和接收器
這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào)(A)
當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送要訪問(wèn)從機(jī)的那個(gè)地址, 繼續(xù)等待從機(jī)的應(yīng)答信號(hào)
當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送N個(gè)字節(jié)的數(shù)據(jù),繼續(xù)等待從機(jī)的N次應(yīng)答信號(hào),
主機(jī)產(chǎn)生停止信號(hào),結(jié)束傳送過(guò)程。
IIC讀數(shù)據(jù):
?
?
主機(jī)要從從機(jī)讀數(shù)據(jù)時(shí)
主機(jī)首先產(chǎn)生START信號(hào)
然后緊跟著發(fā)送一個(gè)從機(jī)地址,注意此時(shí)該地址的第8位為0,表明是向從機(jī)寫(xiě)命令,
這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào)(ACK)
當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),發(fā)送要訪問(wèn)的地址,繼續(xù)等待從機(jī)的應(yīng)答信號(hào),
當(dāng)主機(jī)收到應(yīng)答信號(hào)后,主機(jī)要改變通信模式(主機(jī)將由發(fā)送變?yōu)榻邮眨瑥臋C(jī)將由接收變?yōu)榘l(fā)送)所以主機(jī)重新發(fā)送一個(gè)開(kāi)始start信號(hào),然后緊跟著發(fā)送一個(gè)從機(jī)地址,注意此時(shí)該地址的第8位為1,表明將主機(jī)設(shè) 置成接收模式開(kāi)始讀取數(shù)據(jù),
這時(shí)候主機(jī)等待從機(jī)的應(yīng)答信號(hào),當(dāng)主機(jī)收到應(yīng)答信號(hào)時(shí),就可以接收1個(gè)字節(jié)的數(shù)據(jù),當(dāng)接收完成后,主機(jī)發(fā)送非應(yīng)答信號(hào),表示不在接收數(shù)據(jù)
主機(jī)進(jìn)而產(chǎn)生停止信號(hào),結(jié)束傳送過(guò)程。
以AT24C02為例子
24C02是一個(gè)2K Bit的串行EEPROM存儲(chǔ)器(掉電不丟失),內(nèi)部含有256個(gè)字節(jié)。在24C02里面有一個(gè)8字節(jié)的頁(yè)寫(xiě)緩沖器。
A0,A1,A2:硬件地址引腳
WP:寫(xiě)保護(hù)引腳,接高電平只讀,接地允許讀和寫(xiě)
SCL和SDA:IIC總線
可以看出對(duì)于不同大小的24Cxx,具有不同的從器件地址。由于24C02為2k容量,也就是說(shuō)只需要參考圖中第一行的內(nèi)容:
芯片的尋址:
AT24C設(shè)備地址為如下,前四位固定為1010,A2~A0為由管腳電平。AT24CXX EEPROM Board模塊中默認(rèn)為接地。A2~A0為000,最后一位表示讀寫(xiě)操作。所以AT24Cxx的讀地址為0xA1,寫(xiě)地址為0xA0。
也就是說(shuō)如果是
寫(xiě)24C02的時(shí)候,從器件地址為10100000(0xA0);
讀24C02的時(shí)候,從器件地址為10100001(0xA1)。
片內(nèi)地址尋址:
芯片尋址可對(duì)內(nèi)部256B中的任一個(gè)進(jìn)行讀/寫(xiě)操作,其尋址范圍為00~FF,共256個(gè)尋址單位。
?
?
對(duì)應(yīng)的修改 A2A1A0 三位數(shù)據(jù)即可
向AT24C02中寫(xiě)數(shù)據(jù)
操作時(shí)序:
MCU先發(fā)送一個(gè)開(kāi)始信號(hào)(START)啟動(dòng)總線
接著跟上首字節(jié),發(fā)送器件寫(xiě)操作地址(DEVICE ADDRESS)+寫(xiě)數(shù)據(jù)(0xA0)
等待應(yīng)答信號(hào)(ACK)
發(fā)送數(shù)據(jù)的存儲(chǔ)地址。24C02一共有256個(gè)字節(jié)的存儲(chǔ)空間,地址從0x00~0xFF,想把數(shù)據(jù)存儲(chǔ)>在哪個(gè)位置,此刻寫(xiě)的就是哪個(gè)地址。
發(fā)送要存儲(chǔ)的數(shù)據(jù)第一字節(jié)、第二字節(jié)、…注意在寫(xiě)數(shù)據(jù)的過(guò)程中,E2PROM每個(gè)字節(jié)都會(huì)>回應(yīng)一個(gè)“應(yīng)答位0”,老告訴我們寫(xiě)E2PROM數(shù)據(jù)成功,如果沒(méi)有回應(yīng)答位,說(shuō)明寫(xiě)入不成功。
發(fā)送結(jié)束信號(hào)(STOP)停止總線
注意:
在寫(xiě)數(shù)據(jù)的過(guò)程中,每成功寫(xiě)入一個(gè)字節(jié),E2PROM存儲(chǔ)空間的地址就會(huì)自動(dòng)加1,當(dāng)加到0xFF后,再寫(xiě)一個(gè)字節(jié),地址就會(huì)溢出又變成0x00。
寫(xiě)數(shù)據(jù)的時(shí)候需要注意,E2PROM是先寫(xiě)到緩沖區(qū),然后再“搬運(yùn)到”到掉電非易失區(qū)。所以這個(gè)過(guò)程需要一定的時(shí)間,AT24C02這個(gè)過(guò)程是不超過(guò)5ms!
所以,當(dāng)我們?cè)趯?xiě)多個(gè)字節(jié)時(shí),寫(xiě)入一個(gè)字節(jié)之后,再寫(xiě)入下一個(gè)字節(jié)之前,必須延時(shí)5ms才可以
從AT24C02中讀數(shù)據(jù)
讀當(dāng)前地址的數(shù)據(jù)
?
?
2、讀隨機(jī)地址的數(shù)據(jù)
?
?
MCU先發(fā)送一個(gè)開(kāi)始信號(hào)(START)啟動(dòng)總線
接著跟上首字節(jié),發(fā)送器件寫(xiě)操作地址(DEVICE ADDRESS)+寫(xiě)數(shù)據(jù)(0xA0)
注意:這里寫(xiě)操作是為了要把所要讀的數(shù)據(jù)的存儲(chǔ)地址先寫(xiě)進(jìn)去,告訴E2PROM要讀取哪個(gè)地址的數(shù)據(jù)。
發(fā)送要讀取內(nèi)存的地址(WORD ADDRESS),通知E2PROM讀取要哪個(gè)地址的信息。
重新發(fā)送開(kāi)始信號(hào)(START)
發(fā)送設(shè)備讀操作地址(DEVICE ADDRESS)對(duì)E2PROM進(jìn)行讀操作 (0xA1)
E2PROM會(huì)自動(dòng)向主機(jī)發(fā)送數(shù)據(jù),主機(jī)讀取從器件發(fā)回的數(shù)據(jù),在讀一個(gè)字節(jié)后,MCU會(huì)回應(yīng)一個(gè)應(yīng)答信號(hào)(ACK)后,E2PROM會(huì)繼續(xù)傳輸下一個(gè)地址的數(shù)據(jù),MCU不斷回應(yīng)應(yīng)答信號(hào)可以不斷讀取內(nèi)存的數(shù)據(jù)
如果不想讀了,告訴E2PROM不想要數(shù)據(jù)了,就發(fā)送一個(gè)“非應(yīng)答位NAK(1)”。發(fā)送結(jié)束信號(hào)(STOP)停止總線
3、連續(xù)讀數(shù)據(jù)
?
?
E2PROM支持連續(xù)寫(xiě)操作,操作和單個(gè)字節(jié)類似,先發(fā)送設(shè)備寫(xiě)操作地址(DEVICE ADDRESS),然后發(fā)送內(nèi)存起始地址(WORD ADDRESS),MCU會(huì)回應(yīng)一個(gè)應(yīng)答信號(hào)(ACK)后,E2PROM會(huì)繼續(xù)傳輸下一個(gè)地址的數(shù)據(jù),MCU不斷回應(yīng)應(yīng)答信號(hào)可以不斷讀取內(nèi)存的數(shù)據(jù)。E2PROM的地址指針會(huì)自動(dòng)遞增,數(shù)據(jù)會(huì)依次保存在內(nèi)存中。不應(yīng)答發(fā)送結(jié)束信號(hào)后終止傳輸。
軟件IIC和硬件IIC
IIC分為軟件IIC和硬件IIC
軟件IIC:軟件IIC通信指的是用單片機(jī)的兩個(gè)I/O端口模擬出來(lái)的IIC,用軟件控制管腳狀態(tài)以模擬I2C通信波形,軟件模擬寄存器的工作方式。
硬件IIC:一塊硬件電路,硬件I2C對(duì)應(yīng)芯片上的I2C外設(shè),有相應(yīng)I2C驅(qū)動(dòng)電路,其所使用的I2C管腳也是專用的,硬件(固件)I2C是直接調(diào)用內(nèi)部寄存器進(jìn)行配置。
硬件I2C的效率要遠(yuǎn)高于軟件的,而軟件I2C由于不受管腳限制,接口比較靈活。
審核編輯:黃飛
?
評(píng)論
查看更多