0

我在使用wiringPi'swiringPiI2CWriteReg16()函数时遇到了意外的结果,我不确定这是由于使用不正确还是其他原因。这是函数的声明:

extern int wiringPiI2CWriteReg16 (int fd, int reg, int data);

如果有帮助,文件中有说明wiringPiI2C.c它类似于 Linux 的SMBus代码。

在我的 Arduino(Uno R3 和 Trinket Pro)上,我正在运行这个精简的草图:

#include <Wire.h>

#define SLAVE_ADDR 0x04

void receive_data (int num_bytes){
  Serial.print("bytes in: ");
  Serial.println(num_bytes);

  while(Wire.available()){
    int data = Wire.read(); // tried char, uint8_t etc
    Serial.println(data);
  }
  Serial.print("\n");
}

void setup() {
  Serial.begin(9600);
  Wire.begin(SLAVE_ADDR);
  Wire.onReceive(receive_data);
}

void loop() {
  delay(500);
}

我认为这Wire.read()会在字节边界处分崩离析,但在我的情况下并没有发生这种情况。也许这是我的问题......一个误解。

尽管如此,我有这个C代码(需要安装wiringPi v2.36+):

// word.c

#include <wiringPiI2C.h>

void main (){
    int fd = wiringPiI2CSetup(0x04);
    wiringPiI2CWriteReg16(fd, 0x00, 255);
    wiringPiI2CWriteReg16(fd, 0x01, 256);
}

编译如下:

gcc -o word word.c -lwiringPi

运行时./word,我在 Arduino 的串行输出上收到以下信息:

bytes in: 3
0
255
0

bytes in: 3
1
0
1

在第一次调用时wiringPiI2CWriteReg16(),我希望输出中的第一个字节为零(0x00),因为这是我请求的寄存器地址。第二个字节 ( 255) 也是正确的。据我所知,第三个字节 ( 0) 毫无意义(因为我只发送一个字节作为数据)。

但是,在对该函数的第二次调用中,我确实得到了寄存器的正确输出(第一个字节为0x01== 1),但第二个字节为零,第三个字节似乎是正确的余数(255 ==一个字节,+ 1)。问题是,第二个字节是0.

511如果我传入或就此而言,任何数字作为调用中的数据,都会发生完全相同的效果。

我的问题是我是否遗漏了一些明显的东西(我对 C 和 Arduino 比较陌生),和/或我是否可以得到一些关于如何更彻底地解决这个问题的指示。

4

1 回答 1

0

我发现问题出在我的 Arduino 代码中。在 Raspi 官方论坛中,Gordon 告诉我字节是单独读取的,LSB 在前。在我所有的搜索过程中,我都没有遇到过,也不太明白发生了什么。将我的 Arduino 草图中的 I2C 读取循环代码更改为:

while(Wire.available()){
    Wire.read(); // throw away register byte

    int16_t data = Wire.read(); // LSB
    data += Wire.read() << 8;   // MSB

    Serial.print("data: ");
    Serial.println(data);
}

...一切正常。实际上,这至少是一种通过 Arduino 上的 I2C 读取两个字节值并将字节重新组合在一起的方法。

于 2017-06-23T12:50:26.370 回答