在 STM32F103 上通过 I2C 驱动 24C02 EEPROM 存储器,需要了解 I2C 协议核心机制、24C02 设备特性及软件模拟/硬件 I2C 实现方法,才能很好的实现 I2C 驱动 24C02 的功能。
一、I2C 协议核心机制
信号定义
起始信号(Start):SCL 高电平时,SDA 由高 → 低跳变,表示通信开始。
停止信号(Stop):SCL 高电平时,SDA 由低 → 高跳变,表示通信结束。
应答信号(ACK):接收方在收到 8 位数据后,在第 9 个时钟周期拉低 SDA,表示确认。
数据传输:SCL 高电平时,SDA 数据必须稳定;SCL 低电平时,SDA 可变化。
时序要求
标准模式:100kbps;快速模式:400kbps;高速模式:3.4Mbps(需硬件支持)。
空闲状态:SDA 和 SCL 均为高电平(由上拉电阻维持)。
二、24C02 设备特性
存储结构
容量:256 字节(2Kb),地址范围 0x00~0xFF。
页写缓冲区:16 字节(连续写入超过 16 字节会覆盖起始地址)。
写保护:通过 WP 引脚控制(高电平保护,低电平允许写入)。
设备地址
固定前 4 位:1010(I2C 标准 EEPROM 地址)。
可配置后 3 位:A2~A0(通过硬件引脚接地或接 VCC 设置,默认为 000)。
读写位:最低位(0=写,1=读)。
完整地址示例:
写操作:0xA0(1010 000 0)
读操作:0xA1(1010 000 1)
24C02 芯片深度解析:低功耗 I²C EEPROM 的存储方案
24C02 是一款基于 I²C 总线的 2Kbit(256 字节)串行 EEPROM 存储器,采用 8 引脚封装 PDIP、SOIC、TSSOP 等。
低功耗设计:工作电压范围 1.8V 至 5.5V,典型待机电流仅 1μA,适合电池供电设备。
高可靠性:支持 100 万次擦写周期,数据保存时间超过 100 年,满足工业级长期存储需求。
硬件写保护:通过 WP 引脚实现数据保护,WP 接高电平时禁止写入操作,防止误擦除。
页写缓冲:内置 8 字节页写缓冲区,支持连续写入 8 字节后自动存储,减少内部写入周期(5ms)的等待时间。
引脚功能与硬件连接
24C02 的引脚定义如下:
A0-A2:器件地址引脚,用于多设备级联。默认接地时,写地址为 0xA0,读地址为 0xA1。
SDA/SCL:I²C 数据线和时钟线,需外接 4.7kΩ 上拉电阻以保证信号稳定性。
WP:写保护引脚,接地时允许读写,接高电平时仅允许读操作。
VCC/GND:电源引脚,支持 1.8V 至 5.5V 宽电压范围。

典型连接示例:
SDA/SCL 连接至 MCU 的 I²C 引脚。
WP 引脚接地以启用读写功能,或接高电平实现只读保护。
A0-A2 引脚接地以简化地址配置(默认地址 0xA0/0xA1)。
工作原理与通信流程
24C02 通过 I²C 协议与主控设备通信。
起始信号:SCL 为高电平时,SDA 由高变低,标志通信开始。
地址传输:主设备发送 7 位设备地址(高 4 位固定为 1010,低 3 位由 A0-A2 决定)和读写位(0 为写,1 为读)。
写入操作:
发送存储地址(0x00-0xFF)。
连续写入最多 8 字节数据至缓冲区,自动触发内部写入周期(需等待 5ms)。
读取操作:
随机读:先发送“哑地址”写入存储地址,再切换为读模式接收数据。
顺序读:在随机读基础上,主设备持续发送应答信号以读取后续数据。
停止信号:SCL 为高电平时,SDA 由低变高,标志通信结束。
三、软硬件资料
硬件连接
SCL:PB6
SDA:PB7
24C02 的 A0/A1/A2 引脚接地(地址为 0x00)
框图

总线配置

起始和停止条件
数据和时钟线都为高则称总线处在空闲状态。当 SCL 为高电平时 SDA 的下降沿高到低叫做起始条件,SDA 的上升沿(低到高)则叫做停止条件。

位传输

应答

应用电路

原理图

四、配置


五、代码
int main(void)
{
/* USER CODE BEGIN 1 */
HAL_StatusTypeDef error;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM6_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
OLED_INIT();
HAL_Delay(2000);
//OLED_Clear();
Test_EEPROM();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
OLED_ShowString(20, 0, "RY MCU F103", 16,1);
OLED_ShowString(20, 3, "TIME: ", 16,1);
OLED_ShowNum(75, 6, Time6Second, 2, 16, 1);
OLED_ShowString(90, 6, " S ", 16,1);
/* USER CODE BEGIN 3 */
}
读
void ReadBufferTo24C02(int addr,uint8_t *pdata,char length)
{
HAL_I2C_Mem_Read(&hi2c1, ADDR_RD_AT24CXX, addr, I2C_MEMADD_SIZE_16BIT, pdata, length, 1000);
}
写
void WriteBufferTo24C02(int addr,uint8_t *pdata,char length)
{
HAL_I2C_Mem_Write(&hi2c1, ADDR_WR_AT24CXX, addr, I2C_MEMADD_SIZE_16BIT, pdata, length, 1000);
}
输出地址
```apache
WriteBuffer24C02[0]= 0xFA ;
WriteBuffer24C02[1]= 0xFB ;
WriteBuffer24C02[2]= 0xFC ;
WriteBuffer24C02[3]= 0x05 ;
WriteBuffer24C02[4]= 0xC0 ;
WriteBuffer24C02[5]= 0x01 ;
WriteBuffer24C02[6]= 0x02 ;
WriteBufferTo24C02(0,&WriteBuffer24C02[0],7);
六、显示效果
输出
