1. 什么是I2C?
I2C全拼Inter Integrated Circuit,簡稱IIC或I2C,是由Philips公司開發(fā)的兩線時串行總線,用于SOC與外設(shè)的連接通訊,它只需要兩根線就能實現(xiàn)I2C的通訊,采用主從模式,主的一方可以讀寫數(shù)據(jù),而從的一方只能等待被讀寫。從的一方?jīng)]有主動權(quán)。
I2C是雙向通訊的,由兩根線完成,分別是:SDA(串行數(shù)據(jù)線)、SCL(串行時鐘線),接口輸出模式為開漏輸出,其總線接口已經(jīng)集成到SOC內(nèi)部,我們只需要通過原理圖找到它的接口,在用外設(shè)的杜邦線或者其它方法連接到此接口上就可以實現(xiàn)I2C的通訊。
SDA與SCL都外接了上拉電阻,所以當SDA空閑時刻輸出的永遠是高電平,它對外設(shè)也有一定要求,要求外設(shè)的輸出模式也是開漏輸出,因為這跟它本身的電路實現(xiàn)有關(guān),若兩個電路接口模式不一則是無法完成正常通訊的。
其中I2C里的上拉電阻也不是隨便用的,因為電阻值越高意味著信號拉高周期越長,那么通訊周期時間就越高,速率就下來了。
I2C為每個設(shè)備提供了一個地址,可以通過這個地址找到不同的設(shè)備,來表明不同的設(shè)備,只有從設(shè)備收到是自己的地址時才響應(yīng)。
因為連接在I2C上的可能有很多個設(shè)備,從設(shè)備需要設(shè)置自己的地址,主設(shè)備不用,因為主設(shè)備是不會被從設(shè)備讀寫的,主設(shè)備是負責讀寫其它設(shè)備的。
通訊時會有一個起始數(shù)據(jù),這個數(shù)據(jù)是9個bit位,前7位是從設(shè)備地址,最后一位是方向(0/1(讀或?qū)?)
這也就表明從設(shè)備的地址不能超過7個bit
2. I2C組成原理
架構(gòu)圖:
SMBA線用于SMBUS 的警告信號,I2C 通訊沒有使用,可以忽略
I2C內(nèi)部是有自己的控制單元的,用于處理I2C的通訊,可以說是一個小芯片,它不屬于CPU,它只是被集成SOC里(看架構(gòu),有的架構(gòu)是沒有的)
3. I2C的特性
僅需兩根線
接口集成在PCB內(nèi)部
因為是開漏輸出,電流消耗較小(高電流由上拉電阻完成,通常情況下器件不需要輸出高電平所以這塊功耗較小)
世界級標準,大多數(shù)開發(fā)板都支持
一對多,一根線接多跟外設(shè),通過地址區(qū)分,節(jié)省排版空間
4. I2C的通訊模式
雙向傳輸總線:
?
模式 | 速率(kbit/s) |
---|---|
標準模式(Standard-mode) | 100 |
快速模式(Fast-mode) | 400 |
快速模式+(Fast-mode Plus) | 1M |
高速模式(High-speed mode) | 3.4M |
?
單向傳輸總線:
?
模式 | 速率(kbit/s) |
---|---|
超快速模式(Ultra Fast-mode) | 5M |
?
這些模式是根據(jù)速率來決定的,也就是說我們將I2C通訊速率設(shè)置成與上面對應(yīng)的速率那么就是處于這個模式當中,其中說是這么快其實是有延遲的,因為要流過上拉電阻,這個取決于上拉電阻的阻值,因為信號在經(jīng)過上拉電阻時會有一個周期變化,這個周期變化區(qū)別于阻值。
設(shè)置方法:
我們需要根據(jù)當前的PCLK時鐘頻率來計算的,這和設(shè)置PWM占空比類似,都需要經(jīng)過計算然后設(shè)置I2C里的CCR時鐘控制寄存器的值,因為如果頻率不同是無法正常工作的。
如:時鐘頻率是66MHZ,預(yù)分頻值是65MHZ,系數(shù)是1/2那么計算公式如下:
時鐘頻率=PCLK/((預(yù)分頻值+1))/分頻系數(shù)
PCLK我們得知是66,分頻值我們設(shè)置的是65,分頻系數(shù)是1/2也就是除于2
所以公式:66/(65+1)/2 =0.5
在將0.5轉(zhuǎn)化為HZ的單位:0.5*1000=500KHZ,這里還有一個公式,就是算HZ轉(zhuǎn)秒,赫茲的倒數(shù)就是它的秒這個公式:(1/500)=0.002ms,1毫秒=1000微秒,0.002毫秒等于2微秒,通過這樣的算法公式就可以得知我們現(xiàn)在的頻率是每2微秒工作一次
我們想讓它每0.5毫秒工作一次,所以TCNTB的值=500毫秒/當前微秒頻率2
500/2=250,所以TCNTB的值應(yīng)該為250,當然你也可以這也算,2微秒一次,1毫秒=1000微秒,0.5毫秒就等于500微秒,500微秒/2微秒=250,就得出經(jīng)過250次2微秒后就到達了500微秒,而500微秒就等于0.5毫秒
5. I2C的通訊過程
通訊步驟:
開始信號:SCL為高電平而SDA由高到低的跳變,表示產(chǎn)生一個起始條件
結(jié)束信號:SCL為高電平而SDA由低到高的跳變,表示產(chǎn)生一個 停止條件
應(yīng)答信號:當發(fā)送完信號之后則拉低
總線在空閑狀態(tài)時,SCL和SDA都保持著高電平
這三種信號里,起始信號是必須需要的,而結(jié)束信號和應(yīng)答信號都可以視情況不要。
在起始條件產(chǎn)生后,總線處于忙狀態(tài),由本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備獨占,其他I2C器件無法訪問總線;而在停止條件產(chǎn)生后,本次數(shù)據(jù)傳輸?shù)闹鲝脑O(shè)備 將釋放總線,總線再次處于空閑狀態(tài)
傳輸過程:
每次傳輸時的數(shù)據(jù)/地址以9位bit進行傳輸,前8位是數(shù)據(jù),最后一位是應(yīng)答位
傳輸時高位在前,低位在后
主設(shè)備在SCL和SDA都處于高電平狀態(tài)時,先將SDA拉到低電平,然后在將SCL也拉入低電平,這樣SDA產(chǎn)生了一個下降沿的信號,從設(shè)備檢測到之后便知道主設(shè)備發(fā)來了起始信號,那么從設(shè)備需要主動拉高SDA線告訴主設(shè)備我準備好了
這個電平變化不是說一個時間點的變化,比如上一秒是高電平下一秒是低電平這不算變化,時間點變化是要求在一個周期里某一時間段處于高電平,某一時間段處于低電平,整個周期里完成這樣一個動作才屬于上升沿或下降沿變化,這個周期取決于I2C的時鐘頻率
如下圖的周期變化,假設(shè)一個周期是1.2毫秒,那么這個毫秒里的周期變化如下
T1到T2之間處于高電平,T3到T4之間處于低電平,然后整個周期就變成了下降沿的信號
然后主設(shè)備會在SCL線上產(chǎn)生時鐘周期的脈沖信號,即發(fā)高電平,每產(chǎn)生一個脈沖信號都會從SDA線上發(fā)送一個數(shù)據(jù)出去,然后從設(shè)備檢測到脈沖信號了就從SDA線上去讀一個BIT位,在產(chǎn)生脈沖信號之后,SCL是處于低電平的,那么此時SDA電平會根據(jù)傳輸?shù)?a target="_blank">數(shù)字信號進行翻轉(zhuǎn)(為了防止數(shù)據(jù)不穩(wěn)定,要求在SCl處于低電平時SDA才允許改變電平值,SCL發(fā)送一次脈沖信號后會要求拉低電平)
首先最開始發(fā)送的是地址信息,每次有效位為8位,當主設(shè)備發(fā)送8位之后就不會在發(fā)了,且發(fā)送完八位以后會主動讓SDA線一直處于高電平(因為SDA線發(fā)送BIT可能是高或低電平,可能第8位是低電平所以需要拉高回來),然后就會一直等待從設(shè)備拉低,當從設(shè)備拉低以后那么主設(shè)備監(jiān)聽到之后就會認為此次通訊是正確的
然后接下來就可以發(fā)送數(shù)據(jù)位了,與地址信息一樣,SCL產(chǎn)生脈沖之后SDA進行翻轉(zhuǎn),從設(shè)備進行讀取,當發(fā)送完成之后就需要產(chǎn)生停止位,這個是由主設(shè)備完成的,會拉高SCL電平使其一直處于高電平,然后將SDA進行周期變化:上升沿,即在一定周期里拉低電平然后在拉高電平,然后此時SCL與SDA都處于高電平模式,則代表總線處于空閑狀態(tài)可以被其它設(shè)備占用
從設(shè)備是需要實時監(jiān)聽SCL的電平變化,來完成對應(yīng)的動作
以下是發(fā)送170(十六進制:0xAA; 二進制:1010 1010)到從設(shè)備的傳輸時序:
總結(jié)理解起始與結(jié)束信號就是:
起始條件:SCL線是高電平時,SDA線從高電平向低電平切換。
停止條件:SCL線是高電平時,SDA線從低電平向高電平切換。
這其中還有重復(fù)起始條件,即不用停止符號,只需要發(fā)送一個重復(fù)起始條件后續(xù)可以發(fā)送任意字節(jié)的數(shù)據(jù),當全部發(fā)送完成之后在發(fā)送停止條件
即在不釋放總線的情況下給從設(shè)備發(fā)送Sr信號,然后重復(fù)上一次的傳輸,這樣做的好處在于不會出現(xiàn)在傳輸期間被別的設(shè)備搶占的情況,因為每次傳輸結(jié)束都會有一定的空閑時間,如果這個時間周期被別的設(shè)備占用會出現(xiàn)一些數(shù)據(jù)不完整的情況,因為每次傳輸只能傳輸一個字節(jié)的有效數(shù)據(jù)位,每次通訊都要產(chǎn)生起始和結(jié)束信號,所以會有一定的空閑時間
具體的通訊步驟可以參考I2C官方文檔
6. I2C接口工作模式
I2C接口有四種工作模式
?
工作模式 | 介紹 |
---|---|
從發(fā)送器模式 | 從設(shè)備收到主設(shè)備發(fā)來的ADDR地址后,將內(nèi)部的數(shù)據(jù)寄存器里的值通過數(shù)據(jù)控制模塊,發(fā)送給SDA總線,這種模式一般應(yīng)用于主設(shè)備讀取從設(shè)備里的數(shù)據(jù) |
從接收器模式 | 從設(shè)備收到主設(shè)備發(fā)來的ADDR地址后,通過數(shù)據(jù)控制模塊將SDA總線的數(shù)據(jù)存于到數(shù)據(jù)寄存器中 |
主發(fā)送器模式 | 在發(fā)送ADDR地址后且得到從設(shè)備響應(yīng)后將數(shù)據(jù)寄存器里的值發(fā)送到SDA總線上 |
主接收器模式 | 在發(fā)送ADDR地址后且得到從設(shè)備響應(yīng)后將SDA總線上的數(shù)據(jù)寫入到數(shù)據(jù)寄存器中 |
?
數(shù)據(jù)寄存器一般是DR寄存器(數(shù)據(jù)緩存寄存器),這塊寄存器是等待內(nèi)部程序?qū)⑵渥x走的
其中因為是高位到地位發(fā)送的,所以內(nèi)部會有一個位移寄存器的過程才能寫入到DR寄存器
7. 硬件拉高拉低的過程
I2C的SDA與SCL都外接了上拉電阻,如果一直處于拉高狀態(tài)那么只能輸出高電平無法輸出低電平,那么數(shù)字邏輯信號時鐘是1,這樣結(jié)果是不對的,所以需要有一個拉低的過程才能保證傳輸?shù)腷it位是有效且正確的。
I2C內(nèi)部有一個邏輯控制器,負責控制這一塊,當需要上拉時候會控制FET(場效應(yīng)管,主要作用是控制半導(dǎo)體器件,控制電阻值),來拉低上拉電阻值使其電流固定在低電平值范圍,產(chǎn)生低電平信號
拉低:
拉高:
S3C2400的物理層的拓撲結(jié)構(gòu)(僅供參考):
8. 一對多
I2C給每個從設(shè)備設(shè)置地址,然后通過發(fā)送地址位來選擇要操控哪個從設(shè)備。
在每個從設(shè)備連接后需要設(shè)置自己的地址,便于I2C主設(shè)備查找。
每個設(shè)備連接到I2C的SDA與SCL上,然后I2C主設(shè)備對這條線發(fā)送地址當從設(shè)備收到以后來確定是否是尋找自己
下圖的連接就是將所有設(shè)備的SCL與SDA連接到I2C的主設(shè)備上,也就是說將I2C主設(shè)備的SDA與SCL引出來,然后從設(shè)備接到這根線上去,然后發(fā)送數(shù)據(jù)時接在這跟線上的所有設(shè)備都能監(jiān)聽到電平變化,就像socket的廣播模式一樣。
主設(shè)備是不需要設(shè)置自身地址的,因為不會有人找它,當然如果要與其它外設(shè)進行合作開發(fā),可以設(shè)置一個自己的地址,并編寫監(jiān)聽代碼讓自己做主或從
9. 開發(fā)流程
主機接收模式:
主機發(fā)送模式:
審核編輯:黃飛
評論
查看更多