关于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. [BI项目记]-搭建代码管理环境之服务端

    上一篇介绍如何搭建环境进行文档版本的管理,这篇主要介绍搭建环境进行代码版本的管理. 即使是BI项目也要进行代码版本管理.代码版本管理的工具有很多,VSS, SVN等都是当下大家经常提起的,这里主要介绍 ...

  2. xml schema xmlns xmlns:xsi xsi:schemaLocation targetnamespace

    先上一段xml文档 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="htt ...

  3. redis数据类型之—String

    (1)String 简单介绍 string是redis中最基本的数据类型,一个字符串类型的值存储的最大容量是1GB. (2)String 常用命令

  4. 【dom4j xml】使用dom4j处理XML文件--测试过程遇到的问题

    首先 关于dom4j的API,有如下: 当然  其中的实体引用有以下: 测试使用环境: 使用Maven搭建web环境,pom.xml文件配置如下: <project xmlns="ht ...

  5. AngularJS学习之依赖注入

    1.什么是依赖注入:简称DI,是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分. 该模式分离了客户端 ...

  6. linux 查找文件或者内容常用命令

    whereis <程序名称> find [路径] <表达式> locate <文件名称> 从文件内容查找匹配指定字符串的行: $ grep "被查找的字符 ...

  7. 从零开始山寨Caffe·贰:主存模型

    你左手是内存,右手是显存,内存可以打死显存,显存也可以打死内存. —— 请协调好你的主存 从硬件说起 物理之觞 大部分Caffe源码解读都喜欢跳过这部分,我不知道他们是什么心态,因为这恰恰是最重要的一 ...

  8. [转载]Grunt插件之LiveReload 实现页面自动刷新,所见即所得编辑

    配置文件下载  http://vdisk.weibo.com/s/DOlfks4wpIj LiveReload安装前的准备工作: 安装Node.js和Grunt,如果第一次接触,可以参考:Window ...

  9. 如何解决Linux下通过root无法远程登录

    解决问题 1.确认ssh服务已安装,通过普通用户连接成功: 2.确认ssh配置是否对root进行特殊设置,修改/etc/ssh/sshd_config文件中 PermitRootLogin witho ...

  10. 数据库 sql server

    1. if exists(select * from sys.objects where name='test') drop table test go create table test ( id ...