外观
at24c32 EEPROM 示例
2025-09-22
本文将详细介绍如何通过 I2C 总线实现设备通信,以 AT24C32 EEPROM 为例演示数据写入与读取操作,并验证数据一致性,帮助读者掌握 I2C 总线的标准通信流程及外设控制方法。
AT24C32 EEPROM
AT24C32 EEPROM 是一款电可擦除可编程只读存储器,通过 I2C 总线接口串行传递地址和数据,最大总线速度为 400Kbits/s,每次读写后内嵌字地址寄存器自动递增。该器件具备非易失性存储特性,即使在断电情况下数据也不会丢失,适用于需要长期保存数据的应用场景。
读取 AT24C32 EEPROM 设备的数据
本示例展示如何通过 I2C 总线对 AT24C32 EEPROM 设备进行数据写入与读取操作,并验证数据一致性,确保 EEPROM 正常工作。
硬件连接
开发板的 IIC 与 AT24C32 已完成硬件连接


查手册获取 RTC 设备地址
通过查阅 AT24C32 的数据手册及硬件连接原理图可知,AT24C32 芯片的读地址为 0xA1 ,写地址为 0xA0:

创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化设备树

固化 APP

核心示例代码
单字节读取操作
该函数实现了标准的 I2C EEPROM 读取流程,包括发送要读取的内存地址(高 8 位和低 8 位)、发送读命令以及接收数据。
at24c32.c
static rt_uint8_t at24c32_read_one_byte(
at24c32_device_t dev, rt_uint16_t read_addr)
{
rt_uint8_t buf[2], temp;
buf[0] = (rt_uint8_t)(read_addr >> 8);
buf[1] = (rt_uint8_t)(read_addr);
if (rt_i2c_master_send(dev->i2c, AT24C32_ADDR, 0, buf, 2) == 0)
{
return RT_ERROR;
}
read_regs(dev, 1, &temp);
return temp;
}单字节写入操作
该函数实现了标准的 I2C EEPROM 写入流程,包括发送要写入的内存地址(高 8 位和低 8 位)、发送要写入的数据以及等待写入完成。
at24c32.c
static rt_err_t at24c32_write_one_byte(
at24c32_device_t dev, rt_uint16_t write_addr, rt_uint8_t to_write)
{
rt_uint8_t buf[3];
buf[0] = (rt_uint8_t)(write_addr >> 8);
buf[1] = (rt_uint8_t)(write_addr);
buf[2] = to_write;
if (rt_i2c_master_send(dev->i2c, AT24C32_ADDR, 0, buf, 3) == 3)
{
return RT_EOK;
}
return (-RT_ERROR);
}设备检查函数
该函数读取通过读取最后一个地址的值来检测芯片是否正常工作,如果读取出来的值不是预期值则写入并再次读取验证。
at24c32.c
static rt_err_t at24c32_check(at24c32_device_t dev)
{
rt_uint8_t temp;
if (dev == RT_NULL)
{
LOG_E("at24c32_check: dev is NULL");
return (-RT_ERROR);
}
temp = at24c32_read_one_byte(dev, AT24C32_MAX_MEM_ADDRESS - 1);
if (temp == 0x55)
{
return RT_EOK;
}
else
{
at24c32_write_one_byte(dev, AT24C32_MAX_MEM_ADDRESS - 1, 0x55);
rt_thread_mdelay(EE_TWR);
temp = at24c32_read_one_byte(dev, AT24C32_MAX_MEM_ADDRESS - 1);
if (temp == 0x55)
{
return RT_EOK;
}
}
return (-RT_ERROR);
}批量读取函数
该函数实现了从 AT24C32 EEPROM 指定地址读取指定长度数据到缓冲区。它逐字节调用单字节读取函数 at24c32_read_one_byte 进行数据读取,每次读取时先发送目标地址,再接收一个字节数据,直到连续读完所有数据。
at24c32.c
static rt_err_t at24c32_read(at24c32_device_t dev,
rt_uint32_t read_addr,
rt_uint8_t *buf,
rt_uint16_t to_write)
{
rt_err_t result;
if (dev == RT_NULL)
{
LOG_E("at24c32_read: dev is NULL");
return (-RT_EINVAL);
}
if (((read_addr + to_write) > AT24C32_MAX_MEM_ADDRESS) || (to_write == 0))
{
return (-RT_ERROR);
}
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
while (to_write)
{
*buf++ = at24c32_read_one_byte(dev, read_addr++);
to_write--;
}
}
else
{
LOG_E("The at24c32 could not respond at this time. Please try again");
}
rt_mutex_release(dev->lock);
return RT_EOK;
}批量写入函数
该函数实现了向 AT24C32 EEPROM 指定地址写入指定长度数据。它逐字节调用单字节写入函数 at24c32_write_one_byte,并且每次写入后调用 rt_thread_mdelay(EE_TWR) 等待写周期完成。 其中,EE_TWR 为写周期时间 (5ms),是 EEPROM 芯片写入操作的必要等待时间。
at24c32.c
static rt_err_t at24c32_write(at24c32_device_t dev,
rt_uint32_t write_addr,
const rt_uint8_t *buf,
rt_uint16_t to_write)
{
rt_uint16_t i = 0;
rt_err_t result;
if (dev == RT_NULL)
{
LOG_E("at24c32_write: dev is NULL");
return (-RT_ERROR);
}
if (((write_addr + to_write) > AT24C32_MAX_MEM_ADDRESS) || (to_write == 0))
{
return (-RT_ERROR);
}
result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
while (1)
{
if (at24c32_write_one_byte(dev, write_addr, buf[i]) == RT_EOK)
{
write_addr++;
}
rt_thread_mdelay(EE_TWR);
if (++i == to_write)
{
break;
}
}
}
else
{
LOG_E("The at24c32 could not respond at this time. Please try again");
}
rt_mutex_release(dev->lock);
return RT_EOK;
}运行程序
开发板运行程序后,在终端输入 at24c32_example 命令,结果如下:
msh />at24c32_example
[I/example.at24c32] at24c32 write/read verify success在整个命令执行期间,系统将执行以下操作:
向
AT24C32指定地址写入字符串:"WELCOME TO RTT EEPROM DEMO";稍作延时等待写入完成;
从相同地址读取字符串;
打印读取与写入字符串的比较结果。
