STM32L0 内部EEPROM写读

STM32L0 内部EEPROM写读

说明

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<len;i++)
	{
		status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);
		Data++;
	}
	HAL_FLASHEx_DATAEEPROM_Lock();
}

基础字节读函数

//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 <string.h>
#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<iEEPROM_CHECK_NUM;i++)
	{
		EEPROM_WRITE(BiasAddress, Data, len);
		EEPROM_READ(BiasAddress, buff, len);
		if (memcmp(Data, buff, len)==0)
		{
			return HAL_OK;
		}
	}

	return HAL_ERROR;
}

带操作校验的读函数

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<iEEPROM_CHECK_NUM;i++)
	{
		EEPROM_READ(BiasAddress, buff0, len);
		EEPROM_READ(BiasAddress, buff1, len);

		if (memcmp(buff0, buff1, len)==0)
		{
			memcpy(Data, buff0, len);
			return HAL_OK;
		}
	}

	return HAL_ERROR;
}

其中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-

猜你喜欢

转载自blog.csdn.net/hwytree/article/details/103799910
今日推荐