指令 | 發出耆 | 作用 |
---|---|---|
Wire.begin([<address>]); | master / slave | 啟動 Wire (由於 i2c 是用 Wire 的, 這就等同啟動 i2c 了) |
Wire.beginTransmission(<address>); | master | 開始對 <address> 的連線 |
Wire.endTransmission(); | master | 關閉之前的連線 |
i2c 地址設定
i2c address 就像是你家中的地址, 每個 slave 都有自己的地址, 由於線路上只有一個 master, 加上 slave 只可以向 master 通訊, 所以 master 是不需地址的.
設定 i2c 地址, 基本上是沒有限制的, 只要同一線路上, 沒有重複就可以了.
要設定 slave 板子的地址, 只需要執行 Wire.begin(<地址>); 而 master 因為不需要地址, 只要 Wire.begin() 就可以了,.
以下是一個 slave 設定的例子, 把 slave 板子的地址設定為 0x12, 上載到 slave 板子上去執行就可以了.
#include <Wire.h> #define SLAVE_ADDRESS 0x12 void setup() { Wire.begin(SLAVE_ADDRESS); // join I2C bus as a slave with address 0x12 } void loop() { }
i2c 地址掃瞄
slave 建立後, 就要看看 master 如果找到它了.
i2c scanner 可以說是 master 板子的最基本例子, 可以用作測試線路上連接了的設備的存在 (只測試存在性, 並非測試其功能).
i2c_scanner 其實也很簡單, 由 master 向所有地址發出 beginTransmission 再 endTransmission, 嘗試建立連線. 在 beignTransmission 中輸入 slave 的地址, 就可以測試該地址的裝置了.
如果 error = 0 (沒 error), 即代表這個地址有設備登記
如果 error = 4 (這是 Wire 庫的設定, 不要問我為什麼是 4), 即代表這個地址可能有設備, 但有錯誤.
否則, 就代表該地址沒有設備使用了.
以下是一個簡單的 i2c scanner 程式:
#include <Wire.h> #define SERIAL_BAUD 9600 void setup() { Wire.begin(); Serial.begin(SERIAL_BAUD); Serial.println("I2C Scanner started"); Serial.println(); } void loop() { uint8_t error, i2cAddress, devCount, unCount; Serial.println("Scanning..."); devCount = 0; unCount = 0; for(i2cAddress = 1; i2cAddress < 127; i2cAddress++ ) { Wire.beginTransmission(i2cAddress); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at 0x"); if (i2cAddress<16) Serial.print("0"); Serial.println(i2cAddress,HEX); devCount++; } else if (error==4) { Serial.print("Unknow error at 0x"); if (i2cAddress<16) Serial.print("0"); Serial.println(i2cAddress,HEX); unCount++; } } if (devCount + unCount == 0) Serial.println("No I2C devices found\n"); else { Serial.println(); Serial.print(devCount); Serial.print(" device(s) found"); if (unCount > 0) { Serial.print(", and unknown error in "); Serial.print(unCount); Serial.print(" address"); } Serial.println(); } delay(5000); }
在這個例子中, 應該可以得到以下的結果:
I2C Scanner startedI2C Scanner 是非常有用的, 當你買了一個新裝置, 如果送來的程式不成功, 先看看相關地址是否可找到裝置, 可簡單測試裝置是否有問題.
Scanning...
I2C device found at 0x12
1 device(s) found
相關程式下載:
作者已經移除這則留言。
回覆刪除請問一個問題:
回覆刪除如果在一個裝置中有5個slave,其中4個的I2C地址使用十進位,1個使用十六進位,這5個slave都只是用作開關用途,在程式操作上將會發生什麼問題?
譬如使用十進位的4個slave:
slave1 使用地址 0100100, 程式定義為36.
slave2 使用地址 0100101, 程式定義為37.
slave3 使用地址 0100110, 程式定義為38.
slave4 使用地址 0100111, 程式定義為39.
譬如使用十六進位的1個slave:
slave5 使用地址 1001111, 程式定義為97.
不要被 二進, 十進 及 十六進的表達方式影響吧.
刪除地址設定是根據你提供的數值, 用什麼表達方式都是一樣.
5 個 slave 只要地址上沒衝突, 執行後應該可以全部 scan 出來.
根據我從https://www.arduino.cc/en/Reference/WireBegin的理解:
回覆刪除如果Arduino要當Master, 呼叫WireBegin(), 不用給address
如果Arduino要當Slave, 呼叫WireBegin(address)
寫得挺詳細, 一般都只提到master 如何傳資料到slave端就結束了
回覆刪除請教一個問題, I2C PIN需要定義是那2個嗎?
回覆刪除