我们这里介绍一下常见的EEPROM,ATMEL的AT24x系列中的AT24C02,学会了这个芯片,其他系列的芯片也是类似的。

AT24C02的存储容量为2K bit,内容分成32页,每页8Byte (共256Byte)。

基础概念:

  • 存储容量: 存储的总数据量

  • 页:储存单元的组织方式

  • 寻址方式:访问元器件的方式,通常计算地址与这个概念有关。

寻址方式

操作时有两种寻址方式:芯片寻址和片内子地址寻址。

芯片寻址

AT24C02的芯片地址为1010,其地址控制字格式为1 0 1 0 A2 A1 A0 R/W

其中A2,A1,A0代表"可编程地址选择位"。A2,A1,A0引脚接高/低电平后得到确定的三位编码,与1010形成7位编码,即为该器件的地址码。

R/W为芯片读写控制位;该位为0,表示芯片进行写操作。取决于芯片手册中的定义,通常,W是低电平有效(0)。

有些大容量的芯片,地址组成位包括了P0P1等选择位;而这些选择位实际上是"页选择位",用来表示内部地址(如下)。但是实际上原理是类似的。

片内子地址寻址

芯片寻址可对内部 256 Bytes中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。

该类器件要通过I2C总线操作,读写过程中都要先寻址,这类器件地址由两个字节组成。

如下表,1010是固定的,A表示器件地址,可以拉高和拉低,I2C总线上可以并接2的n次方个器件。P表示具体的内部地址数,比如at24c02共有256个字节,第二个地址字节完全可以满足,不用P。但是at24c04一个有512个字节,需要9位地址线,第一个字节中的p就表示地址线了,p=0表示低256字节,1表示高256字节。

注意:一般页写可以连续写8个数据。主机每发送一个字节都要接受从机的应答信号。

该类器件是采用I2C总线进行操作的,器件地址根据容量的不同稍有不同,如下:

对于芯片的A0,A1,A2脚:(外部引脚用于芯片寻址,当接入多个IIC设备时,通过引脚电平不同,可以对多个设备进行读写操作)

  • 24C01/02:A0,A1,A2都是从设备地址。
  • 24C04,A1,A2是从设备地址,A0变为P0
  • 24C08,A2是从设备地址,A0,A1变为P0、P1
  • 24C16及以上,只有P0、P1、P2

其中,A表示器件地址,P表示页地址

在读写的时候首先是:起始条件+器件地址

器件地址如上所示在16k中,需要两个字节表示内部地址,正是P 2/1/0 和8位具体的地址

另外有关于容量的说明:

  • AT24C01:一共128页,每页1字节,共需7位地址数据

  • AT24C02:一共256页,每页1字节,共需8位地址数据

  • AT24C04:一共256页,每页2字节,共需9位地址数据

  • AT24C08:分4个块,一共256页,每页4字节,共需10位地址数据

  • AT24C16:分8块,一共256页,每页8字节,共需11位地址数据

在读写的时候要注意,一般在写的时候有页写,在读的时候是连续读,可以设置读取的个数,根据应答和非应答来结束读取。

具体的控制时序省略(关键在于:理解好地址和储存单元的计算关系,结合I2C的时序),只是需要注意:

在读取EEPROM的时候接收到多个数据时,如果不是最后一个数据,单片机要主动发出应答信号,但是接收到最后一个数据后,就不再主动应答,而是等待应答,然后结束条件。

大B与小b之间的换算:

我们常说的MB、KB中的B都是Bytes;但有一些储存芯片,它们是以Bit作为计量单位的;而 有 8Bit = 1 Byte

因此,小b除以8即可得到大B方式的表示方法。

读写操作时序

写数据

第一步:首先是I2C的起始信号,接着跟上首字节,即EEPROM的地址和读写位的组合,读写方向上选择“写”操作。

第二步:发送要写入数据的EEPROM内部存储地址。

第三步:发送要存储的数据第一个字节、第二个字节… …。

1、写数据(单片机发送)过程中,每个字节结束后EEPROM都会回应一个“应答位0”,告诉我们写EEPROM成功,如果没有应答表示未成功。

2、写数据过程中,每成功写入一个字节,EEPROM地址自动加1,当加到最大值,会溢出。

  1. //函数见I2C部分
  2. //向E2PROM中写入一个字节,addr为字节地址
  3. void E2WriteByte(unsigned char addr,unsigned char dat)
  4. {
  5. I2CStart();
  6. I2CWrite(0x50<<1);//寻址后选择为写操作
  7. I2CWrite(addr); //写入存储地址
  8. I2CWrite(dat);
  9. I2CStop();
  10. }

读数据

第一步:首先是I2C的起始信号,接着跟上首字节,即EEPROM的地址和读写位的组合,读写方向上选择“写”操作。

第二步:发送要读取的EEPROM内部存储地址。

第三步:重新发送I2C的起始信号和器件地址,并且在方向位选择“读”操作。

(在这三步中,每一个字节实际上都是在“写”,因此EEPROM都会回应一个“应答位0”。)

第四步:读取从器件发回的数据,每读一个字节,如果还想继续读下一个字节,就发送一个“应答位0”,如果不想继续读了,就发送一个“非应答位1”。

应答位: ACK

非应答位:NACK

  1. //读取E2PROM中一个字节,addr为字节地址
  2. unsigned cahr E2ReadByte(unsigned char addr)
  3. {
  4. unsigned char dat;
  5. I2CStart();
  6. I2CWrite(0x50<<1);
  7. I2CWrite(addr);
  8. I2CStart();
  9. I2CWrite((0x50<<1)|0x01);
  10. dat=I2CReadNAK();
  11. I2CStop();
  12. return dat;
  13. }

多字节进行读写操作

  1. //读取函数,buf为数据指针,addr为E2中的起始地址,len为读取长度
  2. void E2Read(unsigned char *buf,unsigned char addr,unsigned char len)
  3. {
  4. do{
  5. I2CStart();
  6. if(I2CWrite(0x50<<1))
  7. {
  8. break;
  9. }
  10. I2CStop();
  11. }while(1);//查询当前是否可以进行读写操作
  12. I2CWrite(addr);
  13. I2CStart();
  14. I2CWrite((0x50<<1)|0x01);
  15. while(len>1)//连续读取len-1个字节
  16. {
  17. *buf++=I2CReadACK();
  18. len--;
  19. }
  20. *buf=I2CReadNAK();
  21. I2CStop();
  22. }
  23. //写入函数,buf为源数据指针,addr为起始地址,len为写入长度
  24. void E2Write(unsigned char *buf,unsigned char addr,unsigned char len)
  25. {
  26. while(len--)
  27. {
  28. do{
  29. I2CStart();
  30. if(I2CWrite(0x50<<1))
  31. break;
  32. I2CStop();
  33. } while(1);
  34. I2CWrite(addr++);
  35. I2CWrite(*buf++);
  36. I2CStop();
  37. }
  38. }

页写入功能

一次性写入一页,写完再发送停止位就不用写完一个字节就检测一次

连续向页内写入几个字节后,最后发送停止位

E2检测到停止位,将该页写入

如果数据跨页,则发送一个停止位等待E2空闲后,即上一页完全写入非易失区域后,进行下一页的写入

  1. void E2Write(unsigned char *buf,unsigned char addr,unsigned char len)
  2. {
  3. while(len>0)
  4. {
  5. do{
  6. I2CStart();
  7. if(I2CWrite(0x50<<1))
  8. break;
  9. I2CStop();
  10. } while(1);
  11. I2CWrite(addr);
  12. while(len>0)
  13. {
  14. I2CWrite(*buf++);
  15. len--;
  16. addr++;
  17. if((addr&0x07)==0)//检查地址是否到达页边界,每页8字节,固检测第三位即可
  18. break;
  19. }
  20. I2CStop();
  21. }
  22. }

效率对比

多字节写入和页写入程序都编写出来了,而且页写入的程序我们还特地跨页写的数据,它们的写入时间到底差别多大呢。

我们用一些工具可以测量一下,比如示波器,逻辑分析仪等工具。

我现在把两次写入时间用逻辑分析仪给抓了出来,并且用时间标签 T1 和 T2 标注了开始位置和结束位置,如图所示,右侧显示的|T1-T2|就是最终写入 5 个字节所耗费的时间。

多字节一个一个写入,每次写入后都需要再次通信检测 EEPROM 是否在“忙”,因此耗费了大量的时间。

同样的写入 5 个字节的数据:

  • 一个一个写入用了 8.4ms 左右的时间
  • 使用页写入,只用了 3.5ms 左右的时间

附录:关于IIC-EEPROM页写问题

结论:无论从什么地址开始连续写,不能超过(跨过)一整页。

背景:

在向 EEPROM 连续写入多个字节的数据时,如果每写一个字节都要等待的话,整体上的写入效率就太低了。因此 EEPROM 的厂商就想了一个办法,把 EEPROM 分页管理。24C01、24C02 这两个型号是 8 个字节一个页,而 24C04、24C08、24C16 是 16 个字节一页。例如AT24C02,一共是 256 个字节,8 个字节一页,那么就一共有 32 页。

分配好页之后,如果我们在同一个页内连续写入几个字节后,最后再发送停止位的时序。EEPROM 检测到这个停止位后,就会一次性把这一页的数据写到非易失区域,就不需要像上节课那样写一个字节检测一次了,并且页写入的时间也不会超过 5ms。如果我们写入的数据跨页了,那么写完了一页之后,我们要发送一个停止位,然后等待并且检测 EEPROM 的空闲模式,一直等到把上一页数据完全写到非易失区域后,再进行下一页的写入,这样就可以在很大程度上提高数据的写入效率。

本质:页写的原理是通过内部写缓冲RAM实现的(读操作不需要,可以连续读)。

详解:

AT24CXX系列的EEPROM为了提高写效率,提供了页写功能。

内部有个一页大小的写缓冲RAM(地址范围也就是从00到页大小)。

发生写操作时,开始送入的地址对应的页被选中,并将其内容映像到缓冲RAM,数据从低端地址对应的缓冲RAM地址开始修改,超过这个地址范围就回到00。

写完后,就会把开始确定的EEPROM页擦除,再把一整页RAM数据写入。所有写数据都发生在开始写地址时确定的页上。

如,页容量为128,一页都是从00开始按128字节分成一个个的页;

此时,0页就是07F,1页就是80FF,类推,边界就是128字节的整数倍地址。

页RAM的地址范围为7位00~7F,写入时高端地址就是页号。

发生写操作,开始送入的地址对应的页被锁存,后续不论写多少,都在这个页中,只是一个页内的地址进行加一,超过就归零开始。从F0开始写32个字节,那么开始送入的地址为F0,就会锁定在1号页(第2个页)上,底端7位页内部地址开始从70H开始写,到达7F时回到00再到10H,也就是写在了F0FF,808F。

也就是,从01开始写也只能到7F,再往80写就跑到00上去了,这就是写操作的翻卷,datasheet上都有说明。

就是从边界前写两个字节也要分两次写。页是绝对的,按整页大小排列,不是从开始写入的地址开始算。

读没有页的问题,可以从任意地址开始读取任意大小数据,只是超过整个存储器容量时地址才回卷。但一次性访问的数据长度也不要太大。

所以,使用分页的存储器进行储存时,要做好存储管理,尽量同时读写的数据放在一个页上。

ref :

AT24C02、04、08、16 操作说明的更多相关文章

  1. buntu14.04和16.04官方默认更新源sources.list和第三方源推荐(干货!)转

    配置完成后: sudo apt-get update 安装和删除软件: sudo apt-get install sudo apt-get remove buntu14.04和16.04官方默认更新源 ...

  2. Change default network name (ens33) to old “eth0” on Ubuntu 18.04 / Ubuntu 16.04

    Change default network name (ens33) to old “eth0” on Ubuntu 18.04 / Ubuntu 16.04 By Raj Last updated ...

  3. http://www.cnblogs.com/alipayhutu/archive/2012/08/16/2643098.html

    http://www.cnblogs.com/alipayhutu/archive/2012/08/16/2643098.html

  4. linux: ubuntu 14.04 和16.04 快速下载

    由于官网服务器在国外,下载速度奇慢,所以我们可以利用阿里云镜像下载ubuntuubuntu 14.04:http://mirrors.aliyun.com/ubuntu-releases/14.04/ ...

  5. 2021.08.16 P1260 工程规划(差分约束)

    2021.08.16 P1260 工程规划(差分约束) 重点: 1.跑最短路是为了满足更多约束条件. P1260 工程规划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 造 ...

  6. 2021.08.16 P1078 文化之旅(最短路)

    2021.08.16 P1078 文化之旅(最短路) 题意: n个地,k个信仰,每个地都有自己的信仰,信仰之间会相互排斥,同信仰之间也会相互排斥,有m条路,问从s到t的最短距离是多少? 有一位使者要游 ...

  7. 2021.08.16 P1300 城市街道交通费系统(dfs)

    2021.08.16 P1300 城市街道交通费系统(dfs) P1300 城市街道交通费系统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 城市街道交费系统最近创立了.一 ...

  8. 2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意)

    2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意) P1363 幻象迷宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 幻象迷宫可以认为是无限 ...

  9. Ubuntu14.04或16.04下安装JDK1.8+Scala+Hadoop2.7.3+Spark2.0.2

    为了将Hadoop和Spark的安装简单化,今日写下此帖. 首先,要看手头有多少机器,要安装伪分布式的Hadoop+Spark还是完全分布式的,这里分别记录. 1. 伪分布式安装 伪分布式的Hadoo ...

  10. Ubuntu14.04和16.04官方默认更新源sources.list和第三方源推荐(干货!)

    不多说,直接上干货! 写在前面:笔者由于还在学校学习,学校没有开发给Linux用的上网客户端,所以只能用在windows系统中通过安装虚拟机运行linux比较方便,但没有外网,只有学校的教育网,所以我 ...

随机推荐

  1. css的animate做一个信号动画

    html <div class="jump flex-fs fadeAndScaleIn"> <span></span> <span> ...

  2. 鸿蒙HarmonyOS实战-ArkUI事件(焦点事件)

    前言 焦点事件是指程序中的重要事件或关键点.焦点事件通常是程序的核心逻辑和功能,需要引起特殊的关注和处理. 在图形用户界面(GUI)编程中,焦点事件通常与用户交互和界面输入相关.例如,当用户点击按钮. ...

  3. golang、JS AES(CBC模式)加密解密兼容

    目录 golang.JS AES(CBC模式)加密解密兼容 golang代码 前端javascript的代码 aes.js 原文地址: https://www.cnblogs.com/haima/p/ ...

  4. Golang 开发常用代码片段

    Struct to JsonString type BaseRequest struct { httpMethod string domain string path string params ma ...

  5. PCI-E与SATA SSD

    为什么要采用PCI-E通道 目前在固态硬盘SSD中,有一部分采用了SATA3.0接口,而一些高端的固态硬盘则采用了PCI-E接口.那么为什么高端固态硬盘要采用PCI-E接口呢?为了弄清楚这个问题,先看 ...

  6. 报错:Client does not support authentication protocol requested by server; consider upgrading MySQL cli

    IDEA启动项目登录时显示用户或密码错误 或者 连接mysql数据库时报错 原因: mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是ca ...

  7. leaflet 河流颜色渐变效果

    1.Leaflet-polycolor github地址:https://github.com/Oliv/leaflet-polycolor 插件缺陷:需要把每个折点的颜色都指定才行,一般做不到 2. ...

  8. leaflet常用插件汇总介绍

    1.Leaflet Ant Path(线条流动效果) 在交通项目.管网应用的项目中,常常需要标注出道路的走向.河流的流向或者管线的流向等等,Leaflet Ant Path能够很好的解决这类问题: g ...

  9. C数据结构线性表:实现顺序表的增删改查&完整篇

    文章目录 ①前言 顺序表结构体的定义 ②初始化顺序表 ③插入新的元素 插入的时候需要特别注意的几点 ④删除元素 第一个删除元素功能实现 第二个删除元素功能实现 对代码下面中**i- -**的说明(第二 ...

  10. 精准管控|AIRIOT数字油库智能化解决方案

      在油库管理的过程中,储油罐区普遍存在分布空间范围广.安全防爆要求高.监控点多.布线复杂.自动化系统集成难度大等问题,传统的油库管理手段相对落后.管理环境复杂,企业在监测监控.设备设施管理.日常运行 ...