概述
IIC(Inter-Integrated Circuit)其實(shí)是IICBus簡(jiǎn)稱,所以中文應(yīng)該叫集成電路總線,它是一種串行通信總線,使用多主從架構(gòu),由飛利浦公司在1980年代為了讓主板、嵌入式系統(tǒng)或手機(jī)用以連接低速周邊設(shè)備而發(fā)展。I2C的正確讀法為“I平方C”("I-squared-C"),而“I二C”("I-two-C")則是另一種錯(cuò)誤但被廣泛使用的讀法。自2006年10月1日起,使用I2C協(xié)議已經(jīng)不需要支付專利費(fèi),但制造商仍然需要付費(fèi)以獲取I2C從屬設(shè)備地址。
接口
I2C串行總線一般有兩根信號(hào)線,一根是雙向的數(shù)據(jù)線SDA,另一根是時(shí)鐘線SCL。所有接到I2C總線設(shè)備上的串行數(shù)據(jù)SDA都接到總線的SDA上,各設(shè)備的時(shí)鐘線SCL接到總線的SCL上。
- SCL - 串行時(shí)鐘線
- SDA - 串行數(shù)據(jù)線
為了避免總線信號(hào)的混亂,要求各設(shè)備連接到總線的輸出端時(shí)必須是漏極開(kāi)路(OD)輸出或集電極開(kāi)路(OC)輸出。設(shè)備上的串行數(shù)據(jù)線SDA接口電路應(yīng)該是雙向的,輸出電路用于向總線上發(fā)送數(shù)據(jù),輸入電路用于接收總線上的數(shù)據(jù)。而串行時(shí)鐘線也應(yīng)是雙向的,作為控制總線數(shù)據(jù)傳送的主機(jī),一方面要通過(guò)SCL輸出電路發(fā)送時(shí)鐘信號(hào),另一方面還要檢測(cè)總線上的SCL電平,以決定什么時(shí)候發(fā)送下一個(gè)時(shí)鐘脈沖電平;作為接受主機(jī)命令的從機(jī),要按總線上的SCL信號(hào)發(fā)出或接收SDA上的信號(hào),也可以向SCL線發(fā)出低電平信號(hào)以延長(zhǎng)總線時(shí)鐘信號(hào)周期??偩€空閑時(shí),因各設(shè)備都是開(kāi)漏輸出,上拉電阻Rp使SDA和SCL線都保持高電平。任一設(shè)備輸出的低電平都將使相應(yīng)的總線信號(hào)線變低,也就是說(shuō):各設(shè)備的SDA是“與”關(guān)系,SCL也是“與”關(guān)系。 因此SDA和SCL 可以被拉低為低電平,但是不能被驅(qū)動(dòng)為高電平,所以每條線上都要使用一個(gè)上拉電阻,默認(rèn)情況下將其保持在高電平。 IIC 總線上數(shù)據(jù)的傳輸速率在標(biāo)準(zhǔn)模式下可達(dá) 100kbit/s 在快速模式下可達(dá) 400kbit/s 在高速模式下可達(dá) 3.4Mbit/s。
通信協(xié)議
SDA 線上的數(shù)據(jù)必須在時(shí)鐘的高電平周期保持穩(wěn)定。數(shù)據(jù)線的高或低電平狀態(tài)只有在 SCL 線的時(shí)鐘信號(hào)是低電平時(shí)才能改變。
空閑狀態(tài)
SDA為高電平,SCL為高電平。
起始狀態(tài)
其中一種情況是在 SCL 線是高電平時(shí) SDA 線從高電平向低電平切換,產(chǎn)生一個(gè) 下降沿 ,這個(gè)情況表示起始條件。
結(jié)束狀態(tài)
當(dāng) SCL 是高電平時(shí) SDA 線由低電平向高電平切換,產(chǎn)生一個(gè) 上升沿 ,這個(gè)情況表示停止條件。
傳輸數(shù)據(jù)
器件地址位
由于IIC總線上可能掛載著多臺(tái)設(shè)備,所以主設(shè)備在傳輸有效數(shù)據(jù)之前要先指定從設(shè)備的地址, 大多數(shù)從設(shè)備的地址是7位的,還有部分設(shè)備支持10位尋址 ,主設(shè)備如果需要向從機(jī)發(fā)送/接收數(shù)據(jù),首先要發(fā)送對(duì)應(yīng)從機(jī)的地址,然后會(huì)匹配總線上掛載的從機(jī)的地址。將數(shù)據(jù)發(fā)送至SDA數(shù)據(jù)線上即可。
讀寫(xiě)位
緊接著的第 8 位是數(shù)據(jù)方向位(R/ W) ----'0'表示發(fā)送(寫(xiě)),'1'表示請(qǐng)求數(shù)據(jù)(讀)。
應(yīng)答信號(hào)位
主設(shè)備每發(fā)送完8bit數(shù)據(jù)后等待從設(shè)備的ACK。 即在第9個(gè)clock,若從設(shè)備發(fā)ACK,SDA會(huì)被拉低。 若沒(méi)有ACK,SDA會(huì)被置高,這會(huì)引起主設(shè)備發(fā)生RESTART或STOP流程,當(dāng)ACK=0時(shí)為有效應(yīng)答位,說(shuō)明從機(jī)已經(jīng)成功接收到該字節(jié),若為1則說(shuō)明接受不成功。
數(shù)據(jù)地址位
當(dāng)找到往哪個(gè)設(shè)備寫(xiě)數(shù)據(jù)之后,就開(kāi)始尋址往這個(gè)設(shè)備的特定地址寫(xiě)數(shù)據(jù),和上述的發(fā)送器件地址一樣,直接將地址數(shù)據(jù)發(fā)送至SDA線即可。
數(shù)據(jù)位
發(fā)送到 SDA 線上的每個(gè)字節(jié)必須為8位,每次傳輸可以發(fā)送的字節(jié)數(shù)量不受限制,每個(gè)字節(jié)后必須跟一個(gè)響應(yīng)位,首先傳輸?shù)氖菙?shù)據(jù)的最高位 (MSB) 。
示例
設(shè)置器件地址為0x78(0111 1000),數(shù)據(jù)地址為0x40(0100 0000),寫(xiě)入數(shù)據(jù)0xAA(1010 1010)。
HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,data_i,1,0x100);
查看HAL_I2C_Mem_Write說(shuō)明可以得知,目標(biāo)設(shè)備地址在調(diào)用接口之前,數(shù)據(jù)表中設(shè)備的7位地址值必須左移;即發(fā)送到從設(shè)備的數(shù)據(jù)已經(jīng)右移了一位,所以0x78(0111 1000)右移一位變成0x3c(011 1100)。
/**
* @brief Write an amount of data in blocking mode to a specific memory address
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @param DevAddress Target device address: The device 7 bits address value
* in datasheet must be shifted to the left before calling the interface
* @param MemAddress Internal memory address
* @param MemAddSize Size of internal memory address
* @param pData Pointer to data buffer
* @param Size Amount of data to be sent
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
通過(guò)示波器抓取的波形如下所示。
-
在空閑狀態(tài),SDA和SCL都是處于高電平狀態(tài)。
-
在起始狀態(tài),SDA先產(chǎn)生一個(gè)下降沿,之后SCL也出現(xiàn)一個(gè)下降沿,此時(shí)數(shù)據(jù)傳輸開(kāi)始。
-
在傳輸狀態(tài),由于傳輸速率為100kbit/s,故SCL時(shí)鐘的切換時(shí)間為5us,一個(gè)周期為10us;當(dāng)SCL為1的時(shí)候,SDA不會(huì)發(fā)生改變,故檢測(cè)SDA信號(hào)線的數(shù)據(jù),當(dāng)為低電平則為0,高電平則為1.
-
在讀寫(xiě)狀態(tài),當(dāng)SDA數(shù)據(jù)為0的時(shí)候,為寫(xiě)狀態(tài)。
-
在應(yīng)答狀態(tài),當(dāng)SDA數(shù)據(jù)為0的時(shí)候,為應(yīng)答狀態(tài)。 上述為成功傳輸?shù)睦?,若不成功傳輸,設(shè)置器件地址為0x77(0111 0111),數(shù)據(jù)地址為0x40(0100 0000),寫(xiě)入數(shù)據(jù)0xAA(1010 1010)。
HAL_I2C_Mem_Write(&hi2c1 ,0x77,0x40,I2C_MEMADD_SIZE_8BIT,data_i,1,0x100);
由于地址位0x77(0111 0111)右移一位,故發(fā)送出去的為0x3B(011 1011),通過(guò)示波器抓取的波形如下所示。
- 在應(yīng)答狀態(tài),由于沒(méi)有連接0x77地址(實(shí)際發(fā)送為0x3B)的設(shè)備,當(dāng)SDA數(shù)據(jù)為1的時(shí)候,為非應(yīng)答狀態(tài),之后進(jìn)入復(fù)位或者停止。
審核編輯:湯梓紅
-
IIC
+關(guān)注
關(guān)注
11文章
300瀏覽量
38333 -
通訊協(xié)議
+關(guān)注
關(guān)注
10文章
274瀏覽量
20354
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論