首先,介绍一下我们要驱动的芯片:AT24C02
AT24C02的存储容量为2Kb,内容分成32页,每页8B,共256B,操作时有两种寻址方式:芯片寻址和片内子地址寻址。
(1)芯片寻址:AT24C02的芯片地址为1010,其地址控制字格式为 1010A2A1A0R/W。其中A2,A1,A0可编程地址选择位。
A2,A1,A0引脚接高、低电平后得到确定的三位编码,与1010形成7位编码, 即为该器件的地址码。R/W为芯片读写控制位,
该位为0,表示芯片进行写操作。
(2)片内子地址寻址:芯片寻址可对内部256B中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。
我们采用的是第2种 寻址方式。
另外,有一个问题需要了解一下,就是EEPROM 与flash , 什么时候使用EEPROM,什么时候用FLASH合适。
Flash存储器又称闪存,它结合了ROM和RAM的长处,不仅具备
电子可擦除可编程(EEPROM)的性能,还可以快速读取数据(NVRAM的优势),使数据不会因为断电而丢失。U盘和MP3里用的就是这种存储器。用作存储Bootloader以及操作系统或者程序代码,或者直接当硬盘使用(U盘)。
一, EEPROM以单字节读写,FLASH部分芯片只能以块方式擦除(整片擦除),部分芯片可以单字节写入(编程),一般需要采用块写入方式;
二,FLASH比EEPROM读写速度更快,可靠性更高。
三,价格方面比较,FLASH比EEPROM贵。
So,我们的版卡参数信息,等一些固定的,小量的,不需要经常修改资料信息放在EEPROM中。而flash作为存储程序的存储器,存放操作系统代码等需要快速读写的,经常访问的数据。
其次,我们来看看linux iic的驱动框架:
到这里,我们就可以写应用测试程序了!
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define I2C_RETRIES 0x0701
- #define I2C_tiMEOUT 0x0702
- #define I2C_RDWR 0x0707
- // not include READ/WRITE bit
- #define I2C_ADDR 0x50
- struct i2c_msg
- {
- unsigned short addr;
- unsigned short flags;
- #define I2C_M_TEN 0x0010
- #define I2C_M_RD 0x0001
- unsigned short len;
- unsigned char *buf;
- };
- struct i2c_rdwr_ioctl_data
- {
- struct i2c_msg *msgs;
- int nmsgs;
- };
- int main(int argc, char** argv){
- int fd,ret;
- char buf[100];
- struct i2c_rdwr_ioctl_data e2prom_data;
- //disable WP
- //system("echo 103 > /sys/class/gpio/export");
- //system("echo "out" > /sys/class/gpio/gpio103/direction");
- //system("echo 0 > /sys/class/gpio/gpio103/value");
- fd = open(argv[1],O_RDWR);
- if(fd<0){
- perror("open error");
- }
- e2prom_data.nmsgs=2;
- e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(struct i2c_msg));
- if(!e2prom_data.msgs)
- {
- perror("malloc error");
- exit(1);
- }
- ioctl(fd,I2C_TIMEOUT,1);
- ioctl(fd,I2C_RETRIES,2);
- /* write data to e2prom */
- e2prom_data.nmsgs=1;
- (e2prom_data.msgs[0]).len = 6;
- (e2prom_data.msgs[0]).addr = I2C_ADDR;
- (e2prom_data.msgs[0]).flags = 0; //write
- (e2prom_data.msgs[0]).buf = (unsigned char*)malloc(6);
- (e2prom_data.msgs[0]).buf[0] = 0x00;// e2prom addr[15:8]
- (e2prom_data.msgs[0]).buf[1] = 0x00;//e2prom addr[7:0]
- (e2prom_data.msgs[0]).buf[2] = 0x55;//the data to write byte0
- (e2prom_data.msgs[0]).buf[3] = 0x66;//the data to write byte1
- (e2prom_data.msgs[0]).buf[4] = 0x77;//the data to write byte2
- (e2prom_data.msgs[0]).buf[5] = 0x88;//the data to write byte2
- ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
- if(ret<0)
- {
- perror("ioctl error1");
- }
- sleep(1);
-
- /* read data from e2prom */
- e2prom_data.nmsgs=2;
- (e2prom_data.msgs[0]).len=2;
- (e2prom_data.msgs[0]).addr=I2C_ADDR;
- (e2prom_data.msgs[0]).flags=0;
- (e2prom_data.msgs[0]).buf=(unsigned char*)malloc(2);
- (e2prom_data.msgs[0]).buf[0]=0x00;// e2prom addr[15:8]
- (e2prom_data.msgs[0]).buf[1]=0x00;//e2prom addr[7:0]
- (e2prom_data.msgs[1]).len=6;
- (e2prom_data.msgs[1]).addr=I2C_ADDR;
- (e2prom_data.msgs[1]).flags=I2C_M_RD;
- (e2prom_data.msgs[1]).buf=(unsigned char*)malloc(6);
- (e2prom_data.msgs[1]).buf[0]=0;
- (e2prom_data.msgs[1]).buf[1]=0;
- (e2prom_data.msgs[1]).buf[2]=0;
- (e2prom_data.msgs[1]).buf[3]=0;
- (e2prom_data.msgs[1]).buf[4]=0;
- (e2prom_data.msgs[1]).buf[5]=0;
- ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
- if(ret<0)
- {
- perror("ioctl error2");
- }
- printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[0]);
- printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[1]);
- printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[2]);
- printf("Read back:0x%02Xnr",(e2prom_data.msgs[1]).buf[3]);
- close(fd);
- //system("echo 103 > /sys/class/gpio/unexport");
- return 0;
- }
至此,我们可以把以上代码测试,通过串口sz命令把编译出来的可执行文件发送到
开发板执行了!