ESP32使用TCA9548A IIC多路复用器拓展
本文将讲述如何使用TCA9458A IIC多路复用器扩展IIC总线端口。使用相同的IIC地址控制多个IIC设备,如多个OLED或BME280等
TCA9548介绍
IIC通信协可以实现在同一IIC总线上与多个IIC设备通信,只要所有设备都具有唯一的I2C地址。但无法实现相同的地址连接多个IIC设备。
TCA9548A IIC多路复用器可使用相同的IIC总线与多达8个IIC设备通信。多路复用器使用IIC通信协议与微控制器通信。然后,可以选择要寻址的多路复用器上的哪个IIC总线。
要寻址特定的端口,只需要向具有所需输出端口号的多路复用器发送一个字节。
TCA9548A多路复用器I2C地址
TCA9548A多路复用器使用I2C通信协议与微控制器通信。因此,它需要一个I2C地址。多路复用器地址是可配置的。可以通过调整A0、A1和A2引脚的值来选择0x70到0x77之间的一个值,如下表所示。
A0 | A1 | A2 | I2C Address |
---|---|---|---|
LOW | LOW | LOW | 0x70 |
HIGH | LOW | LOW | 0x71 |
LOW | HIGH | LOW | 0x72 |
HIGH | HIGH | LOW | 0x73 |
LOW | LOW | HIGH | 0x74 |
HIGH | LOW | HIGH | 0x75 |
LOW | HIGH | HIGH | 0x76 |
HIGH | HIGH | HIGH | 0x77 |
所以,可以将8个TCA9548A多路复用器连接到相同的IIC总线,仅使用微控制器的一个IIC总线连接具有相同地址的64个设备。
例如,将A0, A1和A2连接到GND,则会为多路复用器设置地址0x70。
Pin | Description |
---|---|
VIN | Powers |
GND | GND |
SDA | 连接到主微控制器SDA引脚 |
SCL | 连接到主微控制器SCL引脚 |
RST | 激活低RST引脚—可用于复位多路复用器 |
A0 | 选择多路复用器I2C地址-连接到GND或VCC |
A1 | 选择多路复用器I2C地址-连接到GND或VCC |
A2 | 选择多路复用器I2C地址-连接到GND或VCC |
SD0 | SDA for channel 0 |
SC0 | SCL for channel 0 |
SD1 | SDA for channel 1 |
SC1 | SCL for channel 1 |
SD2 | SDA for channel 2 |
SC2 | SCL for channel 2 |
SD3 | SDA for channel 3 |
SC3 | SCL for channel 3 |
SD4 | SDA for channel 4 |
SC4 | SCL for channel 4 |
SD5 | SDA for channel 5 |
SC5 | SCL for channel 5 |
SD6 | SDA for channel 6 |
SC6 | SCL for channel 6 |
SD7 | SDA for channel 7 |
SC7 | SCL for channel 7 |
TCA9548A I2C多路复用器选择IIC总线
如前所述,要选择特定的IIC总线来读取/写入数据,只需要将单个字节发送到具有所需输出端口号(0到7)的多路复用器。
可以使用以下函数:
void TCA9548A(uint8_t bus){Wire.beginTransmission(0x70); // TCA9548A地址为0x70Wire.write(1 << bus); // 发送字节到选择总线Wire.endTransmission();Serial.print(bus);
}
然后,只需要调用该函数并在发送IIC命令之前将要控制的端口总线号作为参数传递。例如,要控制连接到总线3号的设备,将在调用其他IIC命令之前调用以下行(注意它从0开始):
TCA9548A(2);
控制多个OLED显示器- tca9548a IIC多路复用器
在接下来的内容中,将讲述如何控制多个OLED显示器。例如,控制4个OLED(最多可以连接8个)。
Microcontroller | I2C Pins |
---|---|
ESP32 | GPIO 22 (SCL), GPIO 21 (SDA) |
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);// 选择IIC总线
void TCA9548A(uint8_t bus){Wire.beginTransmission(0x70); // TCA9548A 地址Wire.write(1 << bus); // 发送字节到总线Wire.endTransmission();Serial.print(bus);
}void setup() {Serial.begin(115200);// 启动与多路复用器的IIC通信Wire.begin();// 定义OLED在总线2上TCA9548A(2);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306分配失败"));for(;;);} // 清除缓冲区display.clearDisplay();// 定义OLED在总线3上TCA9548A(3);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306分配失败"));for(;;);} // 清除缓冲区display.clearDisplay();// 定义OLED在总线4上TCA9548A(4);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306分配失败"));for(;;);} // 清除缓冲区display.clearDisplay();// 定义OLED在总线5上TCA9548A(5);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306分配失败"));for(;;);} // 清除缓冲区display.clearDisplay();// 写入2号总线上的OLEDTCA9548A(2);display.clearDisplay();display.setTextSize(8);display.setTextColor(WHITE);display.setCursor(45, 10);// 显示静态文本display.println("1");display.display(); // 写入3号总线上的OLEDTCA9548A(3);display.clearDisplay();display.setTextSize(8);display.setTextColor(WHITE);display.setCursor(45, 10);// 显示静态文本display.println("2");display.display(); // 写入4号总线上的OLEDTCA9548A(4);display.clearDisplay();display.setTextSize(8);display.setTextColor(WHITE);display.setCursor(45, 10);// 显示静态文本display.println("3");display.display(); // 写入5号总线上的OLEDTCA9548A(5);display.clearDisplay();display.setTextSize(8);display.setTextColor(WHITE);display.setCursor(45, 10);// 显示静态文本display.println("4");display.display();
}void loop() {}