STM32L0内部的EEPROM写操作由解锁,写入,加锁过程组成,读过程则无需解锁。至于STM32L0内部的非易失空间区分为FLASH和EEPROM,主要体现在用ST-LINK等工具进行整片擦除时,只擦除FLASH的空间,EEPROM的部分不会被擦除,如同外部EEPROM芯片,MPU的代码升级不影响EEPROM的内容。后面以内部EEPROM的写读作为范例。
定义内部EEPROM的地址空间:
//STM32L031K6T6
#define EEPROM_BASE_ADDR 0x08080000
#define EEPROM_BYTE_SIZE 0x03FF
基础字节写函数
//Byte write
void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
{
uint16_t i;
HAL_StatusTypeDef status = HAL_OK;
HAL_FLASHEx_DATAEEPROM_Unlock();
for(i=0;i
基础字节读函数
//Byte read
void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len)
{
uint8_t *wAddr;
wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);
while(Len--)
{
*Buffer++=*wAddr++;
}
}
如果考虑到写读过程中,可以出现错误的情况,为了保证操作的正确性,需要采用校验方式进行写读。
对于写过程,需要将写入的数据,读回做比较。
对于读过程,需要将两次读回的数据,进行比较。
如果比较正确,则操作完成。
如果错误,可重新进行写或读操作,并在设定的重新操作次数范围内,进行重新操作识别,如果正确,则报告正确,如果错误,则报告错误。
设定重复校验次数
#include
#define iEEPROM_CHECK_NUM 2
带操作校验的写函数
HAL_StatusTypeDef EEPROM_WRITE_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
{
uint8_t buff[len];
uint16_t i;
for (i=0;i
带操作校验的读函数
HAL_StatusTypeDef EEPROM_Read_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
{
uint8_t buff0[len];
uint8_t buff1[len];
uint16_t i;
for (i=0;i
其中BiasAddress为0对应内部EEPROM的0地址(EEPROM_BASE_ADDR定义了其基址),Data为数据字节指针,len为操作字节长度。
需要注意的是,基于工艺制程和设计,EEPROM的使用也分为两种,其中一种和FRAM相似,可以直接进行写入而不需要提前擦除,STM32内部的EEPROM也是这一种;另外一种和FLASH相似,需要先进行基于Page的擦除后才能正确写入,对于有的EEPROM,支持基于Page最小为Byte单元的擦除。
HAL提供的内部EEPROM擦除函数, 只是进行一个word的擦除,即在某个地址上将数据改写为0x00000000, 和直接调用写函数在该地址写入0x00000000效果一样。HAL的内部EEPROM擦除函数如下:
/**
* @brief Erase a word in data memory.
* @param Address specifies the address to be erased.
* @note To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
* must be called before.
* Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access
* and Flash program erase control register access(recommended to protect
* the DATA_EEPROM against possible unwanted operation).
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the parameters */
assert_param(IS_FLASH_DATA_ADDRESS(Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
if(status == HAL_OK)
{
/* Clean the error context */
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
/* Write 00000000h to valid address in the data memory */
*(__IO uint32_t *) Address = 0x00000000U;
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
}
/* Return the erase status */
return status;
}
上述的代码,如果要用于STM32内部FLASH的操作,还需要增加页擦除操作。
-End-