Adafruit TCA9548A 1-to-8 I2C 多路復用器:解決 I2C 設備地址沖突的利器
在電子設計中,當我們遇到需要連接多個具有相同 I2C 地址的設備時,常常會陷入困境。不過,Adafruit TCA9548A 1-to-8 I2C 多路復用器的出現(xiàn),為我們提供了一個完美的解決方案。
文件下載:2717.pdf
一、概述
在使用 I2C 傳感器時,我們可能會遇到這樣的問題:某個 I2C 傳感器芯片具有固定的 I2C 地址,而 I2C 協(xié)議不允許在同一 SDA/SCL 引腳上連接兩個具有相同地址的設備。這時,TCA9548A 多路復用器就派上用場了。它就像一個門衛(wèi),能夠根據我們的指令將命令傳輸到選定的 I2C 引腳組。
該多路復用器本身的 I2C 地址默認為 0x70,但可以在 0x70 到 0x77 之間進行調整。我們只需向該端口寫入一個包含所需多路復用輸出編號的單字節(jié),后續(xù)的 I2C 數據包就會被發(fā)送到該端口。理論上,我們可以在 0x70 - 0x77 每個地址上使用 8 個這樣的多路復用器,從而控制 64 個具有相同 I2C 地址的設備。
二、引腳說明
1. 電源引腳
- Vin:電源引腳,傳感器芯片使用 3 - 5 VDC 供電。為板子供電時,應提供與微控制器邏輯電平相同的電源,例如對于 5V 的 Arduino 微控制器,使用 5V 電源。
- GND:電源和邏輯的公共接地端。
2. I2C 控制側引腳
- SCL:芯片本身的 I2C 時鐘引腳,連接到微控制器的 I2C 時鐘線。
- SDA:芯片本身的 I2C 數據引腳,連接到微控制器的 I2C 數據線。
- RST:復位引腳,用于復位多路復用器芯片。默認情況下拉高,連接到地即可復位。
- A0、A1、A2:多路復用器的地址選擇引腳。默認情況下,多路復用器的地址為 0x70,這三個引腳被拉低。將它們連接到 Vin 可以將地址設置為 0x71 - 0x77。其中,A0 是最低有效位(拉高時地址增加 1),A1 是次低有效位(拉高時地址增加 2),A2 是第三低有效位(拉高時地址增加 4)。
3. I2C 多路復用側引腳
有 8 組 SDx 和 SCx 引腳,從 SD0/SC0 到 SD7/SC7。這些是多路復用引腳,每組都是一個完全獨立的 I2C 總線集。因此,只要每個設備都連接到一個 I2C 總線上,我們就可以連接 8 個具有相同地址的 I2C 設備。需要注意的是,這些引腳沒有安裝上拉電阻,如果使用的芯片或擴展板沒有 I2C 上拉電阻,一定要添加。而且,Vin 可以是 3.3V,而這些引腳可以上拉到 5V(即它們支持 5V)。
三、組裝步驟
1. 準備排針
如果需要,將排針裁剪到合適的長度。將其插入面包板,長引腳朝下,這樣更便于焊接。
2. 添加擴展板
將擴展板放在排針上,使短引腳穿過擴展板的焊盤。
3. 焊接
確保焊接所有引腳,以實現(xiàn)可靠的電氣連接。如果需要焊接技巧,可以查看相關的焊接指南。
四、Arduino 接線與測試
1. 基本原理
TCA9548A 多路復用器有一個 I2C 地址(默認 0x70),我們可以向它發(fā)送命令,告訴它要與哪個 I2C 多路復用輸出進行通信,然后就可以對目標板進行尋址。
2. 示例代碼
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 < i);
Wire.endTransmission();
}
我們可以調用 tcaselect(0) 到 tcaselect(7) 來設置多路復用器。如果碰巧有 I2C 地址為 0x70 的 I2C 設備,需要將 TCA9548 擴展板上的一個地址引腳短接到 Vin,以避免沖突。
3. 示例復用
假設我們要連接兩個 HMC5883 擴展板,這些磁力計的固定地址為 0x1E,不能在一個 I2C 總線上連接兩個。接線時,將 TCA9548 擴展板的 Vin 連接到 5V(對于 3V 邏輯的 Arduino/微控制器,使用 3.3V),GND 連接到地,SCL 連接到 I2C 時鐘,SDA 連接到 I2C 數據。然后將每個傳感器擴展板連接到 Vin、地,并使用其中一個 SCn/SDn 多路復用總線。
4. 掃描腳本
#include "Wire.h"
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 < i);
Wire.endTransmission();
}
void setup() {
while (!Serial);
delay(1000);
Wire.begin();
Serial.begin(115200);
Serial.println("nTCAScanner ready!");
for (uint8_t t = 0; t < 8; t++) {
tcaselect(t);
Serial.print("TCA Port #");
Serial.println(t);
for (uint8_t addr = 0; addr <= 127; addr++) {
if (addr == TCAADDR) continue;
Wire.beginTransmission(addr);
if (!Wire.endTransmission()) {
Serial.print("Found I2C 0x");
Serial.println(addr, HEX);
}
}
Serial.println("ndone");
}
}
void loop() {}
運行這個腳本可以檢測連接的設備。
5. 多傳感器示例
#include
#include
#include
#define TCAADDR 0x70
Adafruit_HMC5883_Unified mag1 = Adafruit_HMC5883_Unified(1);
Adafruit_HMC5883_Unified mag2 = Adafruit_HMC5883_Unified(2);
void displaySensorDetails(Adafruit_HMC5883_Unified *mag) {
sensor_t sensor;
mag->getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(sensor.name);
Serial.print("Driver Ver: ");
Serial.println(sensor.version);
Serial.print("Unique ID: ");
Serial.println(sensor.sensor_id);
Serial.print("Max Value: ");
Serial.print(sensor.max_value);
Serial.println(" uT");
Serial.print("Min Value: ");
Serial.print(sensor.min_value);
Serial.println(" uT");
Serial.print("Resolution: ");
Serial.print(sensor.resolution);
Serial.println(" uT");
Serial.println("------------------------------------");
delay(500);
}
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 < i);
Wire.endTransmission();
}
void setup(void) {
Serial.begin(9600);
Serial.println("HMC5883 Magnetometer Test");
Serial.println("");
tcaselect(2);
if (!mag1.begin()) {
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while (1);
}
tcaselect(6);
if (!mag2.begin()) {
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while (1);
}
tcaselect(2);
displaySensorDetails(&mag1);
tcaselect(6);
displaySensorDetails(&mag2);
}
void loop(void) {
sensors_event_t event;
tcaselect(2);
mag1.getEvent(&event);
Serial.print("Sensor #1 - ");
Serial.print("X: ");
Serial.print(event.magnetic.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.magnetic.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event.magnetic.z);
Serial.println(" uT");
tcaselect(6);
mag2.getEvent(&event);
Serial.print("Sensor #2 - ");
Serial.print("X: ");
Serial.print(event.magnetic.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.magnetic.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event.magnetic.z);
Serial.println(" uT");
delay(500);
}
通過添加 tcaselect() 函數,我們可以與兩個傳感器進行通信。
6. 多個多路復用器
由于 TCA9548 是可尋址的,我們可以在總線上使用多個多路復用器。有 8 個可能的地址,這意味著我們可以控制多達 64 個獨立的 I2C 總線。為了避免不同多路復用器上具有相同地址的設備之間發(fā)生沖突,可以使用以下代碼禁用多路復用器上的所有通道:
Wire.beginTransmission(TCAADDR1);
Wire.write(0); // no channel selected
Wire.endTransmission();
五、CircuitPython 與 Python
1. 安裝 TCA9548A 庫
需要安裝 Adafruit_Blinka 庫,該庫為 Python 提供 CircuitPython 支持。這可能還需要在平臺上啟用 I2C 并驗證是否運行 Python 3。由于每個平臺略有不同,并且 Linux 經常變化,請訪問 CircuitPython on Linux 指南來準備好計算機。安裝完成后,從命令行運行以下命令:
sudo pip3 install adafruit-circuitpython-tca9548a
如果默認 Python 是版本 3,可能需要運行 pip 而不是 pip3。請確保不要在 Python 2.x 上使用 CircuitPython,因為它不支持。
2. CircuitPython 用法
使用 CircuitPython 時,需要先將 TCA9548A 庫及其依賴項安裝到 CIRCUITPY 驅動器的 lib 文件夾中,然后用示例腳本更新 code.py??梢渣c擊下載項目捆綁包按鈕,下載必要的庫和 code.py 文件的壓縮包,解壓后將整個 lib 文件夾和 code.py 文件復制到 CIRCUITPY 驅動器。
3. Python 用法
在計算機上使用 pip3 安裝庫后,將示例代碼復制或下載到計算機上,運行以下命令:
python3 code.py
4. 簡單測試示例代碼
import board
import adafruit_tca9548a
i2c = board.I2C()
tca = adafruit_tca9548a.TCA9548A(i2c)
for channel in range(8):
if tca[channel].try_lock():
print("Channel {}:".format(channel), end="")
addresses = tca[channel].scan()
print([hex(address) for address in addresses if address != 0x70])
tca[channel].unlock()
這個簡單的測試會對 TCA9548A 的所有八個端口進行 I2C 掃描,如果有設備連接,會將 I2C 地址打印到 REPL 中。
5. 多傳感器示例代碼
import time
import board
import adafruit_tsl2591
import adafruit_tca9548a
i2c = board.I2C()
tca = adafruit_tca9548a.TCA9548A(i2c)
tsl1 = adafruit_tsl2591.TSL2591(tca[0])
tsl2 = adafruit_tsl2591.TSL2591(tca[1])
while True:
print(tsl1.lux, tsl2.lux)
time.sleep(0.1)
在這個多傳感器示例中,TCA9548A 作為 I2C 多路復用器與兩個 TSL2591 光傳感器一起使用。循環(huán)中,每 0.1 秒將兩個光傳感器的讀數打印到 REPL 中。
六、下載資源
可以下載 TCA9548A 的數據手冊、Adafruit Fritzing 庫中的 Fritzing 對象以及 GitHub 上的 EagleCAD PCB 文件,還能查看原理圖和制造圖紙。
總之,Adafruit TCA9548A 1-to-8 I2C 多路復用器為解決 I2C 設備地址沖突問題提供了一個簡單而有效的解決方案。無論是使用 Arduino 還是 CircuitPython/Python,都能輕松實現(xiàn)多個相同地址 I2C 設備的連接和通信。大家在實際應用中有沒有遇到過類似的地址沖突問題呢?又是如何解決的呢?歡迎在評論區(qū)分享交流。
發(fā)布評論請先 登錄
SGM65230S:4位1選2多路復用器/解復用器,低電壓高帶寬總線開關
RK3576平臺PCA9548 I2C開關設備樹配置與生效全解析
SN74CBT3257C:高性能4位1-of-2 FET多路復用器/解復用器
深入剖析TS3A27518E-Q1:6位1-of-2多路復用器/解復用器的卓越性能與應用
深入剖析PCA9544A:多功能4通道I2C和SMBus多路復用器
TCA8418:I2C控制的鍵盤掃描IC深度剖析
探秘TCA9554A:低電壓8位I2C和SMBus I/O擴展器的實用之選
TCA9548A:低電壓8通道I2C開關的設計與應用
TCA9544A:4 通道 I2C 與 SMBus 多路復用器深度解析
TCA9538:低電壓8位I2C和SMBus低功耗I/O擴展器的深度剖析
TCA9534:低電壓8位I2C和SMBUS低功耗I/O擴展器的全面解析
深入解析TCA9617B:I2C總線中繼器的卓越之選
支持復位的 TCA9548A-Q1 汽車 8 通道 I2C 開關:設計與應用全解析
Texas Instruments TUSB1021-Q1 10Gbps線性轉接驅動器多路復用器和多路解復用器數據手冊
Adafruit TCA9548A 1-to-8 I2C 多路復用器:解決 I2C 設備地址沖突的利器
評論