esp32 idf eeprom驱动代码编写
最近买了一个esp32s3的开发板,想在春节期间学习一下freeRTOS,春节期间各种吃喝玩乐也没怎么学。
看到了eeprom的章节,觉得开发板提供的代码也不太好用。又去翻看了一下乐鑫官网代码,依然不符合我的心里预期。所以参考我之前写的linux用户态eeprom接口代码,重写了一个esp idf的eeprom驱动代码。2025过年期间deepseek也是出尽风头,其实我在vscode上使用“通义灵码”插件也有一段时间了,源于一个阿里的客服打电话给我推荐使用,这段时间亲眼见证了它的进化,简直强大的让我感到害怕。
这个驱动代码也是在AI的帮助下调出来的,所以强力安利一下使用AI助手写代码,虽然它不能完全取代程序员,但是确实是一个高级助手。
风格是按照linux编程的风格来写的,有问题还请各位看官多多指导,初次尝试freeRTOS。
按照我之前写的代码,把所有的eeprom型号都支持上,如果有不同厂家只需要调整一下芯片的那几个参数获取函数就可以适配了。
at24cxx.h
其实这个设备结构体应该隐藏在c文件中的,反正都公开源码了,也懒得再去修改。
#ifndef __24CXX_H
#define __24CXX_H
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "esp_log.h"
#include "driver/i2c.h"
#define AT24CXX_FREQ_HZ 100000
#define I2C_MASTER_TIMEOUT_MS 1000
/// @brief
typedef enum
{
AT24C01 = 1,
AT24C02 ,
AT24C04 ,
AT24C08 ,
AT24C16 ,
AT24C32 ,
AT24C64 ,
AT24C128,
AT24C256,
AT24C512,
AT24CM01,
AT24CM02,
MODEL_COUNT
} E2_Models;
struct at24c_dev_t{
//i2c_端口信息
i2c_port_t i2c_port; //控制器
int sda_io_num; //数据线
int clk_io_num; //时钟线
/*EEPROM特征属性*/
E2_Models model_type; //芯片类型
unsigned char chip_addr; //芯片从机地址
unsigned int word_mask; //芯片位宽掩码,用于多个DIE叠加的E2
int chip_size; //E2的最大存储空间
int page_size; //E2的页大小
int self_time; //E2的页自写入时间us
SemaphoreHandle_t mutex; // 添加互斥锁
};
/* 函数声明 */
struct at24c_dev_t* at24cxx_init(i2c_port_t i2c_obj, int clk, int sda, unsigned char chip, E2_Models model); /* 初始化AT24Cxx */
int at24cxx_exit(struct at24c_dev_t *dev);
int at24cxx_write(struct at24c_dev_t *dev, int offset, uint8_t *data, int len);
int at24cxx_read(struct at24c_dev_t *dev, int offset, uint8_t *buff, int len);
#endif
#include "24cxx.h"
static int chip_size_get(E2_Models model); //E2芯片容量
static int page_size_get(E2_Models model); //E2页写大小
static int self_time_get(E2_Models model); //E2页写时间
static int word_mask_get(E2_Models model); //E2位宽掩码
static int chip_size_get(E2_Models model)
{
switch(model)
{
case AT24C01:
return 128u;
case AT24C02:
return 256u;
case AT24C04:
return 512u;
case AT24C08:
return 1024u;
case AT24C16:
return 2048u;
case AT24C32:
return 4096u;
case AT24C64:
return 8192u;
case AT24C128:
return 16384u;
case AT24C256:
return 32768u;
case AT24C512:
return 65536u;
case AT24CM01:
return 131072u;
case AT24CM02:
return 262144u;
default:
return 0;
}
}
static int page_size_get(E2_Models model)
{
switch(model)
{
case AT24C01:
return 4;
case AT24C02:
return 8;
case AT24C04:
case AT24C08:
case AT24C16:
return 16;
case AT24C32:
case AT24C64:
return 32;
case AT24C128:
case AT24C256:
return 64;
case AT24C512:
return 128;
case AT24CM01:
case AT24CM02:
return 256;
default:
return 0;
}
}
//这个参数需要查看数据手册,否则会发生意想不到的错误
static int self_time_get(E2_Models model)
{
switch(model)
{
case AT24C01:
return 10;
case AT24C02:
case AT24C04:
return 10;
case AT24C08:
case AT24C16:
case AT24C32:
case AT24C64:
return 10;
case AT24C128:
return 10;
case AT24C256:
return 5;
case AT24C512:
return 5;
case AT24CM01:
return 5;
case AT24CM02:
return 10;
default:
return 0;
}
}
static int word_mask_get(E2_Models model)
{
switch(model)
{
case AT24C01:
case AT24C02:
case AT24C04:
case AT24C08:
case AT24C16:
return 0xff;
case AT24C32:
case AT24C64:
case AT24C128:
case AT24C256:
case AT24C512:
case AT24CM01:
case AT24CM02:
return 0xffff;
default:
return 0;
}
}
static esp_err_t i2c_read(i2c_port_t port, u