关于I2C 学习的时候介绍得最多的就是24C02 这里存储EEPROM了,但学的时候基本只是讲讲简单的I2C 的总线数据传输而已,即便先gooogle上搜索也绝大部分这这样的文章,不多有说到如何在实际状况中如何使用的程序。html
24Cxx系列数据块存储时也是比较讲究的,缓存
图为 几类不一样容量的芯片的存储空间结构,24C16如下空间的大于8位后的寻址高位地址在片选地址中选择,详细看芯片手册。另外要注意的就是字节页,一次连续写入的数据量不能超过一页的数据量。有些老款的芯片甚至不支持跨页写入。为了适用也参照不跨页写入的方法写这个程序。而读取数据没有这个限制,只要单片机开辟的缓存够大,能够一直连续读下去。
函数
/*****24Cxx Seriel EEPROM*************************/ #define EEPROM 8 /******** 01 -> 24C01; 02 -> 24C02; 04 -> 24C04; 08 -> 24C08; 16 -> 24C16; 32 -> 24C32; 64 -> 24C64; 128 -> 24C128; 256-> 24C256; 512 -> 24C512; *****/ #if EEPROM==1 #define PAGE_SIZE 8 #define EE_SIZE 0x007F #elif EEPROM==2 #define PAGE_SIZE 16 #define EE_SIZE 0x00FF #elif EEPROM==4 #define PAGE_SIZE 16 #define EE_SIZE 0x01FF #elif EEPROM==8 #define PAGE_SIZE 16 #define EE_SIZE 0x03FF #elif EEPROM==16 #define PAGE_SIZE 16 #define EE_SIZE 0x07FF #elif EEPROM==32 #define PAGE_SIZE 32 #define EE_SIZE 0x0FFF #elif EEPROM==64 #define PAGE_SIZE 32 #define EE_SIZE 0x1FFF #elif EEPROM==128 #define PAGE_SIZE 64 #define EE_SIZE 0x3FFF #elif EEPROM==256 #define PAGE_SIZE 64 #define EE_SIZE 0x7FFF #elif EEPROM==512 #define PAGE_SIZE 128 #define EE_SIZE 0xFFFF #endif
unsigned char EEPROM_Write(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumbyteToWrite); unsigned char EEPROM_Read(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite);
#define DATA1 0x0010 #define DATA2 0x0050
EEPROM_Write(EE_Buffer,DATA1,20);
unsigned char EEPROM_Write(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumbyteToWrite) { unsigned char TempBuffer,Temp2Buffer; if((WriteAddress+NumbyteToWrite) > EE_SIZE) //判断是否超出存储空间 { return 0; } else {// 连续写入两次避免因EMC等因素形成的写入失败状况 IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite); IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite); //读取eeprom 的数据与缓存中的数据对比 相同为确认写入成功 IIC_ReadBuffer(&TempBuffer,WriteAddress+NumbyteToWrite-1,1); Temp2Buffer=*(pBuffer+NumbyteToWrite-1); if(TempBuffer==Temp2Buffer) return 1; else return 0; } } unsigned char EEPROM_Read(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite) { if((ReadAddress+NumbyteToWrite) > EE_SIZE) { return 0; } else { IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite); IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite); return 1; } }
static void IIC_ReadBuffer(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite); static void IIC_WriteBuffer(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumByteToWrite); void IIC_ReadBuffer(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite) { u8 PageAddress=0; /******pageAddress is over 8bit***********/ /******判断存储地址是否超过8位************/ #if EEPROM < 32 PageAddress=(u8)(ReadAddress>>7)&0x0E|ReadAddress_EEPROM; #else PageAddress=WriteAddress_EEPROM; #endif IIC_ReadPage(pBuffer,PageAddress,ReadAddress,NumbyteToWrite); } void IIC_WriteBuffer(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumByteToWrite) { u8 NumOfPage=0,NumOfSingle=0; // u16 Part=0;// u8 PageAddress=0; /******pageAddress is over 8bit***********/ /******判断存储地址是否超过8位************/ #if EEPROM < 32 PageAddress=(u8)(WriteAddress>>7)&0x0E|WriteAddress_EEPROM; #else PageAddress=WriteAddress_EEPROM; #endif /*********判断起始地址与跨页地址的字节个数********/ Part=WriteAddress/PAGE_SIZE; if(Part!=0) { Part=PAGE_SIZE*(Part+1)-WriteAddress; } else { Part=PAGE_SIZE-WriteAddress; } /******/ if(Part >= NumByteToWrite) { /***写入的数据个数小于跨页剩余的个数可直接写入 ***/ IIC_WritePage(pBuffer,PageAddress,WriteAddress,NumByteToWrite); } else { NumOfPage = (NumByteToWrite-Part)/PAGE_SIZE; NumOfSingle = (NumByteToWrite-Part)%PAGE_SIZE; pBuffer = IIC_WritePage(pBuffer,PageAddress,WriteAddress,Part); /***1.写入的数据个数大于跨页剩余的个数先把剩余的跨页个数填充满 ***/ NumByteToWrite -= Part; WriteAddress += Part; while(NumOfPage--) { pBuffer = IIC_WritePage(pBuffer,PageAddress,WriteAddress,PAGE_SIZE); /***2.按计算的数据量占页面数,连续写入页面*******/ WriteAddress += PAGE_SIZE; } if(NumOfSingle!=0) { IIC_WritePage(pBuffer,PageAddress,WriteAddress,NumOfSingle); /***3.补充页面写完后超出的不足一页数据量的数据***/ } } }