26091|42

381

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

24Cxx 系列EEPROM通用程序及应用(STM32 应用函数文件) [复制链接]

 

         (论坛到现在对chrome的支持还是非常不好,上传附件失败以及把排版弄乱等,使得我不得不编辑了好几次,幸好还不是用linux,不然都发不了了)


        关于I2C 学习的时候介绍得最多的就是24C02 这里存储EEPROM了,但学的时候基本只是讲讲简单的I2C 的总线数据传输而已,即使先gooogle上搜索也绝大部分这这样的文章,很少有说到如何在实际情况中如何使用的程序。

    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:数据写入或读出的字节个数;
这样的应用比较简单 例如在头文件中分配了两类数据的存储空间起始地址DATA1、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的使用便能得心应手


EEPROM.c (8.22 KB, 下载次数: 1138)
EEPROM.h (2.22 KB, 下载次数: 983)
可自行修改IIIC_WritePageIIC_ReadPage  两通讯函数即可应用于其他平台

[ 本帖最后由 虚V界 于 2012-8-17 11:53 编辑 ]
此帖出自stm32/stm8论坛

最新回复

感谢楼主了,真需要这东西   详情 回复 发表于 2020-6-7 10:30

赞赏

1

查看全部赞赏

点赞 关注(8)
 

回复
举报

3836

帖子

19

TA的资源

纯净的硅(中级)

沙发
 
字体很漂亮 很精致 :)
此帖出自stm32/stm8论坛
 
 

回复

381

帖子

0

TA的资源

纯净的硅(高级)

板凳
 
我自己博客上Copy过来的,上面有这种字体
此帖出自stm32/stm8论坛

点评

#if EEPROM < 32 PageAddress=(u8)(WriteAddress>>7)&0x0E|WriteAddress_EEPROM; #else PageAddress=WriteAddress_EEPROM; #endif 这里不应该是移位 8位么,求解答 急急急  详情 回复 发表于 2015-3-9 22:14
 
 

回复

50

帖子

0

TA的资源

一粒金砂(中级)

4
 
好东西。
此帖出自stm32/stm8论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

5
 

这个不错

要顶下,避免重复劳动
此帖出自stm32/stm8论坛
 
 
 

回复

381

帖子

0

TA的资源

纯净的硅(高级)

6
 
  没人看 以后还是会有人重复劳动
此帖出自stm32/stm8论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

7
 
注释的很详细,适合初学者。非常感谢
此帖出自stm32/stm8论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

8
 
继续顶啊  谢谢
此帖出自stm32/stm8论坛
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

9
 
抓下来参考一下,谢谢楼主
此帖出自stm32/stm8论坛
 
 
 

回复

38

帖子

1

TA的资源

一粒金砂(中级)

10
 
之前用的时候,发现大容量的EEPROM用硬件IIC驱动不了,有没有遇到这种情况的?请指教啊,谢谢
此帖出自stm32/stm8论坛
 
 
 

回复

14

帖子

0

TA的资源

一粒金砂(中级)

11
 
收下了
此帖出自stm32/stm8论坛
 
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

12
 
太感谢楼主了,真需要这东西
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

1

TA的资源

一粒金砂(中级)

13
 
谢谢。。
此帖出自stm32/stm8论坛
 
 
 

回复

117

帖子

0

TA的资源

一粒金砂(中级)

14
 
正好在写EEPROM的程序  用的大容量的128k的  发现怎么就是驱动不了  读写不对  参考一下
此帖出自stm32/stm8论坛
 
 
 

回复

8

帖子

1

TA的资源

一粒金砂(初级)

15
 
虚V界 发表于 2012-8-16 18:52
我自己博客上Copy过来的,上面有这种字体


#if EEPROM < 32
  PageAddress=(u8)(WriteAddress>>7)&0x0E|WriteAddress_EEPROM;
#else
  PageAddress=WriteAddress_EEPROM;
#endif



这里不应该是移位 8位么,求解答 急急急


此帖出自stm32/stm8论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

16
 
感谢分享!!!!
此帖出自stm32/stm8论坛
 
 
 

回复

3

帖子

1

TA的资源

一粒金砂(中级)

17
 
里面有个定义找不到,不知道是什么值?是宏定义吗?    ReadAddress_EEPROM
此帖出自stm32/stm8论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

18
 
不能用,不知道问题在哪?用st的程序会数据会乱。
此帖出自stm32/stm8论坛
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

19
 
感谢楼主的分享。
此帖出自stm32/stm8论坛
 
 
 

回复

9

帖子

2

TA的资源

一粒金砂(初级)

20
 
正好要学习
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表