STM32 HAL库FLASH擦写页

基于STM32F103RC

编码

先读,有数据(可暂存),再擦,后写。
HAL_FLASHEx_Erase须传参,不宜直接传值,或导致扇区第一组数据不能被写(因错误标识符置起,PGERR)

/* USER CODE BEGIN PFP */
/**
	* @brief: stm32f103 main memory is between 0x08000000 to 0x0801FFFF, and with 128 sector (128 * 1K Byte)
	*/
int8_t GetPage(uint32_t flash_address)
{
	if (flash_address >= 0x08020000) return -1;
	
	return (uint8_t)((flash_address - FLASH_BASE) / 128);
	
}
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	uint16_t data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	uint32_t start_flash_address = 0x080010000, end_flash_address = 0x080015000;
	_Bool erase_flag = 0, allow_write_flag = 1;
	/* Unlock */
	HAL_FLASH_Unlock();
	/* Read */
	uint16_t read_date[10];
	for (uint8_t i = 0; i < 10; i++)
	{
		read_date[i] = *(__IO uint16_t*)start_flash_address + 2*i;
		if (read_date[i] != 0xFF) { erase_flag = 1; allow_write_flag = 0; break; }
	}
	/* Erase */
	if (erase_flag)
	{
		FLASH_EraseInitTypeDef FLASH_EraseInitType;
		FLASH_EraseInitType.TypeErase 	= FLASH_TYPEERASE_PAGES;
		FLASH_EraseInitType.PageAddress = start_flash_address;
		FLASH_EraseInitType.NbPages 		= GetPage(start_flash_address) - GetPage(end_flash_address) + 1;
		uint32_t PageError = HAL_FLASH_GetError();
		if (HAL_FLASHEx_Erase(&FLASH_EraseInitType, &PageError) == HAL_OK)
		{
			allow_write_flag = 1;
		}
	}
	/* Write */
	if (allow_write_flag)
	{
		for (uint8_t i = 0; i < 10; i++) 
			HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, start_flash_address + 2*i, (uint16_t)data[i]);
	}
	/* Lock */
	HAL_FLASH_Lock();
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

修改程序偏移地址

修改system_stm32f1xx.c,解除USER_VECT_TAB_ADDRESS定义注释,修改偏移量VECT_TAB_OFFSET
重新设置编译器地址信息和擦写地址

/* Note: Following vector table addresses must be defined in line with linker
         configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
#define USER_VECT_TAB_ADDRESS

#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000500U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值