i2c|I2C外挂eeprom的读写

I2C简介
【i2c|I2C外挂eeprom的读写】I2C总线通信是一种通信协,用于连接微控制器及其外围设备,由两根线组成,时钟线SDA和数据线SCL。
i2c|I2C外挂eeprom的读写
文章图片

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

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

如图是某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|I2C外挂eeprom的读写
文章图片

图中i2c-3, i2c-0的3和0就是该两条总线的代号
i2cdetect -r -y 0 检测总线上挂载的设备地址
i2c|I2C外挂eeprom的读写
文章图片

0是你要检测的总线代号
i2cdump -f -y 0 0x500是总线代号,0X50是挂载地址
i2c|I2C外挂eeprom的读写
文章图片

如图默认值为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的下载地址


    推荐阅读