AT24Cxx EEPROM 存储模块

元器件
其他
库存 120

介绍

基于AT24C系列I²C EEPROM芯片的存储模块,常见型号AT24C02(2Kbit)/AT24C04(4Kbit)/AT24C08(8Kbit)/AT24C16(16Kbit)/AT24C32(32Kbit)/AT24C64(64Kbit)/AT24C256(256Kbit),I²C接口,电压1.8-5.5V,支持100万次擦写,数据保持100年,板载I²C上拉电阻和地址选择焊盘

规格参数

参数
接口I²C (TWI)
I²C地址0x50~0x57(由A0/A1/A2引脚决定,AT24C16以下部分地址位用于页选择)
工作电压1.8V ~ 5.5V
擦写次数100万次
数据保持100年
最大时钟400kHz (Fast Mode)
板载特性I²C上拉电阻、地址选择焊盘、写保护跳线
模块尺寸约 18x14mm
芯片系列AT24C02/04/08/16/32/64/256
页写大小8/16/32/64字节(视型号)

代码例程

AT24Cxx EEPROM 存储模块 — 代码例程.md
# AT24Cxx EEPROM 存储模块 — 代码例程

---

## 示例 1:Arduino — 使用 Wire 库读写单字节

```cpp
/*
 * AT24Cxx EEPROM — Arduino Wire库 单字节读写
 * 接线: SCL→A5, SDA→A4 (Uno/Nano), VCC→5V, GND→GND
 * 地址默认 0x50 (A0=A1=A2=GND)
 */
#include <Wire.h>

#define EEPROM_ADDR 0x50   // 7位地址

void eepromWriteByte(uint16_t addr, uint8_t data) {
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((addr >> 8) & 0xFF);   // 高字节地址
  Wire.write(addr & 0xFF);          // 低字节地址
  Wire.write(data);
  Wire.endTransmission();
  delay(10);  // 等待写周期
}

uint8_t eepromReadByte(uint16_t addr) {
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((addr >> 8) & 0xFF);
  Wire.write(addr & 0xFF);
  Wire.endTransmission();

  Wire.requestFrom(EEPROM_ADDR, (uint8_t)1);
  if (Wire.available()) {
    return Wire.read();
  }
  return 0xFF;
}

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("AT24Cxx EEPROM 测试");

  // 写一个字节
  eepromWriteByte(0x00, 0xAB);
  Serial.println("写入: 0xAB → 地址 0x00");

  // 读回
  uint8_t val = eepromReadByte(0x00);
  Serial.print("读出: 0x");
  Serial.println(val, HEX);
}

void loop() { }
```

---

## 示例 2:Arduino — 页写入 + 任意长度读写

```cpp
/*
 * AT24Cxx EEPROM — 页写入 & 批量读写
 * 适用于 AT24C02(8字节页) ~ AT24C256(64字节页)
 */
#include <Wire.h>

#define EEPROM_ADDR  0x50

// 根据芯片型号定义页大小
// AT24C02/04/08/16: 16, AT24C32/64: 32, AT24C256: 64
#define PAGE_SIZE    32   // AT24C64 为例

void eepromPageWrite(uint16_t addr, const uint8_t *data, uint8_t len) {
  if (len > PAGE_SIZE) len = PAGE_SIZE;
  // 确保不跨页边界
  uint8_t spaceInPage = PAGE_SIZE - (addr % PAGE_SIZE);
  if (len > spaceInPage) len = spaceInPage;

  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((addr >> 8) & 0xFF);
  Wire.write(addr & 0xFF);
  for (uint8_t i = 0; i < len; i++) {
    Wire.write(data[i]);
  }
  Wire.endTransmission();
  delay(10);
}

void eepromRead(uint16_t addr, uint8_t *buf, uint8_t len) {
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((addr >> 8) & 0xFF);
  Wire.write(addr & 0xFF);
  Wire.endTransmission();

  Wire.requestFrom(EEPROM_ADDR, len);
  uint8_t i = 0;
  while (Wire.available() && i < len) {
    buf[i++] = Wire.read();
  }
}

void setup() {
  Wire.begin();
  Serial.begin(115200);

  // 写入字符串
  const char *msg = "Hello EEPROM!";
  eepromPageWrite(0x00, (const uint8_t*)msg, strlen(msg));
  Serial.print("写入: ");
  Serial.println(msg);

  // 读回
  char buf[32] = {0};
  eepromRead(0x00, (uint8_t*)buf, strlen(msg));
  Serial.print("读回: ");
  Serial.println(buf);
}

void loop() { }
```

---

## 示例 3:Arduino — 存储/读取配置结构体

```cpp
/*
 * AT24Cxx — 存储配置结构体(含校验和)
 */
#include <Wire.h>
#define EEPROM_ADDR 0x50

struct Config {
  uint8_t  deviceId;
  uint16_t baudRate;
  float    calibFactor;
  uint8_t  checksum;
};

uint8_t calcChecksum(uint8_t *data, uint8_t len) {
  uint8_t sum = 0;
  for (uint8_t i = 0; i < len - 1; i++) sum ^= data[i];
  return sum;
}

void saveConfig(Config &cfg) {
  cfg.checksum = calcChecksum((uint8_t*)&cfg, sizeof(Config));
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write(0x00); Wire.write(0x00);  // 起始地址 0
  Wire.write((uint8_t*)&cfg, sizeof(Config));
  Wire.endTransmission();
  delay(10);
  Serial.println("配置已保存");
}

bool loadConfig(Config &cfg) {
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write(0x00); Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(EEPROM_ADDR, sizeof(Config));
  if (Wire.available() == sizeof(Config)) {
    Wire.readBytes((uint8_t*)&cfg, sizeof(Config));
    uint8_t ck = calcChecksum((uint8_t*)&cfg, sizeof(Config));
    if (ck == cfg.checksum) {
      Serial.println("配置加载成功(校验通过)");
      return true;
    }
  }
  Serial.println("配置无效,使用默认值");
  return false;
}

void setup() {
  Wire.begin();
  Serial.begin(115200);

  Config myConfig = {1, 115200, 1.05f, 0};
  saveConfig(myConfig);

  Config loaded;
  if (loadConfig(loaded)) {
    Serial.print("ID:"); Serial.println(loaded.deviceId);
    Serial.print("Baud:"); Serial.println(loaded.baudRate);
    Serial.print("Calib:"); Serial.println(loaded.calibFactor, 2);
  }
}

void loop() { }
```

---

## 示例 4:STM32 HAL — I²C 驱动 AT24Cxx

```c
/*
 * STM32 HAL — I2C1 读写 AT24Cxx
 * CubeMX: 使能 I2C1,标准模式 100kHz 或 Fast 400kHz
 */
#include "main.h"

#define EEPROM_ADDR   (0x50 << 1)  // HAL 用8位地址

I2C_HandleTypeDef hi2c1;

HAL_StatusTypeDef EEPROM_WriteByte(uint16_t addr, uint8_t data) {
  uint8_t buf[3] = {(addr >> 8) & 0xFF, addr & 0xFF, data};
  HAL_StatusTypeDef ret = HAL_I2C_Master_Transmit(
    &hi2c1, EEPROM_ADDR, buf, 3, 100
  );
  HAL_Delay(10);  // 等待内部写周期
  return ret;
}

HAL_StatusTypeDef EEPROM_ReadByte(uint16_t addr, uint8_t *data) {
  uint8_t addrBuf[2] = {(addr >> 8) & 0xFF, addr & 0xFF};
  // 先发地址
  HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDR, addrBuf, 2, 100);
  // 再读数据
  return HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDR, data, 1, 100);
}

// 页写入(不跨页)
HAL_StatusTypeDef EEPROM_PageWrite(uint16_t addr, uint8_t *data, uint8_t len) {
  uint8_t buf[66];  // 最大64字节数据 + 2字节地址
  buf[0] = (addr >> 8) & 0xFF;
  buf[1] = addr & 0xFF;
  memcpy(buf + 2, data, len);
  HAL_StatusTypeDef ret = HAL_I2C_Master_Transmit(
    &hi2c1, EEPROM_ADDR, buf, len + 2, 200
  );
  HAL_Delay(10);
  return ret;
}
```

---

## 示例 5:MicroPython (ESP32 / Raspberry Pi Pico)

```python
"""
AT24Cxx EEPROM — MicroPython I2C 驱动
ESP32: SCL→GPIO22, SDA→GPIO21
"""
from machine import I2C, Pin
import time

class AT24Cxx:
    def __init__(self, i2c, addr=0x50, page_size=32):
        self.i2c = i2c
        self.addr = addr
        self.page_size = page_size

    def write_byte(self, mem_addr, data):
        buf = bytearray([(mem_addr >> 8) & 0xFF, mem_addr & 0xFF, data])
        self.i2c.writeto(self.addr, buf)
        time.sleep_ms(10)  # 等待写周期

    def read_byte(self, mem_addr):
        buf = bytearray([(mem_addr >> 8) & 0xFF, mem_addr & 0xFF])
        self.i2c.writeto(self.addr, buf)
        return self.i2c.readfrom(self.addr, 1)[0]

    def write_page(self, mem_addr, data):
        """写入不超过一页的数据"""
        space = self.page_size - (mem_addr % self.page_size)
        chunk = data[:min(len(data), space)]
        buf = bytearray(2 + len(chunk))
        buf[0] = (mem_addr >> 8) & 0xFF
        buf[1] = mem_addr & 0xFF
        buf[2:] = chunk
        self.i2c.writeto(self.addr, buf)
        time.sleep_ms(10)

    def read(self, mem_addr, length):
        buf = bytearray([(mem_addr >> 8) & 0xFF, mem_addr & 0xFF])
        self.i2c.writeto(self.addr, buf)
        return self.i2c.readfrom(self.addr, length)

# 使用示例
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
eeprom = AT24Cxx(i2c, addr=0x50, page_size=32)

# 写入
eeprom.write_byte(0x00, 0xDE)
print(f"写入字节: 0xDE")

# 读取
val = eeprom.read_byte(0x00)
print(f"读回: {hex(val)}")

# 写入字符串
msg = b"MicroPython EEPROM"
eeprom.write_page(0x10, msg)
data = eeprom.read(0x10, len(msg))
print(f"字符串读回: {data.decode()}")
```

参考资料

暂无参考文献