Python SMBus 写入字节及大于1字节的值(255)

1 投票
1 回答
3490 浏览
提问于 2025-04-18 13:45

我在用i2C协议让树莓派和Arduino进行通信。在我的Python代码中,有一段代码,其中foo是一个0到255之间的整数。
问题是当这个值大于255时,我理解这是超过了一个字节的范围。

有没有人能告诉我,我该如何修改下面的代码,以便能够正确地通过串口发送大于255的值呢?

bus = smbus.SMBus(1)
bus.write_byte(0x04, foo)

1 个回答

1

这可能跟你要写入的设备有关,但:

my_data = (0x10, 0x11, 0x20, 0x32)
bus.write_i2c_block_data(dev_address, dev_reg, my_data)

这段代码是把一块数据发送到地址为 dev_address 的设备的寄存器 dev_reg,而数据的字节(也就是一组数字)在 my_data 里。

这里的 dev_reg 并没有什么特别的,它通常只是 SMBus 中的命令或寄存器字节,也就是说,它是发送地址后第一个发送的字节。


如果你只是想把一个16位的整数 i 发送到地址为 dev_address 的设备,你可以使用:

bus.write_i2c_block_data(dev_address, i & 0xff, ((i >> 8) & 0xff,))

这个命令实际上是把第二个参数(设备寄存器)和数据内容(字节列表)合并在一起发送。通常情况下,第一个数据字节是命令或寄存器编号。在这里,16位数字的第一个字节(最低有效字节)被用作设备寄存器,而第二个字节(最高有效字节)则作为数据内容发送。

不过,在这种特定情况下,你也可以使用 write_byte_data 这个调用:

bus.write_byte_data(dev_address, i & 0xff, (i >> 8) & 0xff)

这两个函数调用都是为了一个协议设计的,在这个协议中,每个设备除了有地址外,还有一个8位的寄存器编号。I2C 只规定每个设备有一个7位的地址,其他的就由应用程序决定。

所以,上面任何一个指令都应该只是发送:

<start>
<7-bit address> + <write bit>
<8-bit byte>
<8-bit byte>
<stop>

通常情况下,第一个8位字节是设备寄存器。

如果你想从设备读取一些东西,简单的情况是:

<start>
<device address> + <read bit>
<read octet #1>
...
<stop>

不过,很多时候你需要把寄存器编号告诉设备,这种情况下你需要发送:

<start>
<device address> + <write bit>
<8 bits: register number>
<start>
<device address> + <read bit>
<read octet #1>
...
<stop>

因为这些交互有点复杂,所以它们被封装在 API 命令里。

撰写回答