关于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,);

这样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 ;
}
else
{// 连续写入两次避免因EMC等因素造成的写入失败情况
IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite);
IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite); //读取eeprom 的数据与缓存中的数据对比 相同为确认写入成功
IIC_ReadBuffer(&TempBuffer,WriteAddress+NumbyteToWrite-,);
Temp2Buffer=*(pBuffer+NumbyteToWrite-);
if(TempBuffer==Temp2Buffer)
return ;
else
return ;
}
} unsigned char EEPROM_Read(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite)
{
if((ReadAddress+NumbyteToWrite) > EE_SIZE)
{
return ;
}
else
{
IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite);
IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite);
return ;
}
}
接下来的是是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=;
/******pageAddress is over 8bit***********/
/******判断存储地址是否超过8位************/
#if EEPROM < 32
PageAddress=(u8)(ReadAddress>>)&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=,NumOfSingle=; //
u16 Part=;//
u8 PageAddress=;
/******pageAddress is over 8bit***********/
/******判断存储地址是否超过8位************/
#if EEPROM < 32
PageAddress=(u8)(WriteAddress>>)&0x0E|WriteAddress_EEPROM;
#else
PageAddress=WriteAddress_EEPROM;
#endif /*********判断起始地址与跨页地址的字节个数********/
Part=WriteAddress/PAGE_SIZE;
if(Part!=)
{
Part=PAGE_SIZE*(Part+)-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!=)
{
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
 

【转】24Cxx 系列EEPROM通用程序及应用的更多相关文章

  1. 硬件和软件兼容i2c协议的24Cxx系列EEPROM存储器(转)

    源:硬件和软件兼容i2c协议的24Cxx系列EEPROM存储器 硬件上由于24c01的A0A1A2管脚不允许悬空,故暂时的想法是兼容24c02 ---24c16 使用一个dip8封装的芯片插座,A0 ...

  2. 使用Prism6 建立 Windows 10 通用程序.

    使用Prism6 建立 Windows 10 通用程序. 目标: 使用prism6,建立Windows 通用程序项目. 1, 解决方案—添加新建项目—通用—空白应用—输入名称—确定—确定 2 ,引用上 ...

  3. Win10通用程序 UWP版HtmlAgilityPack UWP应用使用示例

    Win10 UWP版HtmlAgilityPack,UWP应用使用示例下载. Win10 发布了一个多星期,sdk是随着一起发布的,我安装好vs2015和sdk 开发UWP 通用程序. 在做网络解析的 ...

  4. 使用 Visual Studio 生成通用的 XAML 应用程序 (Windows Phone 和 Windows 通用程序)

    在Build会议上,我们发布了新的版本---Windows Phone 8.1. Windows 8.1 平台.作为开发人员,这意味着您现在可以生成 XAML 和 HTML 的通用程序,并通过分享大量 ...

  5. Sprite Kit教程:制作一个通用程序 2

    注1:本文译自Sprite Kit Tutorial: Making a Universal App: Part 2 目录 动画的定义:可行性 属性列表 添加游戏逻辑 添加音效 何去何从 上一篇文章中 ...

  6. 用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署

    用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署 这是微软官方SignalR 2.0教程Getting Started with En ...

  7. ABAP表抛FTP通用程序

    主要功能: 1.支持R3所有表(标准.自建)下传,下传方式为FTP 2.支持输出字段选择及顺序调整 3.支持动态条件,不同的表会有不同的选择条件,根据不同的条件选择需要下传的数据 4.支持单表.多表. ...

  8. Delphi Excel导入 的通用程序转载

    Delphi Excel导入 的通用程序 (-- ::)转载▼ 标签: it 分类: Delphi相关 步骤: 连excel(自己知道其格式,最好是没个字段在数据一一对应) 读excel数据,填入到数 ...

  9. hive表增量抽取到mysql(关系数据库)的通用程序(三)

    hive表增量抽取到oracle数据库的通用程序(一) hive表增量抽取到oracle数据库的通用程序(二) 这几天又用到了该功能了,所以又改进了一版,增加了全量抽取和批量抽取两个参数.并且可以设置 ...

随机推荐

  1. java面试题及答案(转载)

    JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...

  2. 如何创建 Code Snippet

    比如有一行自定义代码段: @property (nonatomic,copy) NSString *<#string#>; 需要添加到 Code Snippet 上,以帮助开发人员开发更便 ...

  3. October 16th Week 43rd Sunday 2016

    Life is not a problem to be solved, but a reality to be experienced. 人生不是待解决的难题,而是等着我们去体验的现实. Life i ...

  4. ajax完整格式

    $.ajax({             url: encodeURI( "@Url.Action("NavList", "Home")"  ...

  5. C++中随机数和不重复的随机数

    随机数 int rand (); rand函数返回一个0-32767之间的一个伪随机整数,32767可以由宏RAND_MAX表示,该函数需要头文件<stdlib.h>. 常用的是如何生成一 ...

  6. 前端设计中关于外部js文件加载的速度优化

    在一般情况下,许多人都是将<script>写在了<head>标签中,而许多浏览器都是使用单一的线程来加载js文件的,从上往下,从左往右. 若是加载过程出错,那么网页就会阻塞,就 ...

  7. Ring3下的DLL注入(NtCreateThreadEx + LdrLoadDll方式实现,可以注入系统进程)

    工具介绍及使用请移步:http://blog.csdn.net/sunflover454/article/details/50441014 本文首发在零日安全论坛:http://www.jmpoep. ...

  8. windows消息钩子注册底层机制浅析

    标 题: [原创]消息钩子注册浅析 作 者: RootSuLe 时 间: 2011-06-18,23:10:34 链 接: http://bbs.pediy.com/showthread.php?t= ...

  9. HTML5页面绘图

    canvas 标签:获取画笔: 对象.getContext("2d")制定画笔Syte: context.fillStyle = "red"; context. ...

  10. SPOJ HIGH Highways ——Matrix-Tree定理 高斯消元

    [题目分析] Matrix-Tree定理+高斯消元 求矩阵行列式的值,就可以得到生成树的个数. 至于证明,可以去看Vflea King(炸树狂魔)的博客 [代码] #include <cmath ...