關於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.補充頁面寫完後超出的不足一頁數據量的數據***/ } } }