我是I2C的初学者,尝试使用rpi 3从GY-521(MPU-6050)读取数据

起初,我使用了C的WiringPi库,然后使用了python smbus库 . 两者都很好,并给出了一致的读数 . 然后我切换到本文中的方法:https://elinux.org/Interfacing_with_I2C_Devices . 我把所有的地址排成一行,但是我的行为非常奇怪和不一致:

•open()函数几乎每次都成功,但read()函数经常将errno设置为REMOTE I / O ERROR(在成功读取之前,我必须将连接调整大约20-30秒) . 考虑到wiringPi和smbus方法没有这个问题,这对我来说很奇怪 .

•根据数据表(https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf),IMU应该通过FIFO缓冲区以“突发”的1024字节包或更频繁的16位包发送数据 . 当我成功读取时,我填充了一个1100字节的无符号短缓冲区 . 但是,read()始终返回一个与缓冲区大小相对应的整数,即使缓冲区大于1024字节(在本例中为1100) . MPU-6050在向文件写入1024字节后是否可能无法发送eof?或者这是标准练习,程序员应该知道在1024处停止阅读?

•我也一直在比较很多有效的输出,我没有看到一个非常明显的模式,用于设置缓冲区中的哪些位 . 从这个文档https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf,我假设“从寄存器读取”,例如,从0x3C开始到0x3D(从第7页开始)的ACCEL_XOUT数据,只是从对应于0x3C和0x3D的某个索引中检索数据 . 填充缓冲区...但我似乎无法找到任何明显的线性映射 . 读取寄存器是否完全涉及其他形式的文件映射,缓冲区只是充满了随机的无关数据?

谢谢 .

// from https://elinux.org/Interfacing_with_I2C_Devices

    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <linux/i2c-dev.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    void sensors_ADC_init(void) {
        int file;
        char filename[40];
        const char *buffer;
        int addr = 0b1101001;   // The I2C address of GY-521, LSB == 1 -> read only

        sprintf(filename,"/dev/i2c-1");
        if ((file = open(filename,O_RDWR)) < 0) {
            printf("Failed to open the bus.");
            /* ERROR HANDLING; you can check errno to see what went wrong */
            exit(1);
        }

        else if (ioctl(file,I2C_SLAVE,addr) < 0) {
            printf("Failed to acquire bus access and/or talk to slave.\n");
            /* ERROR HANDLING; you can check errno to see what went wrong */
            exit(1);
        }
        else{ // opened successfully
            // GY-521 writes 16 bits or 1024 bytes 
            unsigned short buf[550] = {0}; // 1100 byte buffer 
            unsigned short datachunk;
            // Using I2C Read
            int read_ = read(file,buf,1100);
            if (read_ < 0) {
                /* ERROR HANDLING: i2c transaction failed */
                printf("Failed to read from the i2c bus.\n");
                printf("errno =  %s\n", strerror(errno));
                printf("\n\n");
            } else { //successful read
                printf("read  %d bytes\n", read_);
                for(unsigned short i = 0; i < 550; i++){
                    datachunk = buf[i];
                    printf("output: %d , %d index of 550\n", datachunk, i);
                }
            }
        }
    }

    int main(){
        while(1){
            sensors_ADC_init();
        }
    }