內(nèi)部集成電路(I2C)是用于微控制器和新一代專用集成電路之間的串行數(shù)據(jù)交換系統(tǒng)。當(dāng)它們之間的距離很短(接收器和發(fā)射器通常在同一個(gè)印刷電路板上)時(shí)使用。通過(guò)兩根導(dǎo)線建立連接。一個(gè)用于數(shù)據(jù)傳輸,另一個(gè)用于同步(時(shí)鐘信號(hào))。
如下圖所示,一個(gè)設(shè)備始終是主設(shè)備。它在通信開始之前執(zhí)行一個(gè)從芯片的尋址。這樣,一個(gè)微控制器可以與112個(gè)不同的設(shè)備進(jìn)行通信。波特率通常為100 Kb/sec(標(biāo)準(zhǔn)模式)或10 Kb/sec(慢波特率模式)。最近出現(xiàn)了波特率為3.4 Mb/s的系統(tǒng)。通過(guò)I2C總線通信的設(shè)備之間的距離限制在幾米之內(nèi)。
I2C總線由兩個(gè)信號(hào)組成 - SCL和SDA。SCL是時(shí)鐘信號(hào),SDA是數(shù)據(jù)信號(hào)。當(dāng)前總線主機(jī)總是產(chǎn)生時(shí)鐘信號(hào)。一些從設(shè)備可能迫使時(shí)鐘低電平以延遲主設(shè)備發(fā)送更多數(shù)據(jù)(或者在主設(shè)備嘗試將數(shù)據(jù)寫出之前請(qǐng)求更多的時(shí)間來(lái)準(zhǔn)備數(shù)據(jù))。這被稱為“時(shí)鐘伸展”。
以下是不同Arduino板的引腳:
我們有兩種模式 - 主代碼和從代碼 - 使用I2C連接兩個(gè)Arduino板。它們是:
讓我們現(xiàn)在看看什么是主發(fā)送器和從接收器。
以下函數(shù)用于初始化Wire庫(kù),并將I2C總線作為主器件或從器件加入。這通常只被調(diào)用一次。
Wire.begin(地址) - 在我們的例子中,地址是7位從地址,因?yàn)槲粗付ㄖ鳈C(jī),它將作為主機(jī)加入總線。
Wire.beginTransmission(地址) - 開始向給定地址的I2C從設(shè)備發(fā)送數(shù)據(jù)。
Wire.write(值) - 用于從主設(shè)備傳輸?shù)綇脑O(shè)備的隊(duì)列字節(jié)(在beginTransmission()和endTransmission()之間的調(diào)用)。
Wire.endTransmission() - 結(jié)束由beginTransmission()開始的對(duì)從設(shè)備的傳輸,并傳輸由wire.write()排隊(duì)的字節(jié)。
示例
#include <Wire.h> //include wire library void setup() //this will run only once { Wire.begin(); // join i2c bus as master } short age = 0; void loop() { Wire.beginTransmission(2); // transmit to device #2 Wire.write("age is = "); Wire.write(age); // sends one byte Wire.endTransmission(); // stop transmitting delay(1000); }
使用以下函數(shù):
Wire.begin(地址) - 地址是7位從地址。
Wire.onReceive(收到的數(shù)據(jù)處理程序) - 當(dāng)從設(shè)備從主設(shè)備接收數(shù)據(jù)時(shí)調(diào)用的函數(shù)。
Wire.available() - 返回Wire.read()可用于檢索的字節(jié)數(shù),應(yīng)在Wire.onReceive()處理程序中調(diào)用。
示例
#include <Wire.h> //include wire library void setup() { //this will run only once Wire.begin(2); // join i2c bus with address #2 Wire.onReceive(receiveEvent); // call receiveEvent when the master send any thing Serial.begin(9600); // start serial for output to print what we receive } void loop() { delay(250); } //-----this function will execute whenever data is received from master-----// void receiveEvent(int howMany) { while (Wire.available()>1) // loop through all but the last { char c = Wire.read(); // receive byte as a character Serial.print(c); // print the character } }
讓我們現(xiàn)在看看什么是主接收器和從發(fā)射器。
主機(jī)被編程為請(qǐng)求,然后讀取從唯一尋址的從機(jī)Arduino發(fā)送的數(shù)據(jù)字節(jié)。
使用以下函數(shù):
Wire.requestFrom(地址,字節(jié)數(shù)) - 主設(shè)備用于請(qǐng)求從設(shè)備的字節(jié)。然后可以使用函數(shù)wire.available()和wire.read()檢索字節(jié)。
示例
#include <Wire.h> //include wire library void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output } void loop() { Wire.requestFrom(2, 1); // request 1 bytes from slave device #2 while (Wire.available()) // slave may send less than requested { char c = Wire.read(); // receive a byte as character Serial.print(c); // print the character } delay(500); }
使用以下函數(shù):
Wire.onRequest(處理程序) - 當(dāng)主設(shè)備從此從設(shè)備請(qǐng)求數(shù)據(jù)時(shí)調(diào)用該函數(shù)。
示例
#include <Wire.h> void setup() { Wire.begin(2); // join i2c bus with address #2 Wire.onRequest(requestEvent); // register event } Byte x = 0; void loop() { delay(100); } // function that executes whenever data is requested by master // this function is registered as an event, see setup() void requestEvent() { Wire.write(x); // respond with message of 1 bytes as expected by master x++; }
更多建議: