初出茅庐的小李第45篇博客之学习使用AT24C02存储器使用

AT24C02

在这里插入图片描述

8个引脚三个用来接VCC或者GND,其实就是地址选择线,A2 A1 A0 留给我们的编程地址就三位了,通信则采用的是I2C的方式

要想实现数据的存储和读取那首先要明白它和主机(作为存储器件来使用挂在到单片机上我们可以称之为从机)如何通信的

I2C总线协议

我就记录我学习的理解吧

I2C总线:
它是一种同步时钟串行总线
用于
单个主设备----------单个主设备
多个主设备----------多个从设备
两条线
SCL–时钟线
SDA–数据线
电气特性:
开漏输出要外接上拉电阻
场效应管导通电平会被拉低,场效应管不导通高阻态通过上拉电阻电平被拉高,只有一条数据线属于半双工通信总线,所有的通信都必须由主机发起。

- i.主设备想要向从设备请求数据

1.发送起始条件并寻址从器件
2.主机发送器将数据发送到从器件
3.主机以停止条件终止传输
ii.主设备想要向从设备接收数据
1.发送起始条件并寻址从器件
2.主接收器发送请求读取的寄存器
3.主机接收从从机发送器接收数据
4.主机发送器以停止条件终止传输

何为起始条件

SCK=1;
SDA=1;SDA=0;

何为终止条件

SCK=1;
SDA=0;SDA=1;

理解:数据线数据必须在SCK=1的时候稳定,也就是说不能再产生下降沿或者上升沿,要不然容易被误判位起始条件或者是终止条件。我们为了避免以上情况发生,每次SDA数据先数据变化的时候都要发生在SCK=0的低电平时刻。

什么是应答和不应答(ACK和NACK)

应答位是由跟在每一个数据字节的后面一位数据由数据接收的一方发送,并不一定是主机。
SCL=1高电平时刻SDA=1高电平就是无应答
SCK=1高电平时刻SDA=0低电平就是有应答
主器件写数据到从器件
单字节写
S A6 A5 A4 A3 A2 A1 A0 0 A B7 B6 B5 B4 B3 B2 B1 B0 A D7 D6 D5 D4 D3 D2 D1 D0 A P
主器件写数据到从器件
单字节读
S A6 A5 A4 A3 A2 A1 A0 0 A B7 B6 B5 B4 B3 B2 B1 B0 A Sr A6 A5 A4 A3 A2 A1 A0 1 A D7 D6 D5 D4 D3 D2 D1 D0 NA P
S代表START
A6~A0表示要访问的寄存器地址(器件的地址)就相当于需要送快递的小区地址
0代表是写寄存器(A6~A0) 表示一种动作我要写到这里
A代表是从机的应答位 让不让送快递回个信
B7~B0是主机要送数据到的地址 有点像是快递柜子的具体的位置
A代表从机的应答 回复一下没问题
D7~D0 送的数据内容 (瓜子果皮饮料。。。。。。。。)
A收到data后回复
P 就是这个动作结束了stop
下面这个有点类似
只不过在读数据之前也要先说一声去哪里读
沟通好后再次发送START 就可以发地址回复发请求数据地址不回复结束

关于I2C这有一个比较好的图

在这里插入图片描述
物理I2C接口由串行时钟(SCL)和串行数据(SDA)线组成。 SDA和SCL线都必须通过上拉电阻连接到VCC。 上拉电阻的大小由I2C总线上的电容量决定

在这里插入图片描述
在这里插入图片描述

经典的接法

在这里插入图片描述
之前看别人写的代码上来就搞一个从机地址
给我整的迷迷糊糊的
其实它是有原因的,给我们A2 A1 A0 的接线方法有关,但是由于我们经常都是用一个芯片地址啥的也都是静态的
所以就有了下面的结果分析的很有道理
在这里插入图片描述
延时大法适度使用有助于程序不出bug…
在这里插入图片描述

I2C方式操作AT24C02的代码该如何写?

/*
函数功能:向AT24c02指定地址写一字节数据
*/
void At24c02_Write_OneByte(u8 addr,u8 data)
{
  IIC_Start();
  IIC_Write_Byte(At24c02_Write_Addr);//发送写地址0XA0
  if(IIC_Check_Ack())return ;
  IIC_Write_Byte(addr);
  if(IIC_Check_Ack())return ;
  IIC_Write_Byte(data);
  if(IIC_Check_Ack())return ;
  IIC_Stop();
  delay_ms(10);//确保写完成
}
/*
函数功能:向AT24c02指定地址开始读数据
*/
void At24c02_Read_Data(u8 addr,u8 *data,u8 len) 
{
 u8 i=0;
  IIC_Start();
  IIC_Write_Byte(At24c02_Write_Addr);//发送写地址0XA0
  if(IIC_Check_Ack())return ;
  IIC_Write_Byte(addr);//写数据的地址
  if(IIC_Check_Ack())return ;
  IIC_Start();
  IIC_Write_Byte(At24c02_Read_Addr);//发送读地址0XA1
  if(IIC_Check_Ack())return ;
  for(i=0;i<len;i++)
  {
   data[i]=IIC_Read_Byte();
   if(i==len-1)IIC_Send_Ack(1);
   else IIC_Send_Ack(0);
  }
  IIC_Stop(); 
}
/*
函数功能:对AT24C02指定地址页内写数据
*/
void At24c02_Write_Page(u8 addr,u8 *data,u8 len)
{
  u8 i=0;
  IIC_Start();
  IIC_Write_Byte(At24c02_Write_Addr);//发送写地址0XA0
  if(IIC_Check_Ack())return ;
  IIC_Write_Byte(addr);//写数据的地址
  if(IIC_Check_Ack())return ;
  for(i=0;i<len;i++)
  {
   IIC_Write_Byte(*data++);/
   if(IIC_Check_Ack())return ;
  }
  IIC_Stop();
  delay_ms(10);
}
/*
函数功能:对AT24C02指定地址跨页写数据
*/
void At24c02_Write_Data(u8 addr,u8 *data,u8 len)
{
  u8 write_len=16-addr%16;//起始页剩下的空间
  if(write_len>len)write_len=len;
  while(1)
  {
   At24c02_Write_Page(addr,data,write_len);
   if(write_len==len)break;
   addr+=write_len;
   data+=write_len;
   len-=write_len;
   if(len>16)write_len=16;
   else write_len=len;
  }
}

其实这个页写和页读没有看明白。。。。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值