1.IIC概述
1基于對話的形式完成,不需要同時進行發送和接收所以刪掉了一根數據線,變成半雙工2為了安全起見添加了應答機制3可以接多個模塊,且互不干擾4異步時序,要求嚴格,發送過程中不能暫停,所以需要同步時序+一條時鐘線。
模式支持一主多從,和多主多從。仲裁器可以仲裁,也需要時鐘線
2.IIC引腳說明
IIC總線只需要兩根引腳就可以實現通信,一根是數據線(SDA),另一根是時鐘線(SCL),所有通過IIC接口通信的外圍器件都掛載在IIC總線上,通過這種機制就可以實現多機通信。
可以看到,外圍器件的時鐘線和數據線都是掛載在IIC總線(由主控芯片提供),并且在空閑狀態下所有器件的時鐘線(SCL)和數據線(SDA)都被總線的上拉電阻拉高,這樣就可以把SDA引腳和SCL引腳設置為開漏模式即可,好處是防止短路。
尋址
每個掛載在IIC總線上的外圍器件都有獨立的器件地址,主機發送開始信號后,只需要發送想要通信的設備的地址,如果設備收到地址并且匹配正確,則開始進行單獨通信。
3.上拉電阻的作用
- 提供無效應答
當主機在總線上發送數據時(器件地址),從機在接收到該數據后應當回復主機一個有效應答(低電平),但是若主機發送的是器件地址,而從機上沒有與該器件地址匹配的從機,此時主機就會接收到來自上拉電阻提供的無效應答(高電平)
?????2.多主模式仲裁
IIC支持多主模式,多個主機怎么判定那個主機在當前通信總線上有效呢?
上拉電阻在IO引腳配置為開漏輸出后會有線與功能。
線與功能:多主模式下,只要有一個主機發送0,總線上就為低電平,若都發送1,則總線上就是高電平。(有0為0,全1為1)
由線與功能決定在多主模式通信時,哪個主機先發送1信號,誰先被淘汰。最終留下的就是進入通信的主機。
若只有一個主機,通信總線可以配置為通用的推挽輸出,但是多主必須配置為開漏輸出
4.通信過程
可以看到,在建立通信的時候主機需要發送開始信號,緊接著主機需要發出從器件的設備地址(7bit+1bit),從設備的物理地址是7bit,但是由于只有一根數據線,就需要說清楚數據的傳輸方向,數據的傳輸方向通過從設備的地址最低位進行表示(最低位是0,表示寫操作,最低位是1,表示讀操作),IIC總線提供了應答機制,也就是說從機收到了1個字節的數據之后,會在第九個脈沖發送給主機一個應答信號(1bit),如果主機收到從機的應答信號,則主機可以繼續發送數據,反之,如果主機沒有收到從機發送的應答信號,那主機就不應該繼續發送數據,而是應該主動發出一個停止信號,表示停止通信。
5.器件地址
最低位=0,表示寫操作? 10100000---寫地址 ---主機給從機發數據(0xA0)
最低位 = 1,表示讀操作? 10100001(0xA1)---讀地址---主機從從機讀數據(從機給主機發送數據)
1010說明書查的,000是電路設計時接地可以查原理圖,0寫1讀
6.IIC時序
6.1 空閑狀態
指的是不傳輸任何數據的時候就被稱為空閑狀態,IIC總線規定SDA數據線和SCL時鐘線在不傳輸數據的時候都應該設置高電平,表示空閑。
6.2 開始信號
在SCL(時鐘線)為高電平期間,SDA(數據線)從高電平跳變到低電平(下降沿)。
SDA: ----------------\_____
↓ (下降沿)
SCL: --------/ˉˉˉˉˉˉˉ\_____
↑ (SCL高時SDA跳變)
void OELD_IIC_Start(void)
{
//1.設置SDA引腳為輸出模式
OLED_IIC_SDAOutputMode();
//2.確保SDA和SCL為高電平
OLED_IIC_SCL_WRITE(1);
OLED_IIC_SDA_WRITE(1);
Delay_us(5); ? ? ? ? ? ?//提高程序可靠性
//3.把SDA引腳拉低
OLED_IIC_SDA_WRITE(0);
Delay_us(5); ? // IIC總線的通信速率為100KHZ ?1000000us = 100000HZ ?10us = 1HZ?
//4.把SCL引腳拉低,表示準備通信
OLED_IIC_SCL_WRITE(0);
}
6.3 數據發送
6.4 應答信號
6.5 數據接收
6.6 停止信號
停止信號由主設備(Master)發出,時序特征為:SCL(時鐘線)保持高電平期間SDA(數據線)從低電平跳變到高電平(上升沿)
SDA: _____/ˉˉˉˉˉˉˉˉ
↑ (上升沿)
SCL: ˉˉˉˉˉˉˉˉˉˉˉˉˉˉ
(保持高電平)
void OLED_IIC_Stop(void)
{
//1.設置SDA引腳為輸出模式
OLED_IIC_SDAOutputMode();
?? ?//2.確保SDA和SCL為低電平
OLED_IIC_SCL_WRITE(0);
OLED_IIC_SDA_WRITE(0);
//4.把SCL引腳拉高
OLED_IIC_SCL_WRITE(1);
Delay_us(5);
//5.把SDA引腳拉高
OLED_IIC_SDA_WRITE(1);
Delay_us(5); ?//確保SDA的電平狀態可以被其他從器件檢測到
}