i2c|I2C外挂eeprom的读写
I2C简介
【i2c|I2C外挂eeprom的读写】I2C总线通信是一种通信协,用于连接微控制器及其外围设备,由两根线组成,时钟线SDA和数据线SCL。
文章图片
如图所示,外挂设备接到相应的线上就可以被i2c识别到,另外关于scl,sda以怎么样的波形去发送消息,以及设备的应答波纹就不在详细介绍了,这个对于不是直接写驱动的开发人员来说没有必要了解,上层应用很少去以一个一个电位的形式发消息,有需要的可以再找专业的文章了解;
EEPROM
eeprom是一种掉电后数据不丢失的存储器,常用来存储一些配置信息,以便系统重新上电的时候加载之。例如,可以写Mac、IP、用户验证信息等。eeprom市场上提供的类型有许多,主要是内存大小的差异,有1K, 2K, 4K等容量,注意有些是以b为单位,有些是以B为单位,不过厂家为了显大都会以b为单位,就像厂家的1M是以1000算的文不是1024。
文章图片
如图是某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 检测总线上挂载的设备地址
文章图片
0是你要检测的总线代号
i2cdump -f -y 0 0x500是总线代号,0X50是挂载地址
文章图片
如图默认值为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的下载地址
推荐阅读
- 完美解决小区老人出行难题|完美解决小区老人出行难题 沃克斯外挂式电梯备受好评
- GD32VF103|GD32VF103 I2C 通讯
- 协议|I2C总线协议
- 基于at91rm9200的i2c分析(DS1307实时时钟芯片)
- I2C总线之(一)---概述
- Linux I2C驱动(2012-08-24 14:37:21)
- Linux|Linux驱动子系统之I2C(3)
- C语言|Linux i2c 读写应用程序
- 掉电可保存时钟
- 子类__I2C|[RK3399][Android7.1] 调试笔记 AM1805调试