I2C EEPROM : 可写但只读 0xFF

问题描述

我目前正在研究 i.MX6 (Android BSP) 和 24C08WP EEPROM 之间的 I2C 通信。

我在 i.MX6 上运行一个二进制文件,该二进制文件以前是在 Linux 下的 NDK 下编译的。

借助 for (int i = 0; i < grades.size(); i++) { for (int j = 0; j < 2; j++) { } 工具,我检测到连接到 i.MX6 的 I2C 总线(地址 0x50)的 NTAG 5 组件。

通过下面的代码,我可以执行写操作,我可以使用Arduino板和I2C读操作来检查。

但是,我在i.MX6下在用户空间执行读操作时,只得到i2cdetect值。

这是我的代码

0xFF

你能帮我吗?

This thread 描述了与接收 0xFF 值几乎相同的问题。

解决方法

正如@Andrew Cottrell 在 this thread 中所说:“要从您的 I2C 设备读取,假设它使用一个一字节的寄存器,则写入一个字节的缓冲区(寄存器地址),然后读取一个缓冲区一个或多个字节(该寄存器和后续寄存器中的值)。"

所以正确的代码如下:

#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/i2c-dev.h>

#include "board.h"
#include "debug_tools.h"
#include "boardselection.h"

int main(void) {
    int file;
    int adapter_nr = 1; /* probably dynamically determined */
    char filename[20];

    snprintf(filename,19,"/dev/i2c-%d",adapter_nr);
    file = open(filename,O_RDWR);
    if (file < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    int addr = 0x50; /* The I2C address */

    if (ioctl(file,I2C_SLAVE,addr) < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    uint8_t reg = 0x00;

    uint8_t data_w[4] = {0x00,0x00,0x00};

    data_w[0] = reg;
    data_w[1] = 0x44;

    /* Write the register */
    if (write(file,data_w,2) != 2)
    {
        perror("Failed to write to the i2c bus");
        exit(1);
    }

    usleep(1000000);

    uint8_t data_r[4] = {0x00,0x00};

    if (write(file,&reg,1) != 1)
    {
        perror("Failed to write to the i2c bus");
        exit(1);
    }

    if (read(file,data_r,1) != 1) {
        /* ERROR HANDLING: i2c transaction failed */
        perror("Failed to read register value");
        exit(1);
    }

    /* data_r[0] contains the read byte: 0x44 */
    printf("%02X\n",data_r[0]);

    return 0;
}

注意:如果不使用 usleep() 在两次写入操作之间等待,第二次写入操作可能会失败。