【轉】24Cxx 系列EEPROM通用程序及應用

關於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 
     
    頭文件能夠寫成預編譯模式,方便移植後修改,PAGE_SIZE爲一頁的存儲量,EE_SIZE爲芯片的存儲量,然後一些程序的判斷也根據選擇的存儲芯片來判斷。
頂層用於外部程序調用的函數只有兩個,讀和寫兩個狀況而已
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);
 
傳遞函數有三個:
pBuffer:要存儲或讀出來的數據所在的變量存儲區字符串頭指針;
WriteAddress/ReadAddress:要存入EEPROM所在的存儲空間的第一個存儲空間地址;
NumbyteToWrite:數據寫入或讀出的字節個數;
這樣的應用比較簡單 例如在頭文件中分配了兩類數據的存儲空間起始地址DATA一、DATA2
#define DATA1  0x0010
#define DATA2  0x0050
存儲數據所在緩存 EE_Buffer[20],應用程序以下寫法:
EEPROM_Write(EE_Buffer,DATA1,20);
這樣EE_Buffer內的數據便被寫入EEPROM中 0x10~0x30 的數據存儲空間中了。
合理的分配陪EEPROM 的存儲空間對數據管理很是重要。甚至於能夠做爲一個小型黑匣子同樣。
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;
    }
}

 

接下來的是是IIC_ReadBuffer、IIC_WriteBuffer,兩個函數主要是對存入數據的處理,如頁面內寫入,超過頁面數量的數據處理等,我這裏把函數定義爲static 函數只能對內部應用,外部只能調用上面的兩個函數,累似於API函數同樣,這也能夠避免沒必要要的程序調用書寫。IIC_ReadBuffer函數相對簡單,由於讀取沒有對頁面的限制,能夠無限制的讀下去。讀取緩存的函數只對地址作一下判斷便可。寫入函數較爲複雜,需判斷數據起始存儲地址 和頁等關係
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.補充頁面寫完後超出的不足一頁數據量的數據***/
}
    }
}

 

 
剩下的是IIC_WritePage()、IIC_ReadPage()兩個函數是芯片的IIC通信底層函數,根據單片機的IIC通信模式寫入便可。以上的程序可通用到任何24Cxx 系列所應用的程序。
 
     在實際應用中要注意的即是存儲空間的分配,已經空間長度的輸入,這樣EEPROM的使用便能駕輕就熟。
 
 
參考來源:虛V界的我的空間的博客-> 24Cxx 系列EEPROM通用程序及應用,http://home.eeworld.com.cn/my/space-uid-93649-blogid-77560.html
相關文章
相關標籤/搜索