STM32 内部 EEPROM 读写

STM32 的某些系列 MCU 自带 EEPROM 。笔者使用的 STM32L151RET6 自带 16 KB 的 EEPROM,可以用来存储自定义的数据。在芯片选型时,自带 EEPROM 也可以作为一个考量点,省去了在外接 EEPROM 的烦恼。

下面简单介绍下 STM32 内部 EEPROM 的读写流程。

Memory Mapping

以笔者使用的这款 STM32L151RET6 MCU 为例,自带 16 KB 的 EEPROM。Map 到了 2 个 Bank 中:

  • Data EEPROM Bank1: 0x08080000 ~ 0x08081FFF (8KB)
  • Data EEPROM Bank2: 0x08082000 ~ 0x08083FFF (8KB)

Operations

内部 EEPROM 的操作无非就是 读取 、写入 、擦除 等操作。直接调用库函数或者 HAL 库中对应的 API 即可。这里只是对内部 EEPROM 的操作做一个简要的分析。

本文档主要以库函数中的 EEPROM 接口 API 进行分析。

Unlocking/locking memory

STM32 复位后,Data EEPROM 和 Program/erase 控制寄存器 (FLASH_PECR ) 默认是 处于 lock 状态 ,需要 unlock 之后才能执行写入和擦除操作。

如何 unlock 可以参考芯片对应的 datasheet,简单的说就是往 Program/erase 密钥寄存器 (FLASH_PEKEYR) 写指定的密钥集即可。

  • Write PEKEY1= 0x89ABCDEF to the Program/erase key register (FLASH_PEKEYR)
  • Write PEKEY2= 0x02030405 to the Program/erase key register (FLASH_PEKEYR)
c 复制代码
/**
  * @brief  Unlocks the data memory and FLASH_PECR register access.
  * @param  None
  * @retval None
  */
void DATA_EEPROM_Unlock(void)
{
  if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET)
  {  
    /* Unlocking the Data memory and FLASH_PECR register access*/
    FLASH->PEKEYR = FLASH_PEKEY1;
    FLASH->PEKEYR = FLASH_PEKEY2;
  }
}
c 复制代码
#define FLASH_PEKEY1               ((uint32_t)0x89ABCDEF) /*!< Flash program erase key1 */
#define FLASH_PEKEY2               ((uint32_t)0x02030405) /*!< Flash program erase key: used with FLASH_PEKEY2
                                                               to unlock the write access to the FLASH_PECR register and
                                                               data EEPROM */

如何 lock 可以参考芯片对应的 datasheet,相较于 unlock,lock 仅需要置位 Program/erase 控制寄存器 (FLASH_PECR ) 中的 FLASH_PECR 位。

c 复制代码
/**
  * @brief  Locks the Data memory and FLASH_PECR register access.
  * @param  None
  * @retval None
  */
void DATA_EEPROM_Lock(void)
{
  /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */
  FLASH->PECR |= FLASH_PECR_PELOCK;
}

Erasing memory

对于 EEPROM,支持以下 2 种擦除方式:

  • Word 和 double word 擦除
  • Mass 擦除

对于 Word 和 double word 擦除,这种方式仅针对 EEPROM;但是对于 Mass 擦除,这种方式针对 Program memory、EEPROM 和 Option bytes。所以尽量在使用 EEPROM 的时候采用 Word 和 double word 擦除方式。

EEPROM 擦除方式也很简单,只需要将值 0x00000000 写入到对应的有效的擦除地址中即可。

c 复制代码
/**
  * @brief  Erase a word in data memory.
  * @param  Address: specifies the address to be erased.
  * @note   For STM32L1XX_MD, A data memory word is erased in the data memory only 
  *         if the address to load is the start address of a word (multiple of a word).
  * @note   To correctly run this function, the DATA_EEPROM_Unlock() function
  *         must be called before.
  *         Call the DATA_EEPROM_Lock() to disable the data EEPROM access
  *         and Flash program erase control register access(recommended to protect 
  *         the DATA_EEPROM against possible unwanted operation).
  * @retval FLASH Status: The returned value can be: 
  *   FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  */
FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address)
{
  FLASH_Status status = FLASH_COMPLETE;
  
  /* Check the parameters */
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
  
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
  
  if(status == FLASH_COMPLETE)
  {
    /* Write "00000000h" to valid address in the data memory" */
    *(__IO uint32_t *) Address = 0x00000000;
  }
   
  /* Return the erase status */
  return status;
}

Programming memory

写入 EEPROM 的步骤也很简单,一般的流程如下:

  • unlock
  • erase
  • write
  • lock
c 复制代码
/**
  * @brief  Programs a word at a specified address in data memory without erase.
  * @note   To correctly run this function, the DATA_EEPROM_Unlock() function
  *         must be called before.
  *         Call the DATA_EEPROM_Lock() to disable the data EEPROM access
  *         and Flash program erase control register access(recommended to protect 
  *         the DATA_EEPROM against possible unwanted operation).
  * @note   The function  DATA_EEPROM_FixedTimeProgramCmd() can be called before 
  *         this function to configure the Fixed Time Programming.
  * @param  Address: specifies the address to be written.
  * @param  Data: specifies the data to be written.
  * @retval FLASH Status: The returned value can be:
  *   FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or  FLASH_TIMEOUT. 
  */
FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data)
{
  FLASH_Status status = FLASH_COMPLETE;
  
  /* Check the parameters */
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
  
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
  
  if(status == FLASH_COMPLETE)
  {
    *(__IO uint32_t *)Address = Data;

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
  }
  /* Return the Write Status */
  return status;
}

Reading Momory

读取 EEPROM 中的数据就没那么多步骤了,直接读取对应的 Map 的 Bank 即可。

Note

对于 EEPROM 的操作,以下几点需要注意:

  • 尽量以 4 字节为一个单位进行操作
  • 在执行写入或者擦除操作的时候,尽量将全局中断关闭,以免中断触发引起其它的问题
  • 不要对相同的一个 Bank 同时做多种操作,尽量保证一个 Bank 只有一种操作在执行

列出一段 EEPROM 的参考代码:

c 复制代码
void EEPROM_Test(void)
{
	__set_PRIMASK(1);

	DATA_EEPROM_Unlock();

	/* EEPROM Operations */

	DATA_EEPROM_Lock();

	__set_PRIMASK(0);
}
相关推荐
一隅论数智2 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
不悔哥2 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
上海广测检测科技有限公司2 天前
智能平板出口巴西合规详解:Anatel射频、Inmetro电源/电池与LGPD数据合规叠加
经验分享
XiHongShi20162 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
优信电子2 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
FLJwu2 天前
存储与固件量产实战01:运动相机TF卡量产翻车实录!V30≠4K可用,90%OEM踩中的隐形售后坑
经验分享·数码相机·相机
深圳老胡2 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
xiaomu001232 天前
床垫选型的技术评估模型:结构、材料、卫生与检测四层口径
经验分享
wuyk5552 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
汉风设计装饰3 天前
智慧办公弱电系统设计:门禁、监控与 IoT 传感器的集成方案
经验分享