AT24C04A芯片基础知识

当51单片机应用系统需要存放一些在掉电后需要保存的数据时,可以使用E2^{2}2PROM。AT24C04是很常用的E2^{2}2PROM芯片。
AT24C04A是Atmel公司出品的I2^{2}2C总线接口E2^{2}2PROM,有8KB的内部存储空间,采取8字节/页、256页、2个块的分页方式。

AT24C04A的电路简图如上所示,主要有A1、A2、WP、SDA、SCL五个引脚。
SCK:I2^{2}2C总线的时钟引脚;
SDA:I2^{2}2C总线的数据引脚;
A1、A2:地址引脚,用于决定AT24C04A芯片的I2^{2}2C地址;
WP:写保护引脚。当该地址连接到GND时,芯片可以进行正常的读/写操作;当该引脚连接到VCC时,不同的芯片有不同的应用方式。
AT24C04A有自己独立的I2^{2}2C总线地址,其地址结构为“1010+A2、A1+内部页选择位+读写选择位”。当A2、A1均为0时,对AT24C02A的内部页面1进行读操作的地址是0xA1,写操作地址是0xA0。
AT24C04A的操作分为写操作和读操作,写操作包括字节写和页面写两种工作方式;而读操作则分为指定位置读、连续读和当前地址读三种工作方式。

I2^{2}2C总线基本知识

I2^{2}2C的基本结构与主要特点
在单片机系统中,带有I2^{2}2C总线接口的电路现在呗使用得越来越多,主要因为采用I2^{2}2C总线接口的器件连接线和引脚数目少,成本低。且与单片机连接简单,结构紧凑,在总线上增加器件不影响系统正常工作,系统修改和可扩展性好,即使工作时钟不同的器件,也可以直接连接到总线上。
I2^{2}2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线,即可在连接与总线上的器件之间传递信息。
I2^{2}2C总线的特点:

  • 总线只有两根线,即串行时钟线(SCL)和串行数据线(SDA),这在设计中大大减少了硬件接口。
  • 每个连接到总线上的器件都有一个用于识别的器件地址,器件地址由芯片内部硬件电路和外部地址引脚同时决定,避免了片选线的连接方法,并建立了简单的主从关系,每个器件既可以作为发送器件,又可以作为接收器。
  • 同步时钟允许器件以不同的波特率进行通信。
  • 同步时钟可以作为停止或重新启动串行口发送的握手信号。
  • 串行的数据传输位速率在标准模式下可达100kb/s,快速模式下可达400kb/s,高速模式下可达3.4Mb/s。
  • 连接到同一总线的集成电路数只受400pF的最大总线电容的限制。

I2^{2}2C总线是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。各种采用I2^{2}2C总线标准的器件均并联在总线上,每个器件内部都有I2^{2}2C接口电路,用于实现I2^{2}2C总线的连接。
每个器件都有唯一的地址,器件两两之间都可以进行信息传送。当某个器件向总线上发送信息时,它就是发送器(也叫主器件),而当其从总线上接收信息时,它又成为接收器(也叫从器件)。在信息传输过程中,主器件发送的信号分为器件地址码、器件单元地址和数据3部分,其中器件地址码用来选择从器件,确定操作的类型(类型为发送信息或者接受信息);器件单元地址用于选择器件内部的单元;数据是在各器件间传递的信息。处理过程就像打电话一样,只有拨通号码才能进行信息交流。各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。
I2^{2}2C信息传送与读写过程
当 I2^{2}2C总线没有进行信息传送时,数据线(SDA)和时钟线(SCL)都为高电平。当主器件向某个器件传送信息时,首先应向总线传递开始信号,然后才能传送信息,当信息传送结束时,应传送结束信号,开始信号和结束信号规定如下:

  • 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据;
  • 结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

开始信号和结束信号之间传递的是信息,信息的字节数没有限制,但每个字节必须为8位,高位在前,低位在后。
数据线SDA上每一位信息状态的改变只能发生在时钟线SCL为低电平期间,因为SCL为高电平期间SDA状态的改变已经被用来表示开始信号和结束信号。
主器件每次传送的信息的第一个字节必须是器件地址码,第二个字节为器件单元地址,用于实现选择所操作的器件的内部单元,从第三个字节开始,为传送的数据。

4bit器件类型码 片选 R/W‾\overline{W}W
D7-D4 D3-D1 D0

高4位为器件类型识别码(不同的芯片类型有不同的定义,EEPROM一般应为1010);接着三位为片选,同种类型器件最多可接8个,高7位用于选择对应的器件;最后一位为读写位,当为1时进行读操作,表示主器件从高总线上读取信息,为0时进行写操作,表示主器件将传送信息到总线上。
I2^{2}2C总线数据传送时,每传送一个字节数据后,都必须有应答信号。与应答信号相对应的时钟由主器件产生,发送器必须在这一时钟位上释放数据线,使其处于高电平状态,以便接收器在这一位上送出应答信号。从器件在接收到起始信号后,每接收一个地址编码或数据后都会会送一个低电平应答信号,用以表示已收到。主器件收到应答信号后,可根据实际情况做出是否继续传递信号的判断。若未收到低电平应答信号,则判断为从器件出现故障。
当主器件从从器件读取数据时,从器件发送数据,主器件接收数据,主器件接收到数据后,也发送一个低电平应答信号,从器件接收后,继续发送下一个数据,如果主器件没有发送低电平应答信号,而是高电平非应答信号,则从器件结束数据传送,且等待主器件的结束信号,然后结束读操作。

I2^{2}2C的读写操作

  • 从当前地址读

从所选器件的当前地址读,读的字节数不指定,格式如下:

开始信号 控制码(R/W‾\overline{W}W=1) 应答信号 数据1 应答信号 数据2 应答信号 结束信号
  • 从指定单元读

从所选器件的指定地址读,读的字节数不指定,格式如下:

开始信号 控制码(R/W‾\overline{W}W=1) 应答信号 器件地址 应答信号 开始信号 控制码(R/W‾\overline{W}W=1) 应答信号 数据1 应答信号 数据2 应答信号 结束信号
  • 从指定单元写

从所选器件的指定地址写,写的字节数不指定,格式如下:

开始新号 控制码(R/W‾\overline{W}W=1) 应答信号 器件单元地址 应答信号 数据1 应答信号 数据2 应答信号 结束信号

在连续读工作方式的操作过程中,当地址计数器的值超过了器件的最大地址之后会自动溢出,从而覆盖最低地址数据。

实例应用

使用串口控制向AT24C04A中写入并且读出数据。单片机通过串口从PC接收5字节数据,然后将所接收数据写入AT24C04A的指定单元,再将对应单元的数据读出后通过串口发送出去。

#include <AT89X52.h>
#include <intrins.h>#define R24C04ADD 0xA1
#define W24C04ADD 0xA0sbit SDA = P1 ^ 7;                           //数据线
sbit SCL = P1 ^ 6;                         //时钟线
sbit LED = P2 ^ 0;                         //指示灯bit bAck;                                  //应答标志 当bbAck=1是为正确的应答unsigned char wBuff[5];                      //待写入字节缓冲区
unsigned char rBuff[5];                     //读出的字节缓冲区
unsigned char rxCounter = 0;               //接收计数器
unsigned char wrCounter = 0;               //读写计数器
bit rxFlg = 0;                             //接收缓冲标志位void StartI2C();                           //启动函数
void StopI2C();                             //结束函数
void AckI2C();                              //应答函数
void SendByte(unsigned char c);             //字节发送函数
unsigned char RevByte();                    //接收一个字节数据函数
unsigned char WIICByte(unsigned char WChipAdd,unsigned char InterAdd,unsigned char WIICData);
//WChipAdd:写器件地址;InterAdd:内部地址;WIICData:待写数据;如写正确则返回0xff,
//否则返回对应错误步骤序号
unsigned char RIICByte(unsigned char WChipAdd,unsigned char RChipAdd,unsigned char InterDataAdd);
//WChipAdd:写器件地址;RChipAdd:读器件地址;InterAdd:内部地址;如写正确则返回数据,
//否则返回对应错误步骤序号
//向指定器件的内部指定地址发送一个指定字节
unsigned char WIICByte(unsigned char WChipAdd,unsigned char InterAdd,unsigned char WIICData)
{StartI2C();                                //启动总线SendByte(WChipAdd);                       //发送器件地址以及命令if (bAck==1)                          //收到应答{SendByte(InterAdd);                  //发送内部子地址if (bAck ==1){SendByte(WIICData);                //发送数据if(bAck == 1){StopI2C();                    //停止总线return(0xff);}else{return(0x03);}         }else{return(0x02);}}return(0x01);
}
//读取指定器件的内部指定地址一个字节数据
unsigned char RIICByte(unsigned char WChipAdd,unsigned char RChipAdd,unsigned char InterDataAdd)
{unsigned char TempData;    TempData = 0;StartI2C();                               //启动SendByte(WChipAdd);                     //发送器件地址以及读命令if (bAck==1)                         //收到应答{SendByte(InterDataAdd);              //发送内部子地址if (bAck ==1){StartI2C();SendByte(RChipAdd); if(bAck == 1){TempData = RevByte();       //接收数据StopI2C();                  //停止I2C总线return(TempData);           //返回数据}else{return(0x03);}  }else{return(0x02);}}else{return(0x01);}
}
//启动I2C总线,即发送起始条件
void StartI2C()
{SDA = 1;                          //发送起始条件数据信号_nop_();SCL = 1;_nop_();                           //起始建立时间大于4.7us_nop_();_nop_();_nop_();_nop_();SDA = 0;                            //发送起始信号_nop_();_nop_();_nop_();_nop_();_nop_();SCL = 0;                           //时钟操作_nop_();_nop_();
}
//结束I2C总线,即发送I2C结束条件
void StopI2C()
{SDA = 0;                          //发送结束条件的数据信号_nop_();                           //发送结束条件的时钟信号SCL = 1;                          //结束条件建立时间大于4us_nop_();_nop_();_nop_();_nop_();_nop_();SDA = 1;                            //发送I2C总线结束命令_nop_();_nop_();_nop_();_nop_();_nop_();
}
//发送一个字节的数据
void SendByte(unsigned char c)
{unsigned char BitCnt;for(BitCnt = 0;BitCnt < 8;BitCnt++)     //一个字节{if((c << BitCnt)& 0x80) SDA = 1;  //判断发送位else SDA = 0;_nop_();SCL = 1;                  //时钟线为高,通知从机开始接收数据_nop_();_nop_();_nop_();_nop_();_nop_();SCL = 0;}_nop_();_nop_();SDA = 1;                                            //释放数据线,准备接受应答位_nop_();_nop_();SCL = 1;_nop_();_nop_();_nop_();if(SDA == 1) bAck =0;else bAck = 1;                                      //判断是否收到应答信号SCL = 0;_nop_();_nop_();
}
//接收一个字节的数据
unsigned char RevByte()
{unsigned char retc;unsigned char BitCnt;retc = 0;SDA = 1;for(BitCnt=0;BitCnt<8;BitCnt++){_nop_();SCL = 0;                                     //置时钟线为低,准备接收_nop_();_nop_();_nop_();_nop_();_nop_();SCL = 1;                                       //置时钟线为高使得数据有效_nop_();_nop_();retc = retc << 1;                              //左移补零if (SDA == 1)retc = retc + 1;                                 //当数据为1则收到的数据+1_nop_();_nop_();}SCL = 0;_nop_();_nop_();return(retc);             //返回收到的数据
}void InitUART(void)
{TMOD = 0x20;              //9600bpsSCON = 0x50;TH1 = 0xFD;TL1 = TH1;PCON = 0x00;EA = 1;ES = 1;TR1 = 1;
}
void Send(unsigned char x)
{SBUF = x;while(TI == 0);TI = 0;
}
void Serial(void) interrupt 4 using 1
{if(RI == 1)              //接收数据{RI = 0;wBuff[rxCounter] = SBUF;rxCounter++;            //计数器++if(rxCounter>4)           //到了第16个字节{rxCounter = 0;      //清除rxFlg = 1;             //接收缓冲标志位置位}}
}main()
{unsigned char temp;InitUART();                         //初始化串口while(1){while(rxFlg == 0);                    //等待接收标志位被置位rxFlg = 0;                         //清除接收标志位                           for(wrCounter=0;wrCounter<5;wrCounter++)   {rBuff[wrCounter] = RIICByte(W24C04ADD,R24C04ADD,(0x01+wrCounter));    //连续读取一字节数据,共16字节Send(rBuff[wrCounter]);           //将数据通过串口发送}for(wrCounter=0;wrCounter<5;wrCounter++){temp = WIICByte(W24C04ADD,(0x01+wrCounter),wBuff[wrCounter]); //      Send(temp); //连续写入16字节数据}}
}

MCS-51单片机总结——No4.存储之AT24C04A相关推荐

  1. 基于51单片机语音录音机存储与播放回放系统设计

    摘要 语音信号处理属于信息科学的一个重要分支,大规模集成技术的高度发展和计算机技术的飞速前进,推动了这一技术的发展.在数字音频技术和多媒体技术迅速发展的今天,传统的磁带语音录放系统因体积大.使用不便. ...

  2. 51单片机空间的存储

    8051存储器包括程序存储器和数据存储器,从逻辑结构上看,可以分为三个不同的空间: (1) 64KB的程序存储器地址空间:0000H~FFFFH,其中0000H~0FFFH为片内4KB的ROM地址空间 ...

  3. 在51单片机上跑RTOS有没有意义?

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | 嵌入式专栏 最近看见我的一个技术交流群在讨论一个问题:在51单片机上跑RTOS有没有意义? 今天就来围绕51和R ...

  4. 软件与计算机硬件加密,51单片机程序进行软件加密和硬件解密的方法

    由于固化在片外EPROM 里的单片机程序容易复制,所以,如不在技术上采取保护措施,则程序中所采用的处理方法易被他人分析仿制.对单片机程序进行加密是一种有效的保护措施,也是一项实用的技术.虽然本身带有E ...

  5. 51单片机c语言试题及答案,最新单片机试题库分章节答案解析(C语言)

    精品文档 器中. 三.选择题 1.51单片机在同一优先级的中断源同时申请中断时,首先响应( A ). A. 外部中断0 B. 定时器0中断 C.外部中断1 D. 定时器1中断 2.下列说法错误的是:( ...

  6. 对存储还搞不清楚,先看看这篇文章-从51单片机上去理解存储器

    存储器是许多存储单元的集合,存储器单元实际上是时序逻辑电路(锁存器)的一种,按单元号顺序排列.每个单元由若干二进制位构成,以表示存储单元中存放的数值,这种结构和数组的结构非常相似.按存储器的使用类型可 ...

  7. (十一)51单片机——用AT24C02实现存储秒表数据(附成果展示)

    目录 存储器 RAM ROM 存储器简化模型 AT24C02介绍 引脚及应用电路 内部结构框图 I2C总线 I2C总线介绍 I2C电路规范 I2C时序结构 起始条件 终止条件 发送一个字节 接受一个字 ...

  8. 51单片机综合课程设计多功能电子秤(显示时间、温度、存储、串口、报警装置等)

    51单片机综合课程设计----多功能电子秤 关键词:proteus仿真.51单片机.DS1302时钟芯片.DB18B20温度芯片.AT24C02存储芯片.LCD1602液晶屏.ADC0832芯片等,文 ...

  9. 51单片机中变量的存储 xdata bdata idata pdata区别

    先来看data.bdata.idata.pdata.xdata.code指代的意思. 然后我们对应到51单片机的存储空间: 从上面可以知道: 1.51的存储空间分为指令空间和数据空间,他们独立编址.指 ...

最新文章

  1. 【JZOJ4835】【GDOI2017模拟10.31】量化交易
  2. 怎么给工作中重要的pdf文件加密
  3. 5、Power Map—实例:填充地图
  4. 日志 查看匹配内容的前后几行
  5. Leecode 268. 丢失的数字——Leecode每日一题系列
  6. 搭建大数据运行环境之一
  7. VMware相关产品下载(随时更新)
  8. 自制安装包集成.net framework 4.0
  9. HDOJ 2035 人见人爱A^B
  10. 淘宝API代码c#实例(摘)
  11. WinForm窗体美化
  12. Allegro SigXplorer 等长设置方法-比较简单
  13. 桌面级显卡天梯图(显卡性能对比图.2018.11)
  14. STM32配合火焰传感器的火灾报警
  15. c++贪吃蛇源代码 完整版
  16. 【读书笔记】组合计数中的行列式方法
  17. MPD大会上使用的PPT分享
  18. 信息学奥赛一本通 1255:迷宫问题 | OpenJudge NOI 2.5 7084:迷宫问题
  19. 大佬解读 | 华为发布会: 牛逼鸿蒙,吹水的大会
  20. IPGUARD卸载客户端方法

热门文章

  1. 数学建模动态规划的小案例之R代码实现——生产计划问题
  2. 重新排序(排序不等式+差分)蓝桥
  3. Scyther工具形式化分析Woo-Lam协议
  4. layui:图片上传
  5. BiliBili系列(二):个人历史数据爬取与分析
  6. 缓存加速--Squid代理服务器应用(传统代理、透明代理)
  7. leetcode:一道清华考研专业课算法题
  8. STM32输入捕获实验
  9. 【NetWorkX实例(4)】Football数据集
  10. Redis Windows版本的安装以及使用(简单版)