首页 > 其他分享 >AT24C02存储芯片

AT24C02存储芯片

时间:2024-07-06 14:26:12浏览次数:15  
标签:SCL 应答 存储芯片 发送 AT24C02 I2C SDA

AT24C02芯片

目录

AT24C02芯片

一、基本参数

二、接口与引脚

三、功能特点

四、I2C时序结构

起始条件和终止条件

字节传输

发送一个字节:

接受一个字节

发送应答和接受应答

发送完之后要接收应答

接收完之后要发送应答

发送应答

接受应答

发送一帧数据

接收一帧数据

先发送再接受(复合格式)

字节写和随机读

字节写

随机读

五、代码实现

I2C(Inter-Integrated Circuit)总线协议的简单通信功能

I2C接口与AT24C02 EEPROM进行通信

AT24C02_WriteByte 函数

AT24C02_ReadByte 函数

六、使用注意事项


一、基本参数

  • 存储容量:2Kbit,即内部含有256个8位字节的存储空间。

  • 工作电压:宽范围,从1.8V至5.5V。

  • 通信接口:采用I2C(Inter-Integrated Circuit)串行总线接口,这是一种广泛使用的二线制串行总线标准。

  • 存储速率:支持400KHz的传输速率(在特定电压下,如1.8V, 2.5V, 2.7V, 3.6V)。

  • 可擦写次数:高达100万次(也有资料指出为10000次,这可能是不同批次或版本之间的差异,但通常认为其可擦写次数非常可观)。

  • 存储器保持时间:数据保留时间超过100年,但也有资料指出为10年,这可能与具体的工作环境和使用条件有关。

  • 工作温度范围:-40℃至+85℃

二、接口与引脚

  • 引脚配置:AT24C02通常具有8个引脚,包括电源引脚(VCC和GND)、串行数据输入/输出引脚(SDA)、串行时钟输入引脚(SCL)、写保护引脚(WP)以及用于设置器件地址的引脚(A0、A1、A2)。

  • I2C总线:SDA和SCL引脚用于通过I2C总线与主控设备(如单片机)进行通信。SDA是双向数据线,SCL是时钟线。两者都需要通过上拉电阻连接到正电源,以确保在总线空闲时保持高电平状态。

三、功能特点

  • 低功耗:采用先进的CMOS技术,工作电流低(1mA),待机电流极低(1uA),适合低功耗应用。

  • 写保护功能:具有硬件写保护功能,通过WP引脚控制。当WP引脚接地时,允许正常的读/写操作;当WP引脚接高电平时,禁止写操作,以保护存储器内的数据不被意外更改。

  • 灵活的寻址方式:通过A0、A1、A2引脚可以设置不同的器件地址,以实现多个AT24C02芯片在同一I2C总线上的级联使用。

  • 高速读写:写入速度快(小于10ms),支持快速数据存取。

四、I2C时序结构

起始条件和终止条件
  • 起始条件:SCl高电平期间,SDA从高电平切换到低电平

  • 终止条件:SCl高电平期间,SDA从低电平切换到高电平

注意:SCL处于高电平之间的时候,SDA才可以切换电平

代码所示:

/*
I2C开始函数
​
*/
​
​
void I2C_Start(void)
{
    SDA=1;
    SCL=1;
    SDA=0;
    SCL=0;
}
​
/*
I2C停止函数
​
*/
void I2C_Stop(void)
{
    SDA=0;
    SCL=1;
    SDA=1;
}

字节传输
发送一个字节:

SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次即可发送一个字节

高位在前,在SCL处于高电平之间,SDA不允许有数据变化,高电平读取,低电平写

此时单片机是机,at24c02是从机

注意:在发送完一个字节之后,要拉高SCL,再拉高SDA

代码所示:

/*
I2C发送一个字节
Byte为要发送的字节
​
*/
void I2C_SendByte(ucha Byte)
{
    ucha i;
    for(i=0;i<8;i++)
    {
        SDA=Byte&(0x80>>i);
        SCL=1;
        SCL=0;
    }
}

接收一个字节:

注意:主机在接受数据之前,需要先释放SDA,即SDA=1;拉高电平

发送的时候主机控制scl读取和sda发送,接收的时候主机就只控制scl读取了,sda给从机发数据用

代码所示:

/*
I2C接受一个字节
Byte接收到的一个字节数据
​
*/
ucha I2C_ReceiveByte(void)
{
    ucha i,Byte=0x00;
    SDA=1;
    for(i=0;i<8;i++)
    {
        SCL=1;
        if(SDA)
        {
            Byte|=(0x80>>i);//if判断,此时从机拿着话语权,从机在SDA上发送0或1的状态,主机对从机发送的状态进行翻译 |=(0x80),从机送过来一个状态,主机翻译一个,将结果丢入Byte这个小盒子,最终返回出来
        }
        SCL=0;
    }
    return Byte;   
}
发送应答和接受应答

注意,无论什么时候SDA在接受之前,都要释放SDA***

发送完一个字节之后要接受应答,接受完一个字节后要发送应答

发送完之后要接收应答

当一方(发送方)发送完数据后,它通常会期望从另一方(接收方)接收一个应答信号。这个应答信号的作用主要是:

  1. 确认接收:应答信号是接收方告诉发送方“我已经收到了你发送的数据”的一种方式。

  2. 错误检测:如果接收方在接收过程中发现数据错误(如校验错误),它可能会发送一个不应答(NACK)信号来通知发送方。

  3. 流控制:应答机制还可以帮助控制数据流的速度。如果接收方因为某种原因(如缓冲区满)无法立即处理更多数据,它可以通过不应答来告诉发送方暂时停止发送。

接收完之后要发送应答

当接收方成功接收到数据后,它通常需要发送一个应答信号给发送方。这个应答信号的作用主要是:

  1. 确认处理:应答信号是接收方告诉发送方“我已经成功处理了你发送的数据”的一种方式。

  2. 请求更多数据:在某些协议中,接收方的应答可能还包含请求发送方继续发送更多数据的信号。

  3. 维持通信:通过发送应答,接收方告诉发送方它仍然在线并准备好进行进一步的通信

发送应答:
/*
I2C发送应答
askbit 为应答位,0为应答,1为非应答
*/
​
void I2C_SendAck(ucha ackbit)
{
    SDA=ackbit;
    SCL=1;
    SCL=0;
}
接受应答:
/*
I2C接受应答位
返回值为接受到的应答位,0为应答,1为非应答
​
*/
unsigned char I2C_ReceiveAck(void)
{
    ucha AckBit,i;
    SDA=1;//释放SDA
    SCL=1;
    AckBit=SDA;
    SCL=0;  
    return AckBit;
}

发送一帧数据

高电位读,低电位写 前四位固定为1010,A2~A0为手动配置(i2c地址),末尾为读写标志位

接收一帧数据

此时,总线的控制权交给了从机,最后一个字节发非应答,停止

先发送再接受(复合格式)

字节写和随机读

第一个为器件地址,第二个为字地址(用于指定器件内部的具体寄存器或内存位置,以便进行读写操作)

字节写

代码所示:

/*
            AT24C02写入一个字节
            WordADDress 要写入字节的地址
            Data 要写入的数据
​
*/   
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
    //ucha ack;
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS);
//  ack=I2C_ReceiveAck();   //返回的结果为0,0为从机应答之后的回馈信号
//  if(ack==0)
//  {
//      P2=0x00;
//  }                    
    I2C_ReceiveAck();
    I2C_SendByte(WordAddress);
    I2C_ReceiveAck();
    I2C_SendByte(Data);
    I2C_ReceiveAck();
    I2C_Stop();
}

随机读

代码所示:

/*
            AT24C02读取一个字节
            WordADDress 要读出字节的地址
            返回值为读出的数据
*/
​
ucha AT24C02_ReadByte(ucha WordAddress)
{
    ucha Data;
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS);
    I2C_ReceiveAck();
    I2C_SendByte(WordAddress);
    I2C_ReceiveAck();
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS|0x01);
    I2C_ReceiveAck();
    Data=I2C_ReceiveByte();
    I2C_SendAck(1);//SDA等于1为非应答,SDA等于0为应答,SCL等于1为相应应答,为0拒绝应答
    I2C_Stop(); 
    return Data;
}

五、代码实现

I2C(Inter-Integrated Circuit)总线协议的简单通信功能
  1. I2C_Start(void) 这个函数用于生成I2C总线的启动条件。首先,通过拉高SDA和SCL线确保总线处于空闲状态,然后SDA在SCL为高电平时被拉低,形成启动条件。

  2. I2C_Stop(void) 这个函数用于生成I2C总线的停止条件。首先,SDA在SCL为高电平时被拉低,然后SCL被拉高,最后SDA在SCL为高电平时被拉高,形成停止条件。

  3. I2C_SendByte(ucha Byte) 这个函数用于通过I2C总线发送一个字节的数据。它通过循环将字节的每一位(从最高位开始)依次放到SDA线上,并在SCL的每个上升沿将位值锁存到总线上。注意,这里有一个小错误:在循环中,SDA的值应该是通过位操作来设置的,但(Byte&(0x80>>i))实际上并不正确,因为这会使得每次迭代时掩码的值递减(从0x00到0x01),而不是检查Byte的每一位。正确的应该是(Byte & (0x80 >> i)),但通常我们会写为(Byte >> i) & 0x01来确保只检查当前位。

  4. I2C_ReceiveByte(void) 这个函数用于通过I2C总线接收一个字节的数据。在接收过程中,SDA线被释放为高阻态(由外部设备驱动),然后通过检测SCL上升沿时SDA的状态来接收每一位数据。接收到的位被左移并累加,最终形成一个完整的字节。

  5. I2C_SendAck(ucha ackbit) 这个函数用于发送一个应答信号(ACK)或非应答信号(NACK)。它通过设置SDA线的状态(低电平为ACK,高电平为NACK),然后拉高SCL线一个时钟周期来实现。

  6. I2C_ReceiveAck(void) 这个函数用于接收一个应答位。它首先释放SDA线(设置为输入模式),然后拉高SCL线一个时钟周期,读取SDA线的状态(低电平为ACK,高电平为NACK),并将状态返回。

#include <REGX52.H>
​
sbit SCL=P2^1;
sbit SDA=P2^0;
​
typedef unsigned int uint;
typedef unsigned char ucha;
​
/*
I2C开始函数
​
*/
​
​
void I2C_Start(void)
{
    SDA=1;
    SCL=1;
    SDA=0;
    SCL=0;
}
​
/*
I2C停止函数
​
*/
void I2C_Stop(void)
{
    SDA=0;
    SCL=1;
    SDA=1;
}
​
/*
I2C发送一个字节
Byte为要发送的字节
​
*/
void I2C_SendByte(ucha Byte)
{
    ucha i;
    for(i=0;i<8;i++)
    {
        SDA=Byte&(0x80>>i);
        SCL=1;
        SCL=0;
    }
}
​
/*
I2C接受一个字节
Byte接收到的一个字节数据
​
*/
ucha I2C_ReceiveByte(void)
{
    ucha i,Byte=0x00;
    SDA=1;
    for(i=0;i<8;i++)
    {
        SCL=1;
        if(SDA)
        {
            Byte|=(0x80>>i);//if判断,此时从机拿着话语权,从机在SDA上发送0或1的状态,主机对从机发送的状态进行翻译 |=(0x80),从机送过来一个状态,主机翻译一个,将结果丢入Byte这个小盒子,最终返回出来
        }
        SCL=0;
    }
    return Byte;   
}
​
/*
I2C发送应答
askbit 为应答位,0为应答,1为非应答
*/
​
void I2C_SendAck(ucha ackbit)
{
    SDA=ackbit;
    SCL=1;
    SCL=0;
}
​
/*
I2C接受应答位
返回值为接受到的应答位,0为应答,1为非应答
​
*/
unsigned char I2C_ReceiveAck(void)
{
    ucha AckBit,i;
    SDA=1;//释放SDA
    SCL=1;
    AckBit=SDA;
    SCL=0;  
    return AckBit;
}
I2C接口与AT24C02 EEPROM进行通信
AT24C02_WriteByte 函数

这个函数的目的是向AT24C02 EEPROM的指定地址写入一个字节的数据。

  • 参数WordAddress 是要写入数据的地址(一个无符号字符),Data 是要写入该地址的数据(也是一个无符号字符)。

  • 过程

    1. 调用 I2C_Start() 发送I2C起始条件。

    2. 调用 I2C_SendByte(AT24C02_ADDRESS) 发送EEPROM的设备地址(0xa0),注意这里的地址是以写模式发送的(末尾为0)。

    3. 调用 I2C_ReceiveAck() 接收从设备的应答,但这里并没有处理应答的结果。在实际应用中,应该检查应答以确认从设备是否已准备好接收数据。

    4. 调用 I2C_SendByte(WordAddress) 发送要写入数据的地址。

    5. 再次调用 I2C_ReceiveAck() 接收应答,确认地址已被从设备接收。

    6. 调用 I2C_SendByte(Data) 发送要写入的数据。

    7. 调用 I2C_ReceiveAck() 接收应答,但同样没有处理结果。

    8. 调用 I2C_Stop() 发送I2C停止条件,结束通信。

注意:函数中的 I2C_ReceiveAck() 调用虽然接收了应答,但没有检查其返回值来确定通信是否成功。在实际应用中,应该根据应答结果来决定是否继续执行或进行错误处理。

AT24C02_ReadByte 函数

这个函数的目的是从AT24C02 EEPROM的指定地址读取一个字节的数据。

  • 参数WordAddress 是要读取数据的地址(一个无符号字符)。

  • 返回值:从指定地址读取的数据(一个无符号字符)。

  • 过程

    1. 调用 I2C_Start() 发送I2C起始条件。

    2. 调用 I2C_SendByte(AT24C02_ADDRESS) 发送EEPROM的设备地址(以写模式),以便设置要读取数据的地址。

    3. 调用 I2C_ReceiveAck() 接收应答。

    4. 调用 I2C_SendByte(WordAddress) 发送要读取数据的地址。

    5. 再次调用 I2C_ReceiveAck() 接收应答。

    6. 调用 I2C_Start() 再次发送I2C起始条件。

    7. 调用 I2C_SendByte(AT24C02_ADDRESS|0x01) 发送EEPROM的设备地址(这次以读模式发送,通过将地址的最低位设置为1来实现)。

    8. 调用 I2C_ReceiveAck() 接收应答。

    9. 调用 I2C_ReceiveByte() 接收从设备发送的数据,并将其存储在 Data 变量中。

    10. 调用 I2C_SendAck(1) 发送非应答信号(SDA为高电平),告诉从设备不需要更多数据。

    11. 调用 I2C_Stop() 发送I2C停止条件,结束通信。

    12. 返回读取到的数据 Data

这个函数正确地实现了通过I2C接口从AT24C02 EEPROM读取数据的过程。不过,同样需要注意的是,在实际应用中应该根据 I2C_ReceiveAck() 的返回值来确认通信的每一步是否成功。

#include <REGX52.H>
#include "I2C.h"
#include "AT24C02.h"
​
#define AT24C02_ADDRESS 0xa0   // 1010 0000  末尾为0是写入,1为读取 低位写,高位读
​
typedef unsigned int uint;
typedef unsigned char ucha;
​
/*
            AT24C02写入一个字节
            WordADDress 要写入字节的地址
            Data 要写入的数据
​
*/   
void AT24C02_WriteByte(ucha WordAddress,ucha Data)
{
    //ucha ack;
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS);
//  ack=I2C_ReceiveAck();   //返回的结果为0,0为从机应答之后的回馈信号
//  if(ack==0)
//  {
//      P2=0x00;
//  }                    
    I2C_ReceiveAck();
    I2C_SendByte(WordAddress);
    I2C_ReceiveAck();
    I2C_SendByte(Data);
    I2C_ReceiveAck();
    I2C_Stop();
}
​
/*
            AT24C02读取一个字节
            WordADDress 要读出字节的地址
            返回值为读出的数据
*/
​
ucha AT24C02_ReadByte(ucha WordAddress)
{
    ucha Data;
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS);
    I2C_ReceiveAck();
    I2C_SendByte(WordAddress);
    I2C_ReceiveAck();
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS|0x01);
    I2C_ReceiveAck();
    Data=I2C_ReceiveByte();
    I2C_SendAck(1);//SDA等于1为非应答,SDA等于0为应答,SCL等于1为相应应答,为0拒绝应答
    I2C_Stop(); 
    return Data;
}

六、使用注意事项

  • 在使用AT24C02时,需要确保I2C总线的时序和协议得到正确遵守,以避免通信失败或数据错误。

  • 在进行写操作时,需要注意写保护引脚的状态,以避免意外地禁止写操作。

  • 当需要连续写入多个字节时,应注意写入周期的限制,以避免写入速度过快导致的问题。

综上所述,AT24C02是一种功能强大、易于使用的串行EEPROM芯片,适用于多种低功耗、高速存储的应用场景。

标签:SCL,应答,存储芯片,发送,AT24C02,I2C,SDA
From: https://blog.csdn.net/2302_79960206/article/details/140227894

相关文章

  • IIC驱动-基于EEPROM存储芯片AT24C02模块和三合一环境传感器AP3216C
    本文将基于IIC协议编写EEPROM芯片AT24C02存储芯片的IIC驱动程序,本文内容将分为三个部分:imx6ull的IIC控制器介绍,AT24C02存储芯片介绍,IIC的Linux驱动程序编写。关于IIC协议的内容与介绍这里不展开,相关资料很多,可以自行去查阅,但是这里需要注意的是,IIC协议本身就是一个协议,只是一些基......
  • 基于at24c02的按键检测C51程序
    1#include<reg51.h>2#include<intrins.h>3#include<lcd1602.h>4#defineucharunsignedchar5#defineuintunsignedint6#defineulongunsignedlong78#defineEEPROM_ADDR0xA09sbitSDA=P2^0;10......
  • 蓝桥杯嵌入式之AT24C02各种数据的读写
    一、1字节8为的读写u8a=10;u8temp;eeprom_write(0x00,a); temp=eeprom_read(0x00); sprintf(text,"  temp=%d ",temp);      LCD_DisplayStringLine(Line1,(u8*)text);      memset(text,'\0',strlen(text));二、对于uint16_t、int16_t......
  • 蓝桥杯单片机AT24C02
    一个简单的示例程序,统计开机次数。代码如下:#include<STC15F2K60S2.H>#include<intrins.h>#include"onewire.h"#include"iic.h"u8flag_display=0;u8flag_ds18b20=0;u8flag_at=0;u8at=0;u8temp=0;u8a[8]={10,10,10,10,10,10,10,10};voidctr......
  • 【实战技能】简单易实现的SWD接口烧录目标板挂载的EEPROM,支持AT24C02/04/08/16/32/64/
    之前针对外部SPIFlash的SWD接口烧写,制作过一期专题视频教程。产品生产时,不仅SPIFlash,有时候希望烧录目标板程序后,将EERPOM里面的参数也通过SWD接口存储进去,这样就不再需要大家单独再接上EEPROM的I2C接口烧录了,产品生产比较省事。针对这个问题就花了些时间,制作了下EEPROM的烧写......
  • 16_AT24C02(I2C总线)
    AT24C02(I2C总线)存储器介绍存储器简化模型AT24C02介绍引脚及应用电路内部结构框图I2C总线介绍I2C电路规范弱上拉模式开漏输出模式I2C时序结构I2C数据帧AT24C02数据帧AT24C02数据存储I2C.c#include<REGX52.H>sbitI2C_SCL=P2^1;sbitI2C_SDA......
  • AMEYA360代理 | 佰维eMMC、LPDDR存储芯片赋能电视终端流畅体验
    5G、AI、VR、AR等技术的发展,助推智能电视、机顶盒等电视终端成为智能家居领域不可忽视的重要设备。随着4K超高清(UHD)技术、虚拟现实技术(VR)和增强现实技术(AR)的普及,并向8K超高清技术,电视终端将可以为消费者提供更清晰的视觉体验和更身临其境的观赏、游戏体验。同时,电视终端将不......
  • 26 IIC(四)AT24C02 EEPROM
    1.AT24C02简介设备使用AT24C02芯片(EEPROM)1.1原理图1.2引脚描述1.3寻址AT24C02使用7bit表示设备地址,其中高四位固定为1010。结果原理图可知EEPROM的地址为0x501.4读写操作需要注意一点EEPROM在接受到一帧写数据后会进入一段时间(twr)的内部写周期。此时间段内不响应......
  • stm32笔记[5]-FreeRTOS及(软IIC)读写AT24C02
    STM32CubeIDE使用FreeRTOS教程资料FreeRTOS从入门到精通1--实时操作系统的前世今生FreeRTOS从入门到精通2--人生若只如初见,初识STM32CubeIDEFreeRTOS从入门到精通3--......
  • LQB10,AT24C02的使用
    1、单片机用P20和P21和AT24C02通信;2、比赛提供的开发包里面的代码。头文件c文件提供的代码解读以及修改合适自己使用。#ifndef_IIC_H#define_IIC_HvoidIIC_Start(vo......