I2C外挂eeprom的读写

I2C简介

    I2C总线通信是一种通信协,用于连接微控制器及其外围设备,由两根线组成,时钟线SDA和数据线SCL。

                              I2C外挂eeprom的读写_第1张图片

         如图所示,外挂设备接到相应的线上就可以被i2c识别到,另外关于scl,sda以怎么样的波形去发送消息,以及设备的应答波纹就不在详细介绍了,这个对于不是直接写驱动的开发人员来说没有必要了解,上层应用很少去以一个一个电位的形式发消息,有需要的可以再找专业的文章了解;

 

EEPROM

       eeprom是一种掉电后数据不丢失的存储器,常用来存储一些配置信息,以便系统重新上电的时候加载之。例如,可以写Mac、IP、用户验证信息等。eeprom市场上提供的类型有许多,主要是内存大小的差异,有1K, 2K, 4K等容量,注意有些是以b为单位,有些是以B为单位,不过厂家为了显大都会以b为单位,就像厂家的1M是以1000算的文不是1024。

I2C外挂eeprom的读写_第2张图片

    如图是某eeprom的引脚图,我们只关注nc的引脚,一般厂商会提供相应的pdf说明,图中的1,2, 3代表的是A0,A1,A2三个引脚,nc代表可变数据的意思,只有0和1两个值,如果不是nc则代表固定值0,,这些值是用来寻找硬件地址的。按照协议寻址的参数是8位,eeprom前4位是1010,这个是IEEE规定的国际标准,如果你的不是这个,那兼容性来说就比较差了。

     8位数据是 1010(A0)(A1)(A2)(R/W) ,最后一位1为读操作0为写操作,实际上算的时候只会算前7位,比如1010000为0X50,这是挂载在iic上的硬件地址。A0,A1,A2的值取决于eeprom的大小,如果你的容量是2Kb大小,那么A0,A1只能是0,A3可取0和1,那么会发现iic上显示有0x50和0X51的地址被挂载,eeprom一块储存大小为256字节。

 

i2c-tools

        好了介绍一个工具i2c-tools,这个可以专门用来查看i2c的设备挂载情况。你可以去下载源码进行编译,放到你要使用的平台上运行进行查看。这里就介绍两个有用的命令,把编译好的i2cdetect和i2cdump放到你的平台上执行:

    i2cdetect -l   检测有几条iic总线

 图中i2c-3, i2c-0的3和0就是该两条总线的代号

 i2cdetect -r -y 0 检测总线上挂载的设备地址

I2C外挂eeprom的读写_第3张图片

0是你要检测的总线代号

 i2cdump -f -y 0 0x50    0是总线代号,0X50是挂载地址

I2C外挂eeprom的读写_第4张图片

如图默认值为0xff。最后一排01 01 是我修改的。

            这样你就可以看到eeprom里面写入的数据了,当然实际上没有人会这么直白的写密码账号,通常都是一堆加密的数据,需要特定的算法才可以得到正解。

##程序读写eeprom数据

    读写的方式就比较多了,直接调用iic读写接口读写,自己参考i2c-tool工具的源代码进行读写,我是用文件的形式来读写。

    毕竟是在linux平台上进行操作,那么对于linux的概念来说一切皆文件。下面就放代码吧,具体注释就不给了,相信大家还是可以看懂的。

 

 

void _alpu_delay_ms(unsigned int i)  
{
    usleep(2000 * i);
}

//dev-name 设备名 linux上的"/dev/i2c-0"

//device_addr 数据块地址0x50 到.....

//sub_addr 块中地址名 0x00到0xff

//buff 写入数据

//ByteNo 写入数据长度
int i2c_write(char *dev_name,unsigned char device_addr, unsigned char sub_addr, unsigned char *buff, int ByteNo)
{
    int fd, ret;
    unsigned char buftmp[32];
    struct i2c_rdwr_ioctl_data i2c_data;

   
    
    fd = open(dev_name, O_RDWR);
    if (fd < 0)
    {
        printf("can not find dev %s\n",dev_name);
        return -2;
    }

    i2c_data.nmsgs = 1;
    i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs *sizeof(struct i2c_msg));
    if (i2c_data.msgs == NULL)
    {
        printf("malloc error \n");
        close(fd);
        return -1;
    }

    ioctl(fd, I2C_TIMEOUT, 1);
    ioctl(fd, I2C_RETRIES, 2);

    memset(buftmp, 0, 32);
    buftmp[0] = sub_addr;
    memcpy(buftmp + 1, buff, ByteNo);
    i2c_data.msgs[0].len = ByteNo + 1;;
    i2c_data.msgs[0].addr = device_addr;
    i2c_data.msgs[0].flags = 0;     // 0: write 1:read
    i2c_data.msgs[0].buf = buftmp;
    ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
    if (ret < 0)
    {
        printf("write reg %x %x error\r\n", device_addr, sub_addr);
        close(fd);
        free(i2c_data.msgs);
        return -3;
    }
    free(i2c_data.msgs);
    close(fd);

#if 0
    int i;
    printf("i2c_write 0x%02x:",buftmp[0]);
    for(i=0; i

 

好了。之后放一盒i2c-tools的下载地址

 

 

你可能感兴趣的:(i2c,eeprom,linux)