gpt4 book ai didi

Arduino 作为具有多个 i2c 地址的从机

转载 作者:行者123 更新时间:2023-12-04 16:51:48 34 4
gpt4 key购买 nike

我想使用 Arduino 作为 i2c 从站。但我要求 Arduino 通过向多个 i2c 地址注册自身来充当多个设备。

这可能不是一个人通常会做的事情,但这是我这样做的原因:

我想使用 Arduino 作为 Spektrum 遥测的遥测传感器。遥测接收器有几个 i2c 插头连接到多个传感器(电流 0x02、电压 0x03、空速 0x11 等),每个传感器都有遥测接收器期望的固定 i2c 地址。

我想使用 一个 Arduino 通过使用上述所有地址注册自己,并用读数适本地响应来充当所有这些设备。

我可以为每个传感器使用一个 Arduino,这似乎很愚蠢,因为我可以使用一个 Arduino pro-mini 执行所有这些读数。

我知道你可以使用注册 Arduino

Wire.begin(0x02); 

但我需要类似的东西(伪代码)
Wire.begin(0x02, 0x03, 0x11);

当收到请求时,我需要知道查询 Arduino 的地址是什么。

例如(伪代码)
void receiveEvent(byte address, int bytesReceived){
if(address == 0x02){
// Current reading
}
else if(address == 0x03){
// Voltage reading
}
else if(address == 0x11){
// Airspeed reading
}
}

任何意见,将不胜感激。

最佳答案

由于 Wire.begin() ,无法使用Wire 库让Arduino 监听多个从地址。只允许传递一个从地址。

即使是大多数 Arduino 所基于的 Atmel ATmega 微 Controller 也只允许通过其 2 线地址寄存器 TWAR 将其硬件 2 线串行接口(interface) (TWI) 设置为单个 7 位地址。 .但是,可以通过使用 TWI 地址屏蔽寄存器 TWAMR 屏蔽一个或多个地址位来解决此限制。如记录(有点简短)例如这个ATmega datasheet第 22.9.6 节:

The TWAMR can be loaded with a 7-bit Salve (sic!) Address mask. Each of the bits in TWAMR can mask (disable) the corresponding address bits in the TWI address Register (TWAR). If the mask bit is set to one then the address match logic ignores the compare between the incoming address bit and the corresponding bit in TWAR.



因此,我们首先必须根据我们想要响应的所有 I2C 地址设置掩码位,方法是对它们进行 OR 运算并右移以匹配 TWAMR。寄存器布局( TWAMR 在 bit7:1 中保存掩码,未使用 bit0):

TWAMR = (sensor1_addr | sensor2_addr | sensor3_addr) << 1;

从这里开始的主要问题将是找出查询了哪个特定的 I2C 地址(我们只知道它与地址掩码匹配)。
如果我正确解释第 22.5.3 节,说明

The TWDR contains the address or data bytes to be transmitted, or the address or data bytes received.



我们应该能够从 TWDR 中检索未屏蔽的 I2C 地址登记。

ATmega TWI 操作是基于中断的,更具体地说,它使用单个中断向量来处理由 TWSR 中的状态代码指示的大量不同 TWI 事件。状态寄存器。
在 TWI 中断服务程序中,我们必须
  • 确保我们进入 ISR 的原因是因为我们被询问过。这可以通过检查 TWSR 来完成。状态码 0xA8 (已收到自己的SLA+R)
  • 通过检查 TWDR 中总线上的最后一个字节,根据实际查询的 I2C 地址决定将哪些传感器数据发送回主机.

  • ISR 的这一部分可能看起来像这样(未经测试):

    if (TWSR == 0xA8) { // read request has been received
    byte i2c_addr = TWDR >> 1; // retrieve address from last byte on the bus
    switch (i2c_addr) {
    case sensor1_addr:
    // send sensor 1 reading
    break;
    case sensor2_addr:
    // send sensor 2 reading
    break;
    case sensor3_addr:
    // send sensor 3 reading
    break;
    default:
    // I2C address does not match any of our sensors', ignore.
    break;
    }
    }

    感谢您提出这个有趣的问题!

    关于Arduino 作为具有多个 i2c 地址的从机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34691478/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com