I2C从Arduino读取寄存器

时间:2016-02-02 15:04:17

标签: arduino byte i2c

我在理解I2C方面遇到了一些麻烦。这是我第一次使用该协议。文档说明如下

Screenshot of the documentation.

我只是不知道我是否应该写入读取寄存器并且两个字节是0x00和0x01,或者使用Wire.request来请求两个字节。

我已经读取了0-20的寄存器和几个写寄存器,但是我只对读寄存器感兴趣。

我们非常感谢您的帮助,如果您有任何疑问,请随时提出。

谢谢,

彼得

修改

#include <Wire.h>

void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
int k = readRegister(0x08, 0x06);
Serial.println(k);
delay(500);
}

uint16_t readRegister(uint8_t i2cAddr, uint8_t regAddr) {

// I2C write sequence to address the given read register
Wire.beginTransmission(i2cAddr); // Module address
Wire.write(regAddr);             // Register Address
Wire.write(0);                   // Command Data = dummy zeroes
Wire.write(0);
Wire.write(regAddr);             // Checksum
Wire.endTransmission();          // Finish I2C write sequence

// I2C read sequence to actually get the register value
Wire.requestFrom(i2cAddr, 3);
uint16_t regVal = Wire.read();
regVal <<= 8;
regVal |= Wire.read();
if (Wire.read() == (((regVal >> 8) + regVal) & 0xFF)) {
    return regVal; // Checksum OK
}
return 0xFFFF;     // Checksum error
}

1 个答案:

答案 0 :(得分:0)

It seems the only way to say which register you want to read is to complete an I2C write sequence using that register's address. Probably the "Command Data" you use in the write sequence will be irrelevant if you use the address of a read register.

So it would become something like this:

uint16_t readRegister(uint8_t i2cAddr, uint8_t regAddr) {

    // I2C write sequence to address the given read register
    Wire.beginTransmission(i2cAddr); // Module address
    Wire.write(regAddr);             // Register Address
    Wire.write(0);                   // Command Data = dummy zeroes
    Wire.write(0);
    Wire.write(-regAddr);            // Checksum
    Wire.endTransmission();          // Finish I2C write sequence

    // I2C read sequence to actually get the register value
    Wire.requestFrom(i2cAddr, 3);
    uint16_t regVal = Wire.read();
    regVal <<= 8;
    regVal |= Wire.read();
    if ((Wire.read() + regVal >> 8 + regVal & 0xFF) == 0) {
        return regVal; // Checksum OK
    }
    return 0xFFFF;     // Checksum error
}

It is usual in many chips to access subsequent register addresses incrementally by just issuing new read sequences. This way you could do a bulk or multi-byte read. However I'm not sure that's the case here, so you might need to do the write sequence every time.