4.6 51单片机-EEPROM存储芯片(AT24C02)

简介: 4.6 51单片机-EEPROM存储芯片(AT24C02)

4.6 EEPROM存储芯片(AT24C02)

4.6.1 原理图介绍

IIC_SCL=0; //总线开始工作、开始读写数据image.png

image.png

实验板上的EEPROM型号是AT24C02N,通信接口是IIC,接在单片机的P2.1(SCL)和P2.2(SDA) 口上。


AT24C02是一颗2kbit(256字节)的EEPROM。


实验板的原理图上描述是24C16,实际实验板上使用的具体芯片型号是AT24C02。


4.6.2 AT24C02介绍


AT24C02是一个2K位串行EEPROM,内部含有256个字节空间。AT24C02内部有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。


I2C总线是由 PHILIPS(飞利浦) 公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点(这个速率高指的是和它同时代的通信总线)。


特性:


(1)、传送速率为400KHz和IIC总线兼容


(2)、2.7V至7V的工作电压


(3)、8字节页写缓冲区


(4)、100万次擦写周期


(5)、数据保存可达100年

image.png

管脚上的A0、A1、A2是地址配置引脚,以组成000~111八种情况,通过器件地址输入端A0、A1和A2可以实现将最多8个AT24C02器件连接到总线上。 SDA是IIC总线的数据线,SCL是IIC总线的时钟线。


AT24C02内部的设备地址是:1010  ,下面图片里2K就是AT2C02的对应地址。

image.png

AT24C02的一个写周期时间为10ms,单片机向AT24C02传输数据时,AT24C02是将数据暂存在8字节的缓冲区里的,单片机发送完数据之后需要等待10ms的时间,等待AT24C02将缓冲区的数据存到内部EEPROM里,存放到EEPROM之后,掉电才不会丢失。

image.png

4.6.3 AT24C02时序介绍

(1) 总线时序图

image.png

(2) 起始信号与停止信号时序图

image.png

当时钟线为高电平的时候,数据线由高电平变为低电平的过程。

1.IIC_SCL=1;
IIC_SDA=1;
IIC_SDA=0;
IIC_SCL=0; //总线开始工作、开始读写数据

当时钟线为高电平的时候,数据线由低电平变为高电平的过程。

IIC_SCL=0;
IIC_SDA=0;
IIC_SCL=1;
IIC_SDA=1;

(3) 应答信号时序图

image.png

有效应答信号是低电平。

(4) 数据位的传输时序图

image.png

输出传输从高位开始。

1./*函数功能: 发送一个字节数据*/
void IIC_SendOneByte(u8 dat)
{
    u8 j=0,i=0;
    for(j=0;j<8;j++)
    {
        IIC_SCL=0;
        if(dat&0x80)IIC_SDA=1;
        else IIC_SDA=0;
        IIC_SCL=1;
        dat<<=1;
    }
IIC_SCL=0;
}

(5) AT24C02写一个字节的总时序

image.png

(6) AT24C02写一页数据的总时序


image.png

(7) 从AT24C02当前地址读取一个字节的总时序


image.png

(8). 从AT24C02指定位置读取指定长度数据的总时序

image.png

4.6.4 AT24C02读写数据示例代码


下面代码演示了AT24C02写入数据和读取数据的过程,在主函数里,调用AT24C02写字节函数向指定空间存入数据,再调用读函数读出来,打印到串口终端。


(硬件平台说明:CPU是STC90C516RD 、晶振频率12MHZ 、工作在12T模式下、一个机器周期为1us时间)


示例代码:

#include <reg51.h>
/*
说明: 在12MHZ晶振下,12T模式下,i++消耗的时间差不多是12us
*/
/*
硬件连接: 
    SCL---P2.1
    SDA---P2.0
*/
//数据线
sbit IIC_SDA=P2^0;
//时钟线
sbit IIC_SCL=P2^1;
/*
函数功能: 发送起始信号
当时钟线为高电平的时候,数据线由高电平变为低电平的过程
*/
void IIC_SendStart(void)
{
    u8 i=0;
    IIC_SCL=1;
    IIC_SDA=1;
    IIC_SDA=0;
    IIC_SCL=0; //总线开始工作、开始读写数据
}
/*
函数功能: 停止信号
当时钟线为高电平的时候,数据线由低电平变为高电平的过程
*/
void IIC_SendStop(void)
{
    u8 i=0;
    IIC_SCL=0;
    IIC_SDA=0;
    IIC_SCL=1;
    IIC_SDA=1;
}
/*
函数功能: 获取应答信号
返 回 值: 0表示获取到应答 1表示没有获取到应答
*/
u8 IIC_GetAck(void)
{
    u8 i=0;
    IIC_SDA=1; //上拉
    IIC_SCL=0;
    IIC_SCL=1;
    while(IIC_SDA)
    {
        i++;
        if(i>250)return 1; //获取不到应答
    }
    IIC_SCL=0;
    return 0;
}
/*
函数功能: 发送应答信号
函数参数:0表示应答 1表示非应答
*/
void IIC_SendAck(u8 ack)
{
    u8 i=0;
    IIC_SCL=0;
    if(ack)IIC_SDA=1; //发送非应答
    else IIC_SDA=0; //发送应答
    IIC_SCL=1;
    IIC_SCL=0;
}
/*
函数功能: 发送一个字节数据
*/
void IIC_SendOneByte(u8 dat)
{
    u8 j=0,i=0;
    for(j=0;j<8;j++)
    {
        IIC_SCL=0;
        if(dat&0x80)IIC_SDA=1;
        else IIC_SDA=0;
        IIC_SCL=1;
        dat<<=1;
    }
    IIC_SCL=0;
}
/*
函数功能: 接收一个字节数据
*/
u8 IIC_RecvOneByte(void)
{
    u8 i=0,j=0;
    u8 dat=0;
    for(j=0;j<8;j++)
    {
        IIC_SCL=0;
        IIC_SCL=1;
        dat<<=1; //表示默认收到0
        if(IIC_SDA)dat|=0x01;
    }
    IIC_SCL=0;
    return dat;
}
/*
函数功能: 写一个字节
函数参数:
    u8 addr 数据的位置(0~255)
    u8 dat 数据范围(0~255)
*/
void AT24C02_WriteOneByte(u16 addr,u8 dat)
{
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    IIC_SendOneByte(addr); //数据存放的地址
    IIC_GetAck();//获取应答
    IIC_SendOneByte(dat); //发送将要存放的数据
    IIC_GetAck();//获取应答
    IIC_SendStop(); //停止信号
    DelayMs(10); //等待写
}
/*
函数功能: 读一个字节
函数参数:
    u8 addr 数据的位置(0~255)
返回值: 读到的数据
*/
u8 AT24C02_ReadOneByte(u16 addr)
{
    u8 dat=0;
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    IIC_SendOneByte(addr); //将要读取数据的地址
    IIC_GetAck();//获取应答
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_READ_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    dat=IIC_RecvOneByte();//读取数据
    IIC_SendAck(1); //发送非应答
    IIC_SendStop(); //停止信号
    return dat;
}
/*
函数功能: 从指定位置读取指定长度的数据
函数参数:
    u16 addr 数据的位置(0~255)
    u16 len 读取的长度
    u8 *buffer 存放读取的数据
返回值: 读到的数据
*/
void AT24C02_ReadByte(u16 addr,u16 len,u8 *buffer)
{
    u16 i=0;
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    IIC_SendOneByte(addr); //将要读取数据的地址
    IIC_GetAck();//获取应答
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_READ_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    for(i=0;i<len;i++)
    {
        buffer[i]=IIC_RecvOneByte();//读取数据
        if(i<len-1)IIC_SendAck(0); //发送应答
        else IIC_SendAck(1); //发送非应答
    }
    IIC_SendStop(); //停止信号
}
/*
函数功能: AT24C02页写函数
函数参数:
    u16 addr 写入的位置(0~1023)
    u8 len 写入的长度(每页16字节)
    u8 *buffer 存放读取的数据
*/
void AT24C02_PageWrite(u16 addr,u16 len,u8 *buffer)
{
    u16 i=0;
    IIC_SendStart();//起始信号
    IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
    IIC_GetAck();//获取应答
    IIC_SendOneByte(addr); //数据存放的地址
    IIC_GetAck();//获取应答
    for(i=0;i<len;i++)
    {
        IIC_SendOneByte(buffer[i]); //发送将要存放的数据
        IIC_GetAck();//获取应答 
    }
    IIC_SendStop(); //停止信号
    DelayMs(10); //等待写
}
/*
函数功能: 从指定位置写入指定长度的数据
函数参数:
    u16 addr 数据的位置(0~255)
    u16 len 写入的长度
    u8 *buffer 存放即将写入的数据
返回值: 读到的数据
*/
void AT24C02_WriteByte(u16 addr,u16 len,u8 *buffer)
{
    u8 page_byte=8-addr%8; //得到当前页剩余的字节数量
    if(page_byte>len) //判断当前页剩余的字节空间是否够写
    {
        page_byte=len; //表示一次性可以写完
    }
    while(1)
    {
        AT24C02_PageWrite(addr,page_byte,buffer); //写一页
        if(page_byte==len)break; //写完了
        buffer+=page_byte; //指针偏移
        addr+=page_byte;//地址偏移
        len-=page_byte;//得到剩余没有写完的长度
        if(len>8)page_byte=8;
        else page_byte=len; //一次可以写完
    }
}
//u8 at24c02_w[8]="1234567";
//u8 at24c02_r[8];
int main()
{
    u8 dat;
    UART_Init();        //初始化串口波特率为4800
    while(1)
    {
//单个字节读写测试
        AT24C02_WriteOneByte(10,34);
        dat=AT24C02_ReadOneByte(10);
        printf("dat=%d\r\n",(int)dat);
        //多个字节读写测试
        //AT24C02_WriteByte(0,8,at24c02_w);
//        AT24C02_ReadByte(0,8,at24c02_r);
//        printf("at24c02_r=%s\r\n",at24c02_r);
          DelayMs(1000);
}
}

image.png

image.png

image.png

目录
相关文章
【STC15单片机】模拟I2C操作AT24C02数据读取,PCF8591的A/D转换代码
【STC15单片机】模拟I2C操作AT24C02数据读取,PCF8591的A/D转换代码
337 0
|
存储 C语言 芯片
51单片机&15单片机 时钟芯片DS1302
51单片机&15单片机 时钟芯片DS1302
260 0
|
存储 芯片
51单片机使用AT24C02
51单片机使用AT24C02
184 0
蓝桥杯之单片机学习(十九)——IIC协议(PCF8591、AT24C02)
蓝桥杯之单片机学习(十九)——IIC协议(PCF8591、AT24C02)
250 0
蓝桥杯之单片机学习(十九)——IIC协议(PCF8591、AT24C02)
|
传感器 编解码 芯片
51单片机驱动步进电机——使用ULN2003芯片
51单片机驱动步进电机——使用ULN2003芯片
408 0
51单片机驱动步进电机——使用ULN2003芯片
|
存储 数据采集 芯片
基于单片机的数字存储示波器设计
基于单片机的数字存储示波器设计
180 0
基于单片机的数字存储示波器设计
|
芯片
复习单片机:直流电机(内含1 直流电机介绍+2 ULN2003 芯片介绍+3 硬件设计+4 软件设计+5原始代码+6. 实验现象)
复习单片机:直流电机(内含1 直流电机介绍+2 ULN2003 芯片介绍+3 硬件设计+4 软件设计+5原始代码+6. 实验现象)
218 0
复习单片机:直流电机(内含1 直流电机介绍+2 ULN2003 芯片介绍+3 硬件设计+4 软件设计+5原始代码+6. 实验现象)
|
存储 缓存 芯片
复习单片机:IO串转并(内含:1. 74HC595 芯片介绍+2. 硬件设计+3. 软件设计+4.原始代码+5. 实验现象)
复习单片机:IO串转并(内含:1. 74HC595 芯片介绍+2. 硬件设计+3. 软件设计+4.原始代码+5. 实验现象)
426 0
复习单片机:IO串转并(内含:1. 74HC595 芯片介绍+2. 硬件设计+3. 软件设计+4.原始代码+5. 实验现象)
|
芯片
复习单片机:动态数码管(1 数码管介绍+2 74HC245 和 74HC138 芯片介绍+3 硬件设计+4 软件设计+5 实验现象)
复习单片机:动态数码管(1 数码管介绍+2 74HC245 和 74HC138 芯片介绍+3 硬件设计+4 软件设计+5 实验现象)
1179 0
复习单片机:动态数码管(1 数码管介绍+2 74HC245 和 74HC138 芯片介绍+3 硬件设计+4 软件设计+5 实验现象)