STM32驱动AT24C02存储模块
AT24C02是一款2KB容量的EEPROM存储器,采用I2C接口,支持1.7-5.5V宽电压工作。它具有低功耗(待机1μA)、非易失性存储、页写(每页8字节)等特点。使用时需注意器件地址配置,支持字节写、页写和三种读操作模式(当前地址读、随机读、顺序读)。典型应用包括通过STM32的I2C接口进行数据读写,配合OLED显示操作结果。代码示例展示了如何初始化I2C接口、实现数据写入和读取功能,并通
简介
AT24C02是可擦除EEPROM,采用256*8- bit的组织结构以及两线串行接口。其特点是,低功耗,有页写能力,每页最多8字节。还具有非易失性,即断电后数据依然保留,非常适合各种微控制器在项目中做数据存储用。电压可允许低至1.8V,待机电流和工作电流分别为1μA和1mA。
参数特征
工作电压:1.7-5.5V
存储容量:2KB(256字节)
时钟频率:1 MHz (2.5V,5V), 400 kHz (1.7V)
接口类型:IIC接口
页写:每页最多8字节
原理图

时序图

寻址
起始条件使能芯片读写操作后,EEPROM都要求有8位的器件地址信息。如下图所示:
AT24C02地址信息由"1"、"0"序列组成,前4位如上图所示,对于所有串行EEPROM都是一样的。随后3位A2、A1和A0为器件地址位,必须与硬件输入引脚保持一致。
操作
存储复位
当协议中产生中断、掉电或系统复位后,I2C总线可通过以下步骤复位:
(1)产生9个时钟周期。
(2)当SCL为高时,SDA也为高。
(3)产生一个起始条件。
写操作
1.字节写
写操作要求在接收器件地址和ACK应答后,接收8位的字地址。接收到这个地址后EEPROM应答"0",然后是一个8位数据。在接收8位数据后,EEPROM应答"0", 接着必须由主器件发送停止条件来终止写序列。
此时EEPROM进 入内部写周期twR,数据写入非易失性存储器中,在此期间所有输入都无效。直到写周期完成,EEPROM才会有应答。如下图所式:
2.页写
AT24C02器件按8字节/页执行页写。页写初始化与字节写相同,只是主器件不会在第一个数据后发送停止条件,而是在EEPROM收到每个数据后都应答“0”。最后仍需由主器件发送停止条件,终止写序列。
接收到每个数据后,字地址的低3位内部自动加1,高位地址位不变,维持在当前页内。当内部产生的字地址达到该页边界地址时,随后的数据将写入该页的页首。如果超过8个数据传送给了EEPROM,字地址将回转到该页的首字节,先前的字节将会被覆盖。
3.应答查询
一旦内部写周期启动,EEPROM输入无效,此时即可启动应答查询:发送起始条件和器件地址(读/写位为期望的操作)。只有内部写周期完成,EEPROM才应答"0"。之后可继续读/写操作。应答流程如下图所示:
读操作
读操作与写操作初始化相同,只是器件地址中的读/写选择位应为"1"。有三种不同的读操作方式:当前地址读,随机读和顺序读。
1.当前地址读
内部地址计数器保存着上次访问时最后一个地址加1的值。只要芯片有电,该地址就一直保存。
当读到最后页的最后字节,地址会回转到0;当写到某页尾的最后一个字节,地址会回转到该页的首字节。
接收器件地址(读/写选择位为"1")、EEPROM应答ACK后,当前地址的数据就随时钟送出。主器件无需应答"0",但需发送停止条件。如下图所示:

2.随机读
随机读需先写一个目标字地址,一旦EEPROM接收器件地址和字地址并应答了ACK,主
器件就产生一个重复的起始条件。随后,主器件发送器件地址( 读/写选择位为"1"),EEPROM应 答ACK,并随时钟送出数据。主器件无需应答"0",但需发送停止条件。如下图所示:

3.顺序读
顺序读可以通过“当前地址读”或“随机读”启动。主器件接收到一个数据后,应答ACK。只要
EEPROM接收到ACK,将自动增加字地址并继续随时钟发送后面的数据。若达到存储器地址末尾,地址自动回转到0,仍可继续顺序读取数据。主器件不应答"0",而发送停止条件,即可结束顺序读操作。如下图:

接线
| STM32 | AT24C02 | OLED |
|---|---|---|
| 3.3V | VCC | VCC |
| GND | GND | GND |
| PB6 | - | SCL |
| PB7 | - | SDA |
| PB10 | SCL | - |
| PB11 | SDA | - |
代码
main.c
#include "oled.h"
#include "delay.h"
#include "AT24C0X.h"
#include "bsp_usart.h"
uint8_t DIS_Dat[10]={0};
void DigDisplay()
{
u8 j=0;
OLED_ShowString(32, 0,"AT24C02",16);
OLED_ShowString(0, 2,"Write:",16);
for(j=0;j<8;j++)
{
DIS_Dat[j]= Write_Dat[j];
}
DIS_Dat[8]= '\0';
OLED_ShowString(48, 2,DIS_Dat,16);
Usart_SendString(DEBUG_USARTx,"Write:");
Usart_SendString( DEBUG_USARTx,DIS_Dat);
OLED_ShowString(0, 4,"Read:",16);
for(j=0;j<8;j++)
{
DIS_Dat[j]= Read_Dat[j];
}
DIS_Dat[8]= '\0';
OLED_ShowString(48, 4,DIS_Dat,16);
Usart_SendString( DEBUG_USARTx,"Read:");
Usart_SendString( DEBUG_USARTx,DIS_Dat);
}
int main(void)
{
DelayInit();
OLED_Init();
OLED_Clear();
USART_Config();
i2c_CfgGpio();
while(1)
{
Write_data();
Read_data();
DigDisplay();
DelayMs(500);
}
}
AT24C02.c
uint8_t Write_Dat[10]={"YouXin25"};
uint8_t Read_Dat[10]={0};
/*
*********************************************************************************************************
* 函 数 名: ee_ReadBytes
* 功能说明: 从串行EEPROM指定地址处开始读取若干数据
* 形 参:_usAddress : 起始地址
* _usSize : 数据长度,单位为字节
* _pReadBuf : 存放读到的数据的缓冲区指针
* 返 回 值: 0 表示失败,1表示成功
*********************************************************************************************************
*/
uint8_t ee_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
{
uint16_t i;
/* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */
/* 第1步:发起I2C总线启动信号 */
i2c_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_WR); /* 此处是写指令 */
/* 第3步:等待ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
i2c_SendByte((uint8_t)_usAddress);
/* 第5步:等待ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第6步:重新启动I2C总线。前面的代码的目的向EEPROM传送地址,下面开始读取数据 */
i2c_Start();
/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_RD); /* 此处是读指令 */
/* 第8步:发送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第9步:循环读取数据 */
for (i = 0; i < _usSize; i++)
{
_pReadBuf[i] = i2c_ReadByte(); /* 读1个字节 */
/* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */
if (i != _usSize - 1)
{
i2c_Ack(); /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */
}
else
{
i2c_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
}
}
/* 发送I2C总线停止信号 */
i2c_Stop();
return 1; /* 执行成功 */
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
i2c_Stop();
return 0;
}
/*
*********************************************************************************************************
* 函 数 名: ee_WriteBytes
* 功能说明: 向串行EEPROM指定地址写入若干数据,采用页写操作提高写入效率
* 形 参:_usAddress : 起始地址
* _usSize : 数据长度,单位为字节
* _pWriteBuf : 存放读到的数据的缓冲区指针
* 返 回 值: 0 表示失败,1表示成功
*********************************************************************************************************
*/
uint8_t ee_WriteBytes(uint8_t *_pWriteBuf, uint16_t _usAddress, uint16_t _usSize)
{
uint16_t i,m;
uint16_t usAddr;
usAddr = _usAddress;
for (i = 0; i < _usSize; i++)
{
/* 当发送第1个字节或是页面首地址时,需要重新发起启动信号和地址 */
if ((i == 0) || (usAddr & (EEPROM_PAGE_SIZE - 1)) == 0)
{
/* 第0步:发停止信号,启动内部写操作 */
i2c_Stop();
for (m = 0; m < 1000; m++)
{
/* 第1步:发起I2C总线启动信号 */
i2c_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_WR); /* 此处是写指令 */
/* 第3步:发送一个时钟,判断器件是否正确应答 */
if (i2c_WaitAck() == 0)
{
break;
}
}
if (m == 1000)
{
goto cmd_fail; /* EEPROM器件写超时 */
}
i2c_SendByte((uint8_t)usAddr);
/* 第5步:等待ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
}
/* 第6步:开始写入数据 */
i2c_SendByte(_pWriteBuf[i]);
/* 第7步:发送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
usAddr++; /* 地址增1 */
}
/* 命令执行成功,发送I2C总线停止信号 */
i2c_Stop();
return 1;
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
i2c_Stop();
return 0;
}
/*******************************************************************************
写8字节数据进AT24C02
*******************************************************************************/
void Write_data(void)
{
ee_WriteBytes(Write_Dat,0,8);
DelayMs(3);
}
/*******************************************************************************
从AT24C02读8字节数据
*******************************************************************************/
void Read_data(void)
{
ee_ReadBytes( Read_Dat,0,8);
}
结果
串口打印数据:
OLED显示数据:

总结
以上是基于STM32驱动AT24C02进行数据的写入和读取操作。AT24C02模块是一款功能强大且易于使用的EEPROM存储芯片,主要适用于一些需要小容量非易失性存储的电子项目。通过IIC接口,它能够方便地与多种微控制器进行通信。
感兴趣的可以关注收藏一下。需要资料代码的可以评论留言。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)