eeprom的wp 引脚_EEPROM存储芯片24C02

1、24C02简介

24C02是一个2Kbit的串行EEPROM存储芯片,可存储256个字节数据。工作电压范围为1.8V到6.0V,具有低功耗CMOS技术,自定时擦写周期,1000000次编程/擦除周期,可保存数据100年。24C02有一个16字节的页写缓冲器和一个写保护功能。通过I2C总线通讯读写芯片数据,通讯时钟频率可达400KHz。

可以通过存储IC的型号来计算芯片的存储容量是多大,比如24C02后面的02表示的是可存储2Kbit的数据,转换为字节的存储量为2*1024/8 = 256byte;有比如24C04后面的04表示的是可存储4Kbit的数据,转换为字节的储存量为2*1024/8 = 512byte;以此来类推其它型号的存储空间。

24C02的管脚图如下:

VCC和VSS是芯片的电源和地,电压的工作范围为:+1.8V~+6.0V。

A0、A1、A2是IC的地址选择脚。

WP是写保护使能脚。

SCL是I2C通讯时钟引脚。

SDA是I2C通讯数据引脚。

2、24C02的设备地址和写保护功能

I2C主机在与24C02通讯时,需要发送一个设备地址进行寻址,在I2C总线上,每一个从机设备的地址都是唯一的。

24C02的设备地址包含两部分,第一部分是bit7~bit4是固定的“1010”,第二部分bit3~bit1位由A2、A1、A0组成。主机在与24C02进行通讯时,除了发送设备地址还需要发送数据的读写方向位R/W,24C02的是设备地址与R/W位组成了一个字节的数据。如下图:

上图列出了几个存储IC的设备地址与R/W位组成的字节。由图中可以看到,存储IC地址的bit7~bit4位固定为“1010”;bit3~bit1位由A2、A1、A0引脚的电平状态决定,如果Ax接的是电源(高电平),那么Ax=1,如果Ax接的是地,那么Ax=0,即由A2、A1、A0可以组合成8种设备地址,也就是说在同一个I2C总线上可以同时挂载8个24C02芯片。一般如果I2C总线上只有一片24C02芯片的话,A2、A1、A0引脚都接到地。

由于24C02只有256个字节的存储空间,所以只需要1个字节就可以寻址完24C02的存储空间,但是无法寻址完更大容量的存储IC,比如24C04的存储容量是512字节,需要9个bit的地址位才能寻址完。由上图可以看到,24C04的设备地址内是没有A0参数的,被a8代替了,这个a8就是24C04的第9个bit的地址位,也就是说24C04的A0引脚是不起作用的,这样也就造成了在I2C总线上只能同时挂载4个24C04芯片。其它存储器如24C08、24C16也可以这么类推。

24C02的WP引脚是写保护引脚,当WP引脚接高电平的时,24C02只能进行读取操作,不能进行写操作。只有当WP引脚悬空或接低电平时,24C02才能进行写操作。

3、24C02数据读取操作

在这里只是对24C02的读写进行一些说明和一些注意的实现,不会涉及具体的程序代码,只是进行代码概述,工程代码已经上传到个人GitHub中,感兴趣的可以去GitHub中下载查看,GitHub代码地址如下:

MCU通过使用I2C读取24C02任意存储空间地址内的数据,代码如下:

1 uint8_t AT24CXX_READ_ONE_BYTE(uint16_t address)2 {3 uint8_t dat;4

5 I2C_START();6 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_WIRTE_CMD);7 if(AT24CXX_ERR != 0)//没有响应直接退出

8 {9 AT24CXX_ERR = I2C_WRITE_BYTE(address & 0xFF);10 if(AT24CXX_ERR != 0)11 {12 I2C_START();13

14 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_READ_CMD);15 if(AT24CXX_ERR != 0)16 {17 dat = I2C_READ_BYTE(0);18 I2C_STOP();19 }20 }21 }22

23 returndat;24 }

第5行主机产生一个I2C起始信号,第6行发送设备地址和写数据位给24C02,第9行是发送需要读取的地址给24C02,第12行主机产生一个重复起始信号,第14行设备地址和读数据位给24C02,第17行是读取24C02相应地址存储的数据。第18行是主机产生I2C结束信号。

在上面的程序代码中,AT24CXX_ERR是用来获取24C02的应答信号,如果主机与24C02的通讯正常,主机每发送一个字节给24C02,24C02都会反馈一个应答信号给主机,如果24C02没有反馈应答信号,那么说明24C02正在进行其它操作或者通讯异常导致无法通讯,主机会产生一个结束信号来结束操作。在I2C_WRITE_BYTE()函数内部有一个等待应答信号的操作,如果没有收到应答信号,在I2C_WRITE_BYTE()函数内会产生一个停止信号来结束当前操作。AT24CXX_ERR用来判断接下来的操作是否执行,如果AT24CXX_ERR=0说明没有收到应答信号,直接退本次读取操作;如果AT24CXX_ERR!=0说明有收到应答信号,继续读取操作。

24C02内部有一个地址计数器,主机发送要读写的存储空间地址给24C02,就相当于改变24C02的内部地址计数器的值,主机每读写一个字节24C02之后,它内部地址计数器的值就会自动加1。也就是说如果当前地址是N,那么主机读取完一个字节的数据之后,再次读的话就变为了读取N+1地址的数据。

这里需要注意的一点是,24C02的内部地址计数器的地址只能从0~255之间递增,这是因为24C02的存储控制只有256个字节,地址计数器只能在0~255(共256个地址)内变化。如果连续读取使得地址计数器超过255,那么地址计数器就会从0地址开始循环。比如说当前内部计数器地址为255,主机在读取一个字节数据之后会导致内部计数器地址变为0,那么主机再次读取数据的时候读取得到的是24C02地址0的数据。

MCU使用I2C连续读取24C02内多个存储空间地址数数的代码如下:

1 void AT24CXX_READ_BUFF(uint16_t address,uint8_t *buffer,uint16_t Len)2 {3 uint16_t i;4

5 I2C_START();6 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_WIRTE_CMD);7 if(AT24CXX_ERR != 0)//没有响应直接退出

8 {9 AT24CXX_ERR = I2C_WRITE_BYTE(address & 0xFF);10 if(AT24CXX_ERR != 0)11 {12 I2C_START();13 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_READ_CMD);14 if(AT24CXX_ERR != 0)15 {16 for(i=0;i

22 if(AT24CXX_ERR != 0)23 {24 I2C_STOP();25 }26 }27 }28 }

上面的代码,大部分跟读取一个字节的程序代码是一样的,不一样的是第16~19行,这里用一个for循环来连续读取24C02内的数据,这里并没有对超范围读取数据进行限制,所以在使用的时候需要注意不要连续读取超过24C02的存储空间,就算超过也不会有问题,只是会重新开始从0地址读取。

4、24C02数据写入操作

MCU使用I2C写入一个字节数据到24C02任意存储空间地址内的代码如下:

1 voidAT24CXX_WRITE_ONE_BYTE(uint16_t address,uint8_t dat)2 {3 I2C_START();4 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_WIRTE_CMD);5 if(AT24CXX_ERR != 0)//没有响应直接退出

6 {7 AT24CXX_ERR = I2C_WRITE_BYTE(address & 0xFF);8 if(AT24CXX_ERR != 0)9 {10 AT24CXX_ERR =I2C_WRITE_BYTE(dat);11 if(AT24CXX_ERR != 0)12 {13 I2C_STOP();14 }15 }16 }17 }

第3行主机产生一个I2C起始信号,第4行发送设备地址和写数据位给24C02,第7行是发送需要写入数据的地址给24C02,第10行是将要写入的数据发送给24C02。第18行是主机产生I2C结束信号。上面大部分操作跟读取是一样的,不一样的只是最后将读取操作改为了写入操作。

如果需要连续写入数据,可以如下:

1 for(i = 0;i < 256;i ++)2 {3 AT24C02_BUFF[i] =i;4 AT24CXX_WRITE_ONE_BYTE(i,AT24C02_BUFF[i]);5 }

但是在实际使用的过程中,发现只有一部分AT24C02_BUFF[]数组里面的数据被写入到了24C02当中,有一些数据没有写进24C02。这是因为24C02擦写数据没有那么快,需要一定的时间,在24C02正在擦写数据的过程中,是不会应答主机的通讯的,所以如果主机在写入一个数据之后又立马写入另一个数据,就会导致24C02跟不上主机的通讯速度从而导致无法写入数据。

需要注意的是24C02并不是在主机发送数据给24C02之后就立马擦写数据的,24C02是在主机产停止信号之后才开始擦写数据的,并且在擦写数据完成之前不会响应主机的其它操作。

可以通过一定的延时函数来等待24C02擦写完成,代码如下:

for(i = 0;i < 256;i ++)

{

AT24C02_BUFF[i]=i;

AT24CXX_WRITE_ONE_BYTE(i,AT24C02_BUFF[i]);

HAL_Delay(1);

}

通过调用HAL_Delay()函数进行延时,具体的延时时间可以通过调试来决定,这里使用1ms的延时时间,具体24C02擦写数据需要多久并不清楚。

除了通过延时函数进行等待24C02擦写完成,也可以通过发送设备地址给24C02,然后查询是否有应答信号返回来判断24C02是否擦写完成。24C02在擦写数据时是不会反馈应答信号给主机的,这样就可以通过不断的发送数据给24C02,然后查询应答信号来判断24C02是否擦写完成,一旦擦写完成就可以进行下一个数据的写入。代码如下:

1 void Wait_AT24CXX_WRITE_OK(void)2 {3 uint8_t Wait_Cnt;4

5 Wait_Cnt = 50;6 do

7 {8 I2C_START();9 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_WIRTE_CMD);10 if(AT24CXX_ERR != 0)11 {12 I2C_STOP();//接收到响应信号退出

13 break;14 }15

16 }while(Wait_Cnt--);17

18 }

Wait_Cnt是一个次数限制变量,不能无限的在里面等待,不然遇到异常就有可能造成程序卡死。

程序通过发送起始信号、发送设备地址和写数据方向给24C02,如果24C02反馈了一个应答信号给主机,主机就产生一个停止信号,然后退出当前循环。应用代码如下:

1 for(i = 0;i < 256;i ++)2 {3 AT24C02_BUFF[i] =i;4 AT24CXX_WRITE_ONE_BYTE(i,AT24C02_BUFF[i]);5 Wait_AT24CXX_WRITE_OK();//可以通过发送设备地址给从机,通过从机反馈的响应信号来判断从机是否可以正常通讯

6 }

5、24C02页写入

24C02有一个页写入功能,可以连续写入16个字节的数据。

24C02可以以页来划分存储空间,每16个字节组成一个页,24C02的存储空间大小为256个字节,所以24C02总共有16个页。如:

页0:地址从0x00~0x0F

页1:地址从0x10~0x1F

......

页15:地址从0xF0~0xFF

24C02可以在一个页内连续的写入数据,但是需要注意的是如果写入的数据超过页大小,那么就会覆盖页初始地址的值,比如说连续写入3个数据,第1个数据写入到地址0x0F当中,第2个数据由于溢出页的限制,会被写入到地址0x00当中,第3个数据会被写入到地址0x01当中。

以个人的理解,24C02内部有一个16byte的数据缓存器,在上面的介绍中知道,主机在发送数据给24C02的时候,24C02是不会擦写数据的,只有当主机发送停止信号之后24C02才会擦写数据。那么当主机发送数据给24C02时,只是将数据写入到了24C02内部的缓存器中,只有当主机发送结束信号之后,24C02才将缓存器内的数据写入到内部存储空间。

由24C02的数据缓存器只有16个byte(每个型号的存储IC的页大小是不一样的也就是缓存器大小是不不一样的)。所以如果写入的数据超过缓存器的大小就会覆盖之前写入的数据。

使用页写入连续将数据写入24C02的代码如下:

1 void AT24CXX_WRITE_BUFF(uint16_t address,uint8_t *Buffer,uint16_t Len)2 {3 uint8_t i;4 uint16_t re_main;5

6 if(address >= 256)//对输入的地址进行限制,24C02只有256个字节的存储空间,其它型号的存储器IC可以通过查资料

7 {8 return;9 }10

11 re_main = 256 - address;//计算出还有多少存储空间

12

13 if(Len > re_main)//如果要写入的数据量超过剩余存储空间,则只写入剩余存储空间数量的数据

14 {15 Len =re_main;16 }17

18 re_main = 16 - address%16;//计算当前页还可以写入多少个数据

19

20 if(Len <= re_main)//如果要写入的数据小于等于当前页剩余的存储空间,则只写入Len个字节数据就好,不需要跨页操作

21 {22 re_main =Len;23 }24

25 do

26 {27 I2C_START();28 AT24CXX_ERR =I2C_WRITE_BYTE(AT24CXX_WIRTE_CMD);29 if(AT24CXX_ERR == 0)//没有响应直接退出

30 {31 break;32 }33

34 I2C_WRITE_BYTE(address & 0xFF);35 for(i = 0;i < re_main;i ++)//最多连续写入一个页数据的大小

36 {37 AT24CXX_ERR =I2C_WRITE_BYTE(Buffer[i]);38 }39

40 I2C_STOP();41 Wait_AT24CXX_WRITE_OK();//等待24C02完成擦写数据动作

42

43 if(re_main !=Len)44 {45 address += re_main;//已经写入re_main个数据,

46 Buffer +=re_main;47 Len -=re_main;48

49 re_main = 16;//写一个页的的大小也是16个字节

50

51 if(Len <=re_main)52 {53 re_main =Len;54 }55 }56 else

57 {58 break;//数据写入完成退出

59 }60 }61 while(1);62 }

AT24CXX_WRITE_BUFF()函数的思路如下:

首先判断输入的地址是否超过存储IC的存储空间,如果超过则退出,如第6~9行。

计算出输入的地址到存储器存储的结束地址剩余多少空间,如果要写入的数据比剩余空间还多,那么剩余多少空间就写入多少空间,需要写入的多余部分就去掉,如第11~16行。

计算当前页还可以写入多少数据,如果当前页剩余的空间比Len要写入的数据长度还大,那么只要写入当前页就足够了,不需要再跨页写入数据。如第18~23行。

通过一个while(1)循环连续写入数据到24C02中。

第27~41行是将re_main个数据写入到24C02当中,由于是在一个页内操作,所以可以连续写入,写完之后在产生一个结束信号然后等待24C02擦写完成。

如果不需要跨页写入就已经将数据全部写完,那么就可以直接break退出while循环,如第58行。

如果需要跨页写入数据,还需要将地址、buffer、Len减去已经写入的数据量,然后下一个页可以写入整个页的数据量,也就是16个字节,通过比较判断一个页的剩余空间是否能够写完剩余的Len数据,如果不行就重复循环操作,如果可以写完,在写完之后就退出while循环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP实现数据库事务处理的方法

在开发Web应用时&#xff0c;无一例外地需要访问数据库&#xff0c;以完成对数据的查询、插入、更新、删除等操作。受应用逻辑的影响&#xff0c;有时需要将多条数据库操作指令组成一个工作单元&#xff08;事务&#xff09;。在数据库中&#xff0c;所谓事务是指一组逻辑操作单…

Session会话技术

一、概念和快速入门 其中&#xff0c;一次会话则关闭浏览器后服务器端的Session数据就会清除&#xff1b; 二、原理 三、session详解 1、 2、 服务器关闭&#xff0c;内存销毁&#xff0c;开启服务要向系统底层资源申请内存&#xff1b; 创建对象分配地址值是随机的&#xff1b…

Spark MaprLab-Auction Data分析

2019独角兽企业重金招聘Python工程师标准>>> 一、环境安装 1.安装hadoop http://my.oschina.net/u/204498/blog/519789 2.安装spark 3.启动hadoop 4.启动spark 二、 1.数据准备 从MAPR官网上下载数据DEV360DATA.zip并上传到server上。 [hadoophftclclw0001 spark-1.…

labimage 怎样旋转图片_大理石旋转楼梯的测量方法,你学会了吗?

楼梯踏步使用什么材料比较好?大理石、木材以及瓷砖都是不错的选择大家可以根据自家的要求和经济条件进行选择天然大理石花色非常丰富在做了防护之后&#xff0c;光泽度就更加高端大气大理石本身不易变形硬度高&#xff0c;磨性强&#xff0c;组织缜密能够保证长期不变形&#…

asp.net日历控件My97DatePicker下载地址

http://www.my97.net/dp/demo转载于:https://www.cnblogs.com/554006164/archive/2009/04/08/1431676.html

VC++ MFC获取对话框上控件的位置

CRect rect;GetDlgItem(控件ID)->GetWindowRect(&rect);//获取控件的屏幕坐标 ScreenToClient(&rect);//转换为对话框上的客户坐标 转载于:https://www.cnblogs.com/lujin49/p/4921194.html

session案例之验证码

一、需求分析 其中&#xff0c;一张图片就是一个单独的请求&#xff1b; 一个验证验证码的Servlet&#xff0c;还有一个验证用户名和密码的Servlet&#xff0c;两次都可能有错误信息返回到前端页面&#xff0c;所以前面页面要从request域中获取返回的错误信息&#xff1b; 登录…

元数据

1. 什么是元数据任何文件系统中的数据分为数据和元数据。数据是指普通文件中的实际数据&#xff0c;而元数据指用来描述一个文件的特征的系统数据&#xff0c;诸如访问权限、文件拥有者以及文件数据块的分布信息(inode...)等等。在集群文件系统中&#xff0c;分布信息包括文件在…

php spry文本域_《PHP和MySQL Web 开发》第8章 设计Web数据库

封面人物刘承羽前言这是我学习《PHP和MySQL Web 开发》的读书笔记&#xff0c;一些重要的知识点我会记录下来&#xff0c;当然只会写我觉得重要的。如果有幸有人看到这个学习笔记了&#xff0c;你要结合着书看&#xff0c;不要光看这个笔记。在笔记里我会记录一些我学习中遇到的…

Appium+Robotframework实现Android应用的自动化测试-2:Windows中启动Appium和模拟器

一.启动Appium 安装好了之后&#xff0c;在桌面或者菜单中找到Appium&#xff0c;分别双击或点击打开Appium.exe&#xff0c;如果一切正常&#xff0c;接着会出现一个Appium启动后的界面窗口&#xff0c;如下图所示。 1.1 Android Settings 点击左上角的第一个机器人图标&#…

数据导出生成word附件使用POI的XWPFTemplate对象

比较常用的实现Java导入、导出Excel的技术有两种Jakarta POI和Java Excel。Jakarta POI 是一套用于访问微软格式文档的Java API。Jakarta POI有很多组件组成&#xff0c;其中有用于 操作Excel格式文件的HSSF和 用于操作Word的HWPF&#xff1b; 一、前端使用get请求和post请求都…

python小仙女_python——time库整理(基础知识+实例)

先上目录&#xff0c;1.Time库的作用2. Time库的使用3.实例1.Time库的作用time库是Python中处理时间的标准库提供获取系统时间并格式化输出功能提供系统级精确计时功能&#xff0c;用于程序性能分析2. Time库的使用先明确几个概念&#xff1a;时间戳&#xff1a;格林威治时间19…

JavaScript调用Web Services实现无刷新三联动

http://singlepine.cnblogs.com/articles/301009.html 使用微软提供的webservice.htc实现通过JavaScript调用WebService.1.首先从微软网站上下载webservice.htc,我附件源代码也包含&#xff0c;不下载也可以http://msdn.microsoft.com/workshop/author/webservice/webservice.h…

ArcGIS server for java 安装配置一 续

今天又发生件奇怪的事&#xff0c;昨天配置好的server for java环境&#xff0c;开机后rest服务有无法访问了&#xff0c;反复重装了几次&#xff0c;发现安装后 8399端口可以 使用&#xff0c;但修改了server.xml后&#xff0c;重启发现端口有无法使用了&#xff0c;提示端口下…

python爬虫-异常处理

URLerror产生原因&#xff1a; 网络未连接&#xff08;即不能上网&#xff09;服务器不存在1 #-*-coding:utf-8-*- 2 import urllib2 3 requesturllib2.Request(http://www.wujiadong.com)#这是一个不能打开的网址 4 responseurllib2.urlopen(request) 5 htmlresponse.read() 6…

将给定数据源生成静态HTML页面持久化到项目之外的硬盘

一、java代码 设置好数据源map Map<String,String> mapnew HashMap<>();map.put("knowledgeName",tBasKnowledgebase.getKnowledgeName());map.put("htmlContent",tBasKnowledgebase.getHtmlContent());map.put("publishDate",new j…

qt qthead里如何响应信号_Qt 中的多线程技术(翻译)

原文链接Multithreading Technologies in Qt​doc.qt.io正文Qt 提供一系列的类与函数来处理多线程。Qt 开发者们可以使用下面四种方法来实现多线程应用。QThread: 底层 API 与可选的事件循环作为 Qt 进行线程控制的基石&#xff0c;每一个 QThread 实例都代表并控制着一个线程。…

SATA盘与SAS盘的区别

在过去的20年中&#xff0c;并行&#xff08;Paralle&#xff09;总线接口在存储市场上占据了主导的地位。但随着CPU时钟频率和内存带宽的不断提升&#xff0c;两种主要的并行总线接口技术ATA和SCSI逐渐显现出不足来。尽管ATA和SCSI均是并行总线接口&#xff0c;但是它们之间却…

如何彻底删除SVN中的文件和文件夹(附恢复方法)

在SVN中如果删除某个文件或文件夹也可以在历史记录中进行找回&#xff0c;有的时候需要彻底删除某些文件&#xff0c;即不希望通过历史记录进行恢复&#xff0c;需要在服务器上对SVN的数据进行重新整理这里假设SVN项目的目录为 /data/svn/project&#xff0c;我们想排除trunk/t…

Linux 技巧: Bash 测试和比较函数

http://www.ibm.com/developerworks/cn/linux/l-bash-test.html 转载于:https://www.cnblogs.com/daojian/archive/2012/07/16/2593960.html