Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 3

Arduino 主從機之間的 I2C 通訊實驗

I2C 匯流排定義 I2C(‘intel’ -Integrated Circuit)匯流排是一種由 PHILIPS 公司


開發的兩線式串列匯流排,用於連接微控制器及其週邊設備。在主從通信中,
可以有多個 I2C 匯流排器件同時接到 I2C 匯流排上,通過位址來識別通信物件。
I2C 匯流排是由資料線 SDA 和時鐘 SCL 構成的串列匯流排,可發送和接收資
料。在 CPU 與被控 IC 之間、IC 與 IC 之間進行雙向傳送,最高傳送速率
100kbps。各種被控制電路均並聯在這條匯流排上,但就像電話機一樣只有撥
通各自的號碼才能工作,所以每個電路和模組都有唯一的位址,在資訊的傳輸
過程中,I2C 匯流排上並接的每一模組電路既可以是主控器(或被控器),又
可以是發送器(或接收器),這取決於它所要完成的功能。

我通過這次 IIC 通訊實驗把這 10 個 I2C 通訊命令全部應用到了。

我現在採用老版本 A rduino-0018 程式設計,老版本 I2C 通訊的發送資料命令


是 send(),接受資料命令是 receive(),最新版本 Arduino 1.0 的發送資料的命
令是 write(),接受資料的命令是 read(),這一點要注意啊,看清楚自己下載應
用的是什麼版本的 Arduino 程式設計軟體。Arduino 程式下載位址:http://
arduino.cc/en/Main/Software

I2C 實驗說明: 主機向從機迴圈發送字串"light is "和位元組 x,x 為 1 或 0,


從機接收後,把資料顯示在它的串口監視器中,如上圖。然後當主機通知從機向
它上傳資料時,會把 x 值再上傳回主機,然後賦值給變數 c。當主機程式判斷 c 為 1,則點
亮主機數位埠 13 相連的 LED,否則熄滅 LED。

通過這個實驗把主從機之間的雙向通訊都詮釋出來了。
實驗全景圖:
把雙 Arduino 控制器的 SCL 和 SDA 以及 GND 三根引腳用杜邦線相連,如果
不是兩個 Arduino 分別獨立供電,您就要把雙 Arduino 控制器的 VCC 也連一起,
它們共用一個電源。這次實驗就是把這四根線 SCL 和 SDA 以及 GND、VCC 都互
連起來了。Arduino 的 SCL 引腳位於模擬埠 5,SDA 引腳位於模擬埠 4。

Arduino 主機程式:(與 I2C 通訊相關的命令用藍色標


注)
/*主機向從機迴圈發送字串"light is "和位元組 x,x 為 1 或 0
從機接收到主機發來的資料後,當主機通知從機向它上傳資料時
會把 x 值再上傳回主機,然後賦值給變數 c。
當主機程式判斷 c 為 1,則點亮 LED,否則熄滅 LED。*/
#include 《Wire.h>//聲明 I2C 庫檔
#define LED 13
byte x = 0;//變數 x 決定 LED 的亮滅
//初始化
void setup()
{
Wire.begin(); // 加入 i2c 匯流排,作為主機
pinMode(LED,OUTPUT);//設置數位埠 13 為輸出
}
//主程序
void loop()
{
Wire.beginTransmission(4); //發送資料到設備號為 4 的從機
Wire.send("light is "); // 發送字串"light is "
Wire.send(x); // 發送變數 x 中的一個位元組
Wire.endTransmission(); // 停止發送

x++;//變數 x 加 1
if(x==2)//如果變數 x 的值為 2,則把 x 值轉為 0
x=0;
delay(1000);//延時 1s

Wire.requestFrom(4, 1); //通知 4 號從機上傳 1 個位元組


while(Wire.available()>0) // 當主機接收到從機資料時
{
byte c = Wire.receive(); //接收一個位元組賦值給 c
//判斷 c 為 1,則點亮 LED,否則熄滅 LED。
if(c==1)
{digitalWrite(LED,LOW);}
else
{digitalWrite(LED,HIGH);}
}
delay(1000);//延時 1s
}

Arduino 從機程式:(與 I2C 通訊相關的命令用藍色標


注)
/*迴圈接收主機發送來的資料包,同時顯示在串口監視器上

把資料包的最後一個位元組,再上傳回主機
*/
#include 《Wire.h>//聲明 I2C 庫檔
int x;//變數 x 值決定主機的 LED 是否點亮
//初始化
void setup()
{
Wire.begin(4); // 加入 i2c 匯流排,設置從機位址為 #4
Wire.onReceive(receiveEvent); //註冊接收到主機字元的事件
Wire.onRequest(requestEvent); // 註冊主機通知從機上傳資料的事件
Serial.begin(9600); //設置串口串列傳輸速率
}
//主程序
void loop()
{
delay(100);//延時
}

// 當從機接收到主機字元,執行該事件
void receiveEvent(int howMany)
{
while( Wire.available()>1) // 迴圈執行,直到資料包只剩下最後一個字

{
char c = Wire.receive(); // 作為字元接收位元組
Serial.print(c); // 把字元列印到串口監視器中
}
//接收主機發送的資料包中的最後一個位元組
x = Wire.receive(); // 作為整數接收位元組
Serial.println(x); //把整數列印到串口監視器中,並回車
}

//當主機通知從機上傳資料,執行該事件
void requestEvent()
{
//把接收主機發送的資料包中的最後一個位元組再上傳給主機
Wire.send( x); // 回應主機的通知,向主機發送一個位元組資料
}
我通過這次 I2C 通訊實驗把這 10 個 Arduino 的 I2C 通訊命令全部應用到了,
仔細看實驗程式注釋,並實踐一次,就可以瞭解這 Arduino 控制器的 I2C 命令
如何應用了。

來源程式請下載:程式.zip

在數位通信各種協定中,相對 Ethernet, USB, SATA, PCI-Express 等傳送速


率達數百上千百萬位元組每秒的匯流排,I2C 和 SPI 常稱為“小”協議。但是,我
們不能忘記的是各種匯流排的用途是什麼。“大”協定是用於系統外的整個系統
之間通信的,“小”協定是用於系統內各晶片間的通信,沒有跡象表明“大”協議有
必要取代“小”協議。I2C 和 SPI 的存在和流行體現了“夠用就好”的哲學。

You might also like