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