基于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. */