24系列EEPROM/FRAM通用接口

版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/qq_20553613/article/details/82733817

1.写在前面
  “24系列”的EEPROM,一般地我们认为是以i2c为通信接口的一系列串行EEPROM,各大半导体厂商出产的该系列EEPROM都遵循这个规则,而且电路和控制程序上也兼容。如AT24C02、ST24C02等。

  FRAM(铁电存储器)是近几年来比较热门的一项存储技术,并且有相关实际产品的应用。FRAM具有ROM和RAM的特点,擦写寿命长、读写速度快、读写功耗极低。24系列的FRAM在电路和程序员兼容24系列的EEPROM,但由于FRAM写速度远高于EEPROM,因此不再需要传统EEPROM“页写”之间的延时或者总线空闲检查的操作,这也是两者程序的主要差别。当然存在延时也可以,并不影响数据的正确性,只是降低写效率。

  除此之外,还有“25系列”的EEPROM,该系列则是以spi串行控制接口,在读写时序上稍有差别,具体页写算法可以和24系列的一致。相应地,也有25系列的FRAM,这块用得少,具体差别还有待验证。说个题外话,个人觉得spi接口的EEPROM并无太大优势,甚至有点浪费资源。虽然spi传输速度可以高于i2c,但EEPROM的写速度实在太低了,像i2c这样的低速总线仍需“等待”,所以使用spi并无优势,还占用多个IO口。但,spi接口的FRAM就有优势了,FRAM读写速度远高于EEPROM,存储数据量较大时,可以优先考虑spi接口的FRAM。

2.接口抽象
2.1 目的
  统一接口,屏蔽底层差异,方便移植。使用时只需设置好具体EEPROM型号、从地址、页写延时函数、写保护函数等即可驱动起来,让用户将更多时间花在业务功能上。

2.2 使用范围
 1)MCU裸机程序上。
 2)RTOS(实时系统)上。
 3)其他。

2.3 实现功能
 1)根据型号自动识别页大小、片容量大小。
 2)带页写算法,自动翻页,自动识别非整齐页。
 3)兼容EEPROM和FRAM。

2.4 API
2.4.1 设备对象
  在介绍API前,有个关键的结构体“_24cxx_dev_t”,在“_24cxx_dev.h”中,每个EEPROM外设必须对应一个该结构体,一般地我们参考Linux的叫法称为“设备对象”或者“文件句柄”。该结构体需要程序员初始化,指定相关参数或者函数指针实例化。后面的读、写、擦除函数接口的第一个参数必须都是传入该对象地址(指针),如果对象为空或者未初始化,则返回错误。

/*24cxx eeprom devcie struct*/
typedef struct 
{
	struct i2c_dev_device 	*i2c_dev;	/*i2c bus device struct*/
	uint8_t					slave_addr;	/*eeprom i2c addr*/
	_24_model_t				model;		/*eeprom model*/
	void(*wp)(uint8_t ctrl);			/*protect of write function*/
	void(*page_write_delay)(void);		/*there is a delay in continuous writin for EEPROM,FRAM not need*/
}_24cxx_dev_t;

1)参数一“i2c_dev”,为控制EEPROM的i2c总线设备,可参考“i2c抽象/模拟i2c”文章,使用的是模拟i2c ,也可以根据定义使用硬件i2c;
2)参数二“slave_addr”,为EEPROM的器件从地址,7bit地址,不包括读写位;
3)参数三“model”,为具体EEPROM的型号,该类型为自定义的枚举型,枚举了24c01—24c1024的型号的EEPROM/FRAM;
4)参数四“wp”,为写保护函数,如果EEPROM的写保护引脚“WP”通过MCU控制,则需实现该函数;实现“WP”引脚IO翻转即可;
5)参数五“page_write_delay”,为页写延时函数,程序中采用了页写算法,EEPROM如果连续页写,则需要实现该函数, 否则写会出错;FRAM则不需要。

2.4.2 读EEPROM

int16_t _24cxx_read(_24cxx_dev_t *pdev,uint32_t addr, uint8_t *pbuf, uint32_t size);
参数 功能描述
pdev EEPROM/FRAM设备对象
addr 起始地址
pbuf 读取的数据(缓存)
size 读取数据大小(字节)
2.4.3 写EEPROM
_24cxx_write(_24cxx_dev_t *pdev,uint32_t addr,uint8_t *pbuf,uint32_t size);
参数 功能描述
pdev EEPROM/FRAM设备对象
addr 起始地址
pbuf 待写的数据
size 待写数据大小(字节)
2.4.4 擦除EEPROM

  原则上EEPROM并不存在“擦除”操作,“擦除”一般指用于flash写入前的操作。但特殊场合下,需赋予EEPROM默认值,如赋值0或者0xff,此时可以使用擦除操作。为了节约内存,该函数内部使用的是单字节擦除,效率不高,如有需擦除大片空间,建议直接调用写函数进行擦除。

int16_t _24cxx_erase(_24cxx_dev_t *pdev,uint32_t addr,uint8_t data, uint32_t size);
参数 功能描述
pdev EEPROM/FRAM设备对象
addr 起始地址
data 擦除为默认值
size 待擦除空间大小(字节)
2.4.5 状态返回

  调用函数时,都会返回一个状态码,无错误返回0。具体状态码可以查看“_24cxx_dev.h”中的定义。

/*operation state*/
enum _24CXX_ERROR
{
	_24CXX_OK 				= 0,	
	_24CXX_ERR_I2C_WR 		= 1,
	_24CXX_ERR_DEV_NONE 	= 2,
	_24CXX_ERR_PAGE_WRITE	= 3,
	_24CXX_ERR_PAGE_SIZE	= 4,
	_24CXX_ERR_CHIP_SIZE	= 5,
};
3.使用例子

  目前测试并且通过的EEPROM/FRAM型号有AT24C02、AT24C16、FM24C16。其他型号暂未测试过,如广大网友测试发现问题欢迎指出。

3.1 EEPROM系列
  在测试工程下的“drivers”目录下,源码文件是“at24cxx.c”,主要初始化实现一个“_24cxx_dev_t”设备对象。

static void page_write_delay(void) 
{
	uint16_t i;
	
	i = 0xFFFF;
	while(i--);
}

/**
 * @brief  device init
 */
const _24cxx_dev_t at24cxx_dev =
{
	&i2c1_dev,					/*i2c device*/
	0x50,						/*eeprom address*/
	_24C16_E,					/*eeprom model,eg AT24C16*/
	0,							/*no write protect*/
	page_write_delay,			/*delay function,must!*/	
};

1)“i2c1_dev”为i2c总线设备对象,在“i2c抽象/模拟i2c”文章提及,不再赘述;
2)0x50为器件从地址,不包括读写位;
3)器件具体型号;
4)写保护函数,这里无,赋值NULL(0);
5)页写延时函数。

  这一步完成,即可通过上述的API接口读、写EEPROM,具体demo查看工程源码。

3.1.1 写保护函数
  常见的使用方式都是直接将EEPROM的WP引脚拉低,没有保护功能。如果WP引脚通过MCU控制,则需要使用上写保护函数。以为STM32为例,假设PA0控制器件的WP引脚,写保护函数实现如下,IO口时钟、方式、状态等寄存器需在初始化时配置。在初始化设备对象时,赋值到写保护函数指针。

static void wp_fun(uint8_t ctrl)
{
	if(ctrl == 0)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_0);
	}
}

3.2 FRAM系列
  FRAM控制接口兼容传统EEPROM,程序上差异不大,主要是页写函数可以去掉,设置为NULL(0)即可。以FM24CL16为例,实现如下。

/**
 * @brief  device init
 */
const _24cxx_dev_t fm24clxx_dev =
{
	&i2c1_dev,			/*i2c device*/
	0x50,				/*fram address*/
	_24C16_E,			/*eeprom model,eg FM24C16*/
	0,					/*no write protect*/
	0,					/*delay fun,FRAM no need*/
};
4.相关文章

[1] i2c抽象/模拟i2c:
https://blog.csdn.net/qq_20553613/article/details/78878211

[2] EEPROM页写算法:
https://blog.csdn.net/qq_20553613/article/details/78550427

5.源码

[1] https://github.com/Prry/_24Cxx-EEPROM-FRAM-Dev

猜你喜欢

转载自blog.csdn.net/qq_20553613/article/details/82733817