1. 程式人生 > >Arduino教程-10. 內部積體電路(I2C)

Arduino教程-10. 內部積體電路(I2C)

Arduino 內部積體電路

通訊介面I2C

I2C介面的原意是"Inter IC",只用兩條線來連線其他元件,為了方便同一個電路板上的各個元件相互通訊。
I2C至少有一個主控端(master,通常由微處理器擔任,負責傳送時鐘和地址訊號)和至少一個從端(slave,通常是感測器元件),所有I2C元件的資料線和時鐘線都連線在一起。此外,I2C的資料線和時鐘線都要連線一個電阻到電源線,電阻值通常選擇1~10KΩ,建議採用1.8kΩ。每個I2C元件的接地線必須相連。為了識別電路板上的不同元件,每個I2C從端都有一個唯一的地址編號。地址編號的長度為7位,總共可以表示27個地址(127個),

詳細I2C規範

內部積體電路(I2C)是用於微控制器和新一代專用積體電路之間的序列資料交換系統。當它們之間的距離很短(接收器和發射器通常在同一個印刷電路板上)時使用。通過兩根導線建立連線。一個用於資料傳輸,另一個用於同步(時鐘訊號)。

如下圖所示,一個裝置始終是主裝置。它在通訊開始之前執行一個從晶片的定址。這樣,一個微控制器可以與112個不同的裝置進行通訊。波特率通常為100 Kb/sec(標準模式)或10 Kb/sec(慢波特率模式)。最近出現了波特率為3.4 Mb/s的系統。通過I2C匯流排通訊的裝置之間的距離限制在幾米之內。
i2c

板的I2C引腳

I2C匯流排由兩個訊號組成 - SCL和SDA。SCL是時鐘訊號,SDA是資料訊號。當前匯流排主機總是產生時鐘訊號。一些從裝置可能迫使時鐘低電平以延遲主裝置傳送更多資料(或者在主設備嘗試將資料寫出之前請求更多的時間來準備資料)。這被稱為“時鐘伸展”。

以下是不同Arduino板的引腳:

  • Uno, Pro Mini A4 (SDA), A5 (SCL)
  • Mega, Due 20 (SDA), 21 (SCL)
  • Leonardo, Yun 2 (SDA), 3 (SCL)

Arduino I2C

我們有兩種模式 - 主程式碼和從程式碼 - 使用I2C連線兩個Arduino板。它們是:

  • Master Transmitter / Slave Receiver 主發射器/從接收器
  • Master Receiver / Slave Transmitter 主接收器/從發射器

主發射器/從接收器

讓我們現在看看什麼是主傳送器和從接收器。

主發射器

以下函式用於初始化Wire庫,並將I2C匯流排作為主器件或從器件加入。這通常只被呼叫一次。

  • Wire.begin(地址) - 在我們的例子中,地址是7位從地址,因為未指定主機,它將作為主機加入匯流排。
  • Wire.beginTransmission(地址) - 開始向給定地址的I2C從裝置傳送資料。
  • Wire.write(值) - 用於從主裝置傳輸到從裝置的佇列位元組(在beginTransmission()和endTransmission()之間的呼叫)。
  • Wire.endTransmission() - 結束由beginTransmission()開始的對從裝置的傳輸,並傳輸由wire.write()排隊的位元組。

示例

#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); 
}

從接收器

使用以下函式:

  • Wire.begin(地址) - 地址是7位從地址。

  • Wire.onReceive(收到的資料處理程式) - 當從裝置從主裝置接收資料時呼叫的函式。

  • Wire.available() - 返回Wire.read()可用於檢索的位元組數,應在Wire.onReceive()處理程式中呼叫。

示例

#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
   }
}

主接收器/從發射器

讓我們現在看看什麼是主接收器和從發射器。

主接收器

主機被程式設計為請求,然後讀取從唯一定址的從機Arduino傳送的資料位元組。

使用以下函式:

  • Wire.requestFrom(地址,位元組數) - 主裝置用於請求從裝置的位元組。然後可以使用函式- wire.available()和wire.read()檢索位元組。

示例

#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); 
}

從發射器

使用以下函式:

  • Wire.onRequest(處理程式) - 當主裝置從此從裝置請求資料時呼叫該函式。

示例

#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++; 
}