STM32 IIC读写AT24C02(二)

接口/总线/驱动

1135人已加入

描述

上次已经完成了IIC读写AT24C02的协议层,现在开始编写读写AT24C02的驱动函数。先从单字节的读写开始。

发送器

字节写要求在接收器件地址和ACK应答后,接收位的字地址。接收到这个地址后AT24C02应答“0”,然后是一个8位数据。在接收8位数据后,AT24C02应答“0”,接着必须由主器件发送停止条件来终止写序列。

此时AT24C02进入内部写周期tWR,数据写入非易失性存储器中,在此期间所有输入都无效。直到写周期完成,AT24C02才会有应答。

void AT24C02_ByteWrite(u8 wordAdd,u8 dat,s8 *err)
{
  u8 ack = 0;

  IIC_Start();
  IIC_SendByte(AT24C02_ADD< < 1);
  ack = IIC_CheckAck();
  if(ack != 0)                //发器件地址
  {                           
    IIC_Stop();               //不应答
    err = -1;
    return;
  }

  IIC_SendByte(wordAdd);      //发字地址
  ack = IIC_CheckAck();
  if(ack != 0)                 //不应答
  {
    IIC_Stop();
    *err = -2;
    return;
  }

  IIC_SendByte(dat);          //发数据
  ack = IIC_CheckAck();
  if(ack != 0)                //不应答
  {
    IIC_Stop();
    *err = -3;
    return;
  }

  IIC_Stop();
  *err = 0;  
}

其中传入了一个错误检测err,是在测试程序时为了快速发现错误位置而设置的。如果出现错误,就发送停止信号并用return退出该次写操作,由于该函数为void类型,所以直接return就可以了,不用带返回值。

和字节写相对应的是随机读,读取任意一个地址的数据。

发送器

随机读需先写一个目标字地址,一旦AT24C02接收器件地址和字地址并应答了ACK,主器件就产生一个重复的起始条件。

然后,主器件发送器件地址,AT24C02应答ACK,并随时钟送出数据。主器件无需应答“0”,但需发送停止条件。

u8 AT24C02_RandomRead(u8 wordAdd,s8 *err)
{
  u8 ack = 0;
  u8 temp = 0;

  IIC_Start();
  IIC_SendByte(AT24C02_ADD< < 1);//发器件地址
  ack = IIC_CheckAck();
  if(ack != 0)                 //不应答
  {
    IIC_Stop();
    *err = -4;
    goto loop;    
  }

  IIC_SendByte(wordAdd);      //发字地址
  ack = IIC_CheckAck();
  if(ack != 0)                 //不应答
  {
    IIC_Stop();
    *err = -5;
    goto loop;
  }

  IIC_Start();
  IIC_SendByte(AT24C02_ADD< < 1 | 1);//发器件地址(读)
  ack = IIC_CheckAck();
  if(ack != 0)                 //不应答
  {
    IIC_Stop();
    *err = -6;
    goto loop;
  }
  temp = IIC_ReadByte();
  IIC_NoAcktoSlave();
  IIC_Stop();

  *err = 0;

loop:
  return temp;
}

跟写字节一样,这里也引入了err判断错误,出现错误发送停止信号并退出该次读操作。因为该函数需要返回值,所以这里不能像上面那样直接return,但是出现错误,也不能让return带着一个未知的数返回。这里退出该次读操作用到了C语言中很忌讳的goto,直接让程序跳到想要的位置。这种方式来做处理在嵌入式中是比较常见的,虽然C语言中goto是不被推荐使用的,但是只要能把它用的好,就可以大胆的用。

字节读写函数封装完成后,直接在主函数中调用。AT24C02擦写次数只有100万次左右,所以写函数不可以放入while循环中,否则器件可能很快就坏了。

主文件

#include "stm32f4xx.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"
#include "AT24C02.h"


int main()
{
  s8 err = 0;
  u8 temp = 0;
  Usart1_Init(115200);
  LED_Init();              //初始化LED灯
  AT24C02_Init();

  AT24C02_ByteWrite(0x05,125,&err);
  temp = AT24C02_RandomRead(0x05,&err);
  printf("temp = %drn",temp);
  
  while(1)              
  {
  }
}

发送器

将程序烧入开发板中,打开串口助手,可以看到读到的数正好是写入的数,AT24C02单字节读写成功。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分