您现在的位置是:首页 > 创新技术

我在高职教STM32——I2C通信之读写EEPROM(二)

智慧创新站 2025-03-30【创新技术】75人已围观

简介【学习目标】了解常用存储器的类型及其特征加深对I2C通信时序的理解领悟I2C驱动与应用的分层理念和相互关联二、EEPROM单字节读写操作从本节开始,我们设计了几个EEPROM的读写实验,分别为单字节读写、多字节读写和页写入,实验内容的安排是循序渐进的。大家需要将EEPROM的工作时序和之前的I2C驱...

【学习目标】

了解常用存储器的类型及其特征

加深对I2C通信时序的理解

领悟I2C驱动与应用的分层理念和相互关联

二、EEPROM单字节读写操作

从本节开始,我们设计了几个EEPROM的读写实验,分别为单字节读写、多字节读写和页写入,实验内容的安排是循序渐进的。大家需要将EEPROM的工作时序和之前的I2C驱动程序结合起来,理解和领悟底层驱动和上层应用是如何进行结合的。实验中STM32的I2C外设采用主模式,用作主发送器和主接收器,通过查询事件的方式来确保正常通讯。

2.1写数据流程

图6是AT24C02的单字节写入和多字节连续写入的时序,大家可以结合图中的序号和下面的分析来理解写数据的流程。

图6AT24C02的写数据时序

第一步,首先是I2C的起始信号,接着跟上首字节,也就是我们前边讲的I2C的器件地址,并且在读写方向上选择“写”操作。

第二步,发送数据的存储地址。AT24C02一共256个字节的存储空间,地址从0x00~0xFF,我们想把数据存储在哪个位置,此刻写的就是哪个地址。

第三步,发送要存储的数据第一个字节、第二个字节……

注意,以上无论是写地址还是写数据,每成功写入一个字节EEPROM都会回应一个“应答位(ACK)”,来告诉我们写入成功,如果没有回应答位,说明写入不成功。而在写数据的过程中,每成功写入一个字节,EEPROM存储空间的地址就会自动加1,当加到0xFF后,再写一个字节,地址会溢出又变成了0x00。

2.2读数据流程

图7是AT24C02的单字节读取和多字节连续读取的时序,大家可以结合图中的序号和下面的分析来理解读数据的流程。

图7AT24C02的读数据流程

第一步,首先是I2C的起始信号,接着跟上首字节,也就是我们前边讲的I2C的器件地址,并且在读写方向上选择“写”操作。这个地方可能有同学会诧异,我们明明是读数据为何方向也要选“写”呢?刚才说过了,AT24C02一共有256个地址,我们选择写操作,是为了把所要读的数据的存储地址先写进去,告诉EEPROM我们要读取哪个地址的数据。这就如同我们打电话,先拨总机号码(EEPROM器件地址),而后还要继续拨分机号码(数据地址),而拨分机号码这个动作,主机仍然是发送方,方向依然是“写”。

第二步,发送要读取的数据的地址,注意是地址而非存在EEPROM中的数据,通知EEPROM我要哪个分机的信息。

第三步,重新发送I2C起始信号和器件地址,并且在方向位选择“读”操作。这三步当中,每一个字节实际上都是在“写”,所以每一个字节EEPROM都会回应一个“应答位(ACK)”。

第四步,读取从器件发回的数据,读一个字节,如果还想继续读下一个字节,就发送一个“应答位(ACK)”,如果不想读了,告诉EEPROM,我不想要数据了,别再发数据了,那就发送一个“非应答位(NACK)”。

和写操作规则一样,我们每读一个字节,地址会自动加1,那如果我们想继续往下读,给EEPROM一个ACK低电平,那再继续给SCL完整的时序,EEPROM会继续往外送数据。如果我们不想读了,要告诉EEPROM不要数据了,那我们直接给一个NACK高电平即可。

这个地方大家要从逻辑上理解透彻,不能简单的靠死记硬背了,一定要理解明白。梳理一下几个要点:1)在本例中STM32是主机,AT24C02是从机;2)无论是读还是写,SCL始终都是由主机控制的;3)写的时候应答信号由从机给出,表示从机是否正确接收了数据;4)读的时候应答信号则由主机给出,表示是否继续读下去。

2.3单字节读写实验

1)任务描述

图8单字节读写的实验效果

2)工程文件清单

与之前一样,我们先给出工程文件清单,如图9所示。和是EEPROM的驱动文件,也是我们剖析的重点。当然,肯定不能少了I2C驱动文件,上一章我们已经编好并分析过了。此外,由于需要液晶显示,因此别忘了把之前编好的LCD1602驱动文件也加进本工程。

图9读写EEPROM工程文件清单

3)源码剖析

这个头文件比较简单,定义了一个宏,声明了两个函数,如代码清单1所示。

代码清单1源码

4)24源码剖析

由于I2C读写的基本操作我们已经在上一章准备好了,所以这里对EEPROM的读写代码就变得非常简单了,直接调用所需的驱动函数即可,如代码清单2所示。对于AT24C02_WriteByte()函数来说,往EEPROM的哪个地址写由参数regAddr决定,具体写什么数据由参数byte决定;对于AT24C02_ReadByte()函数来说,从EEPROM的哪个地址读取由参数regAddr决定,读到的数据存到byte指向的地址里。

代码清单2AT24C02_WriteByte()与AT24C02_ReadByte()函数源码

5)源码剖析

对于主程序来说,完成必要的初始化后,就可以对0x02这个地址先读后写了,如代码清单3所示。

代码清单3文件源码

(第二部分完,多字节连续读写和页写入的实验将在第三部分中分析)

很赞哦!(103)