基础知识

IIC总线有两根总线:SCL(时钟线),SDA(数据线)

只有一根数据线,所以通讯方式是半双工 而且它是一个一主多从的模式

在我们这个板上,主机就是stm32芯片 从机24c02这个存储器就是其中一个从机

编写代码

将i2c_hal.c放在src中  i2c_hal.h放在Inc中 打开工程,然后将.c文件放到工程中。

调用一下初始化函数,在i2c_hal.h中找

 I2C 通信的基本流程

无论是读还是写,I2C 通信的基本流程如下:

  1. STM32 发送起始条件(Start Condition)。

  2. STM32 发送从设备地址(24C02 的地址)和读写位(读或写)。

  3. 24C02 应答(ACK)。

  4. STM32 发送要读写的存储地址。

  5. 24C02 应答(ACK)。

  6. 如果是写操作,STM32 发送数据;如果是读操作,24C02 发送数据。

  7. 通信结束时,STM32 发送停止条件(Stop Condition)。

在.c文件下写一下存储器的读写函数

先是读函数

三个参数(缓冲区,地址,读的大小/次数)

???下面第一个图感觉应该是0xa1,因为这是读函数啊,不是读1写0嘛

解答如下: 

  • 第一次I2CStart和发送0xA0是为了告诉24C02接下来要进行写操作,并写入要读取的内存地址(ucAddr)。

  • 第二次I2CStart和发送0xA1是为了告诉24C02接下来要进行读操作,并从之前指定的内存地址开始读取数据。

  • STM32通过I2CReceiveByte()函数逐个字节读取数据,并在每次读取后发送ACK或NACK信号。

  • 如果还有更多数据要读取(ucNum不为0),STM32发送ACK信号,表示继续读取。

  • 如果读取完成(ucNum为0),STM32发送NACK信号,表示读取结束。

 

然后写函数,跟它的形式差不多

while里面要改 因为是写

  • while(ucNum--):循环发送ucNum个字节的数据。

    • I2CSendByte(*pucBuf++);:发送一个字节的数据(从pucBuf指向的缓冲区中读取)。

    • I2CWaitAck();等待24C02的应答信号(ACK),表示从机已成功接收该字节。

  • 这个循环会一直执行,直到所有数据发送完毕。

 写的话,不能速度太快,每写一次需要延迟一下

延时一段时间,确保24C02有足够的时间完成内部写操作(EEPROM写入需要一定时间)。

delay1我写的时候没有delay1函数,只有HAL_Delay这个函数,所以我就用的这个函数

写好之后,把这两个函数在.h文件中申明一下

实际操作

 下面写一个程序来测试一下

定义一个变量 来记录它上电的次数 每次按下reset键,重新上电之后,就把这个值读出来一次+1

它怎么知道cnt记录的是上电次数呢?

  • 你的程序在每次上电时,都会从地址 0 读取一个值(cnt),将其加1,然后再写回地址 0

  • 通过这种逻辑,cnt 的值会随着每次上电而递增,因此它自然就代表了上电次数。

  • EEPROM 的特点是数据在断电后不会丢失。因此,每次上电时,程序都可以从地址 0 读取之前保存的 cnt 值。

  • 如果没有 EEPROM,cnt 的值会在每次断电后丢失,无法实现上电次数的记录

把值在lcd上显示一下

 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐