STM32 内部 EEPROM 读写

STM32 的某些系列 MCU 自带 EEPROM 。笔者使用的 STM32L151RET6 自带 16 KBEEPROM,可以用来存储自定义的数据。在芯片选型时,自带 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 EEPROMProgram/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);
}
相关推荐
追梦少年时8 分钟前
STM32-Flash闪存
stm32·单片机·嵌入式硬件·51单片机
weixin_452600691 小时前
《青牛科技 GC6125:驱动芯片中的璀璨之星,点亮 IPcamera 和云台控制(替代 BU24025/ROHM)》
人工智能·科技·单片机·嵌入式硬件·新能源充电桩·智能充电枪
weixin_452600692 小时前
【青牛科技】14W 高保真音频放大电路——D2030
科技·单片机·嵌入式硬件·音视频·电动工具·智能电表
源代码•宸5 小时前
完美解决 no model scale passed. assuming scale=‘n‘ 的YOLO问题
经验分享·yolo
xiao_xx5 小时前
华为云计算HCIE-Cloud Computing V3.0试验考试北京考场经验分享
经验分享·华为云
小刘同学-很乖9 小时前
MQTT从入门到精通之MQTT Dashboard
spring boot·stm32·物联网·iot
YuCaiH10 小时前
【STM32】USART串口数据包
笔记·stm32·单片机·嵌入式硬件
Kasen's experience12 小时前
STM32 GPIO 配置
stm32·单片机·嵌入式硬件
知行电子-12 小时前
Proteus中数码管动态扫描显示不全(已解决)
单片机·proteus·嵌入式
erxij13 小时前
【游戏引擎之路】登神长阶(十四)——OpenGL教程:士别三日,当刮目相看
c++·经验分享·游戏·3d·游戏引擎