write_i2c_block_data中cmd参数的含义


12

我正在测试Pi和Arduino之间的i2c通信。

医生说:

write_i2c_block_data(addr,cmd,vals)  Block Write transaction.    int addr,char cmd,long[]    None

我有这个测试:

在Pi上:

import smbus
bus = smbus.SMBus(0)
bus.write_i2c_block_data(address, 48, [49, 50, 51] )

在Arduino上:

void receiveData(int byteCount){
    Serial.print("byte count=");
    Serial.println(byteCount);

    while(Wire.available()) {
        number = Wire.read();
        Serial.print((char)number);
     }
}

在Arduino上,我看到以下输出:

byte count=4
0123

我的问题是:该cmd参数的用途是什么?我在Arduino上看不到哪个字节代表什么的区别。
我想我可以视情况处理它。也许我想使用前2个字节作为命令。

该页面没有关于该方法的太多信息:http : //wiki.erazor-zone.de/wiki : linux : python : smbus : doc


您可能想定义cmd参数是什么...我不得不做一点点的工作来弄清楚您的意思。不过我没有找到答案。它只能由GPIO扩展器之类的特定芯片使用...
Butters 2013年

好的,我将链接添加到文档中了(不多)
Gus Smith

6
我现在没有时间做一个完整的答案(我希望有人会),但总之-这就是I²C的工作方式。主机可以只发送一些字节的数据(发送正确的地址后),而没有关于这些字节实际是什么的规范(它们的含义是按设备定义的)。碰巧的是,第一个字节通常是命令(或寄存器)号。你也总是有至少发送一个字节一点都不像valscmd是强制性的。
Krzysztof Adamski 2013年

1
@KrzysztofAdamski听起来对我来说是一个很完整的答案。
黄油

Answers:


8

I²C协议很简单。它并没有真正定义通过网络发送的数据结构。该帧包括一个从机地址(方向位指示主机是否要读取或写入)和(在写入的情况下)一些字节的数据。由于从0字节的数据开始写操作没有意义,因此必须使用第一个字节。

该第一个字节通常用作从寄存器地址或命令号,但并非必须如此。第一个字节之后可能有也可能没有其他字节。定义每个字节含义的高级协议是特定于设备的。

这可以解释为什么有两个单独的参数-第一个(cmd)是必需的,第二个(vals)是可选的。虽然您的示例使用Python语言编写,但此处使用的API实际上是原始CAPI的非常紧密的映射,您无法轻松创建可选参数。


这是我在问题下的评论中写的内容的更长一点的解释。
Krzysztof Adamski 2013年

我很高兴你做到了!这些简单但又“啊哈”!解释确实在某些时候很有帮助,例如今天:-)
uhoh

3

当您使用以下命令从Pi发出块写/读操作时:

bus.write_i2c_block_data(address, 48, [49, 50, 51] )

要么

bus.read_i2c_block_data(address, 48, [49, 50, 51] )

取决于读写,在Arduino上会发生两件事。

cmd字节是从Pi写入I2C总线的第一个字节,它始终作为“写入”请求发送。这意味着如果Pi正在发布

bus.read_i2c_block_data

要么

bus.write_i2c_block_data

它首先写道

cmd

I2C总线之前,读取

这是一个有用的功能,因为某些I2C硬件需要初始化才能进行读取。

在Arduino上,这意味着:

首先,

Wire.onReceive(yourCallback)

函数被调用,因为cmd由PI到总线。 cmd将是总线上可用的第一个字节。如果Pi发送了写请求,则Arduino将保留在Wire.onReceive回调中,直到功能完成。如果Pi发送了读取请求,则Arduino将完成Wire.onReceive,然后调用Wire.onRequest回调。

您必须通过正确处理cmd的值来确保放置在cmd中的值不会在系统中引起意外行为。例如,如果Wire.read = 0x30,则您的Wire.onReceive回调将关闭LED。然后,即使您发送了读取请求,它也将首先通过写入 0x30 来关闭LED,然后它将从总线读取请求的字节。


1

我正在写I2C LCD,即Newhaven NHD-0216K3Z‐FL‐GBW‐V3。它的规格表可以用谷歌搜索。在这种情况下,当命令字节为0xfe时,表示后面的字节为命令-大约有20个字节。清除,背光,光标闪烁等。如果cmd不是0xfe,则仅显示一些字符。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.