9. AT24C02(I2C)

文章介绍了AT24C02作为E2PROM存储器的工作原理,包括其通过I2C总线进行通信的细节。内容涵盖I2C总线的规范、时序结构和数据帧格式,以及AT24C02的内部结构和应用电路。此外,还提供了I2C通信函数及AT24C02读写操作的示例代码。
摘要由CSDN通过智能技术生成
  1. 存储器介绍

  1. 存储简易模型

  1. AT24C02介绍

•AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息

•存储介质:E2PROM

•通讯接口:I2C总线

•容量:256字节

  1. 引脚及其应用电路

  1. 内部结构图

  1. I2C总线介绍

•I2C总线(Inter IC BUS)是由Philips公司开发的一种通用数据总线

•两根通信线:SCL(SerialClock)、SDA(Serial Data)

•同步、半双工,带数据应答

•通用的I2C总线,可以使各种设备的通信标准统一,对于厂家来说,使用成熟的方案可以缩短芯片设计周期、提高稳定性,对于应用者来说,使用通用的通信协议可以避免学习各种各样的自定义协议,降低了学习和应用的难度

  1. I2C电路规范

•所有I2C设备的SCL连在一起,SDA连在一起

•设备的SCL和SDA均要配置成开漏输出模式

•SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

•开漏输出和上拉电阻的共同作用实现了“线与”的功能,此设计主要是为了解决多机通信互相干扰的问题

  1. I2C时序结构

•起始条件:SCL高电平期间,SDA从高电平切换到低电平

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

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

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

•发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答

•接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

  1. I2C数据帧

1)发送数据帧

2)接收数据帧

3)先发送后接收(复合格式)

字节写&随机读

AT24C02的固定地址为xxxx 可配置000

  1. 时序简图

  1. AT24C02数据存储

1)主程序

#include <REGX52.H>
#include "I2C.h"
#include "AT24C02.h"
#include "LCD1602.h"
#include "Delay.h"
//unsigned char Data;
unsigned char KeyNum;
unsigned int Num;
void main ()

{
    //P2=0X00;
    LCD_Init();
//    LCD_ShowString(1,1,"hello");
//    AT24C02_WriteByte(1,123);
//    Delay(5);
//    Data=AT24C02_ReadByte(1);
    LCD_ShowNum(1,1,Num,5);
 while (1)
 { 
     KeyNum=Key();
     if(KeyNum==1)
     {
         Num++;
         LCD_ShowNum(1,1,Num,5);
     }
     if(KeyNum==2)
     {
         Num--;
         LCD_ShowNum(1,1,Num,5);
     }
     if(KeyNum==3)
     {
        AT24C02_WriteByte(0,Num%256);
        Delay(5);
        AT24C02_WriteByte(1,Num/256);
        Delay(5);
        LCD_ShowNum(1,1,Num,5);
        LCD_ShowString(2,1,"write ok");
        Delay(1000);
        LCD_ShowString(2,1,"        ");
     }
          if(KeyNum==4)
     {
        Num=AT24C02_ReadByte(0);
        Num|=AT24C02_ReadByte(1)<<8;
        LCD_ShowNum(1,1,Num,5);
        LCD_ShowString(2,1,"read ok");
        Delay(1000);
        LCD_ShowString(2,1,"       ");

     }
 }
}

2)I2C

#include <REGX52.H>

sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void I2C_Start(void)
{
    I2C_SDA=1;
    I2C_SCL=1;
    I2C_SDA=0;
    I2C_SCL=0;
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void I2C_Stop(void)
{
    I2C_SDA=0;
    I2C_SCL=1;
    I2C_SDA=1;
}

/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void I2C_SendByte(unsigned char Byte)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        I2C_SDA=Byte&(0x80>>i);
        I2C_SCL=1;
        I2C_SCL=0;
    }
}

/**
  * @brief  I2C接收一个字节
  * @param  无
  * @retval 接收到的一个字节数据
  */
unsigned char I2C_ReceiveByte(void)
{
    unsigned char i,Byte=0x00;
    I2C_SDA=1;
    for(i=0;i<8;i++)
    {
        I2C_SCL=1;
        if(I2C_SDA){Byte|=(0x80>>i);}
        I2C_SCL=0;
    }
    return Byte;
}

/**
  * @brief  I2C发送应答
  * @param  AckBit 应答位,0为应答,1为非应答
  * @retval 无
  */
void I2C_SendAck(unsigned char AckBit)
{
    I2C_SDA=AckBit;
    I2C_SCL=1;
    I2C_SCL=0;
}

/**
  * @brief  I2C接收应答位
  * @param  无
  * @retval 接收到的应答位,0为应答,1为非应答
  */
unsigned char I2C_ReceiveAck(void)
{
    unsigned char AckBit;
    I2C_SDA=1;
    I2C_SCL=1;
    AckBit=I2C_SDA;
    I2C_SCL=0;
    return AckBit;
}

3)AT24C02

#include <REGX52.H>
#include "I2C.h"

#define AT24C02_ADDRESS        0xA0

/**
  * @brief  AT24C02写入一个字节
  * @param  WordAddress 要写入字节的地址
  * @param  Data 要写入的数据
  * @retval 无
  */
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
    I2C_Start();
    I2C_SendByte(AT24C02_ADDRESS);
    I2C_ReceiveAck();
    I2C_SendByte(WordAddress);
    I2C_ReceiveAck();
    I2C_SendByte(Data);
    I2C_ReceiveAck();
    I2C_Stop();
}

/**
  * @brief  AT24C02读取一个字节
  * @param  WordAddress 要读出字节的地址
  * @retval 读出的数据
  */
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
    unsigned char 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);
    I2C_Stop();
    return Data;
}
  1. Proteus仿真

https://download.csdn.net/download/2301_76540867/87471231

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值