內(nèi)部集成電路(I2C)是用于微控制器和新一代專用集成電路之間的串行數(shù)據(jù)交換系統(tǒng)。當(dāng)它們之間的距離很短(接收器和發(fā)射器通常在同一個印刷電路板上)時使用。通過兩根導(dǎo)線建立連接。一個用于數(shù)據(jù)傳輸,另一個用于同步(時鐘信號)。
如下圖所示,一個設(shè)備始終是主設(shè)備。它在通信開始之前執(zhí)行一個從芯片的尋址。這樣,一個微控制器可以與112個不同的設(shè)備進行通信。波特率通常為100 Kb/sec(標準模式)或10 Kb/sec(慢波特率模式)。最近出現(xiàn)了波特率為3.4 Mb/s的系統(tǒng)。通過I2C總線通信的設(shè)備之間的距離限制在幾米之內(nèi)。
I2C總線由兩個信號組成 - SCL和SDA。SCL是時鐘信號,SDA是數(shù)據(jù)信號。當(dāng)前總線主機總是產(chǎn)生時鐘信號。一些從設(shè)備可能迫使時鐘低電平以延遲主設(shè)備發(fā)送更多數(shù)據(jù)(或者在主設(shè)備嘗試將數(shù)據(jù)寫出之前請求更多的時間來準備數(shù)據(jù))。這被稱為“時鐘伸展”。
以下是不同Arduino板的引腳:
我們有兩種模式 - 主代碼和從代碼 - 使用I2C連接兩個Arduino板。它們是:
讓我們現(xiàn)在看看什么是主發(fā)送器和從接收器。
以下函數(shù)用于初始化Wire庫,并將I2C總線作為主器件或從器件加入。這通常只被調(diào)用一次。
Wire.begin(地址) - 在我們的例子中,地址是7位從地址,因為未指定主機,它將作為主機加入總線。
Wire.beginTransmission(地址) - 開始向給定地址的I2C從設(shè)備發(fā)送數(shù)據(jù)。
Wire.write(值) - 用于從主設(shè)備傳輸?shù)綇脑O(shè)備的隊列字節(jié)(在beginTransmission()和endTransmission()之間的調(diào)用)。
Wire.endTransmission() - 結(jié)束由beginTransmission()開始的對從設(shè)備的傳輸,并傳輸由wire.write()排隊的字節(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ù)時調(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ā)射器。
主機被編程為請求,然后讀取從唯一尋址的從機Arduino發(fā)送的數(shù)據(jù)字節(jié)。
使用以下函數(shù):
Wire.requestFrom(地址,字節(jié)數(shù)) - 主設(shè)備用于請求從設(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è)備請求數(shù)據(jù)時調(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++; }
更多建議: