STM32 I2C通信操作24C02写数据、读数据

“202007每月一练” 的板子上还有一个24C02芯片没有写教程,今天介绍一下24C02这个芯片的驱动方法。

有的时候我们在程序中会改变一些参数的值,我们希望这些参数可以固化,掉电重启之后仍旧能够使用最新的值,这种需求,我们就可以使用E2PROM来实现。

24CXX属于串行E2PROM, 是基于I2C总线的存储器件,遵循二线制协议,I2C总线上可以外挂多个器件,每个器件对应不同的地址,通过地址将不同器件进行分开,保证不同芯片之间数据传输的独立性。由于其具有接口方便,体积小,数据掉电不丢失等特点,在仪器仪表及工业自动化控制中得到大量的应用。

24C02的应用场景:

  • 存储硬件的默认参数,这样开机上电之后读取这些参数,就可以按照默认参数运行了,比如存储PID自整定之后的参数;
  • 保存计费、计量的一些应用的余额;
  • 类似血压计、血糖仪之类保存一定次数的检测结果,实现历史回溯功能。

24CXX系列E2PROM为I2C总线的掉电存储数据芯片。

I2C总线主要注意以下几点:

  1. 数据有效性要求

在输入数据时,当SCL是高电平时,SDA上的信号必须保持不变;只有SCL上的时钟信号为低电平时,SDA上的信号才能改变。

  1. 数据的开始和结束条件

SDA、SCL默认为高电平,表示总线处于空闲状态。

数据输入的开始条件是SCL为高电平时,SDA由高变低;

结束条件是SCL为高电平时,SDA由低电平变为高电平,即SDA出现一个上升沿的跳变,即为终止信号。

  1. I2C的应答信号ACK

数据传输带有应答信号ACK,在传输数据的过程中,在时钟线SCL的第九个脉冲时,从机芯片内部会产生一个应答信号ACK将SDA管脚拉低。

引脚定义

24C02模块的原理图

  1. 本文对应实例,CON1跳线短接,24C02的地址为0,故24C02的写地址为0xA0,读地址为0xA1。

  2. 24C02,尾数02代表着内部有256*8(2K bits)空间。

  3. 上拉电阻必需有,否则可能无法对24C02进行正确读写。

24C02器件操作流程

单字节写

单字节写流程

在字节写模式下,主器件发送起始命令和从器件地址信息、此时R/W位置0(写地址)发给从器件,在从器件产生应答信号后,主器件发送24C02的地址信息,然后等待从器件返回的另一个应答信号后,再发送数据到24C02,然后再接收一次Ack应答信号后,主芯片产生一个停止信号,从器件收到停止信号后,开始内部数据的擦写,在内部擦写过程中,24C02不再应答主器件的任何请求,从而完成整个单字节的写流程。

注: 当上一个数据写完之后,即发送停止信号之后,需延时至少10ms以上,才能再发送下一次写操作的起始信号。

读操作

1. 单字节读读操作允许主器件对24C02的任意字节进行读操作。主器件首先通过发送起始信号、从器件地址和写操作(写地址)的标志位0。

在从器件应答之后,主器件发送目标地址,并等待返回应答信号。

主器件重新发送起始信号和从器件地址,此时R/W位置1(读操作,读数据),从器件响应应答信号,然后主器件获取一个8位数据字节,主器件不用发送应答信号但需要产生一个停止信号,即完成单字节读过程。

2. 多字节连续读

在从机给主机发送完一个8位字节数据后,主器件产生一个应答信号来响应,告诉从机主器件请求更多的数据,对应每个主机产生的应答信号,从机将发送一个8位数据字节。当主器件不发送应答信号而发送停止位时结束操作。

如果我们使用如下代码,读取大于24C02容量的字节数的话,会有什么现象呢?

const u8 TEXT_Buffer[]={"0123456789ABCDEF"};
#define SIZE sizeof(TEXT_Buffer)

// 写入16个字节数据
AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);

memset(arrDataTemp, 0, sizeof(arrDataTemp));
// 读取280个字节的数据
AT24CXX_Read(0,arrDataTemp,280); 
// 将读取到的数据串口打印输出
USART_OUT(arrDataTemp,280);

上面代码执行,输出结果如下所示:

从上面截图,我们可以看出来,两个红色圈选部分的内容是一样的,即当读取的字节数超过N(对于24C02,N=255),读取的数据指针将返回存储空间的前面,从头往后输出剩余字节。

出现这样的原因主要是我们在读取函数中,发送地址的时候,将读取地址对存储空间大小取余了,所以又从头开始输出剩余字节了。

IIC_Send_Byte(ReadAddr%256);

紫色的55,就是程序初始化的时候,检查24C02芯片是否存在时,AT24CXX_Check()函数中写入的数据:

while(AT24CXX_Check())  //检测24C02是否存在
{
    printf("24C02 Check Failed!\r\n");  
    delay_ms(500); 
    printf("Please Check! \r\n");  
    delay_ms(500); 
}

注:

代码工程使用的Keil版本为:V5.20我用的PCB设计软件版本为:Altium Designer 14.2

如果没有特殊说明,软件环境都为以上两个版本。

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 1
收藏 2
关注 62
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧
XML 地图 | Sitemap 地图

2024欧洲杯竞猜app