简体   繁体   中英

I2C read from registers with Arduino

I'm having some trouble understanding I2C. This is my first time using the protocol. The documentation says the following

文档的屏幕快照。

I just don't know if I am supposed to write to a read register and the two bytes are 0x00 and 0x01, or use Wire.request to request two bytes.

I have read registers from 0-20 and several write registers however I'm only interested in the read registers.

Any help would be much appreciated and please ask any questions you might have.

Thanks,

Peter

EDIT

#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
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM