跳转到内容

开发示例

使用arduino作为代码示例

提示

注:示例代码中没有做任何的错误处理 (∪.∪ )...zzz

一些前置代码

C
#include <Wire.h>

// 地址 (默认0x77,根据实际拨码开关调整)
uint8_t address = 0x77;

void setup() {
    // 初始化I²C
    Wire.begin();

    // 上电后默认所有通道关闭,无需额外初始化
}

// 写控制寄存器(选通通道)
bool selectChannel(uint8_t channel) {
    Wire.beginTransmission(address);
    Wire.write(1 << channel);  // 仅选通指定通道
    return Wire.endTransmission() == 0;
}

// 写控制寄存器(选通多个通道)
bool writeControl(uint8_t value) {
    Wire.beginTransmission(address);
    Wire.write(value);
    return Wire.endTransmission() == 0;
}

// 读取当前控制寄存器状态
uint8_t readControl() {
    Wire.requestFrom(address, (uint8_t)1);
    if (Wire.available()) {
        return Wire.read();
    }
    return 0;
}

选通单个通道

PCA9546 的控制寄存器只有 1 个字节,低 4 位分别对应 4 个通道。

C
// 选通通道0
selectChannel(0);  // 写入 0b00000001 = 0x01

// 选通通道1
selectChannel(1);  // 写入 0b00000010 = 0x02

// 选通通道2
selectChannel(2);  // 写入 0b00000100 = 0x04

// 选通通道3
selectChannel(3);  // 写入 0b00001000 = 0x08

选通多个通道

PCA9546 支持同时选通多个通道,将多个通道的对应位全部置 1 即可。

C
// 同时选通通道0和通道1
writeControl(0b00000011);  // 0x03

// 同时选通通道0、通道2和通道3
writeControl(0b00001101);  // 0x0D

// 同时选通所有4个通道
writeControl(0b00001111);  // 0x0F

// 关闭所有通道
writeControl(0b00000000);  // 0x00

典型应用:读取多个同地址传感器

当总线上挂载了多个相同 I²C 地址的传感器时,可以通过 PCA9546 切换通道来分别访问:

C
// 假设4个通道上分别连接了4个相同地址(0x40)的传感器
uint8_t sensorAddr = 0x40;

void readAllSensors() {
    for (uint8_t ch = 0; ch < 4; ch++) {
        // 选通当前通道
        selectChannel(ch);
        delay(1); // 等待通道切换稳定

        // 通过 I²C 读取该通道上的传感器数据
        Wire.beginTransmission(sensorAddr);
        Wire.write(0x00); // 假设读取寄存器0
        Wire.endTransmission();
        Wire.requestFrom(sensorAddr, (uint8_t)2);

        if (Wire.available() == 2) {
            uint16_t data = (Wire.read() << 8) | Wire.read();
            Serial.print("Channel ");
            Serial.print(ch);
            Serial.print(": ");
            Serial.println(data);
        }
    }
}

读取当前通道状态

C
uint8_t state = readControl();
Serial.print("当前控制寄存器状态: 0x");
Serial.println(state, HEX);

// 判断各个通道是否选通
if (state & 0x01) Serial.println("通道0已选通");
if (state & 0x02) Serial.println("通道1已选通");
if (state & 0x04) Serial.println("通道2已选通");
if (state & 0x08) Serial.println("通道3已选通");