绝⼤多数的单⽚机和微控制器(ARM,x86),地址空间都是以字节为单位的,也就是说⼀个地址是⼀个字节。Flash存储器有个特点,就是只能写0,不能写1。所以如果原来的地址有数据了,意味着有⼀些位为0,这些位就相当于⽆效了。所以必须写之前确保他们都为1,只有擦除才可以。另外每次擦除都必须擦除⼀个4K⼤⼩的扇区,这是flash的特性所决定的。对Flash操作前必需打开内部振荡器。 STM32F030F4P6的Flash存储简介
STM32F030F4P6硬件配置: FLASH (16KB) RAM (4KB) (包含4个扇区,1个扇区包含4个页,每页有1Kbyte空间) ⽤户可以对Flash进⾏program 和 erase 操作。
Main Flash memory programming
The main Flash memory can be programmed 16 bits at a time. Flash memory erase
The Flash memory can be erased page by page or completely (Mass Erase).
Flash memory addresses0x0800 0000 - 0x0800 03FF0x0800 0400 - 0x0800 07FF0x0800 0800 - 0x0800 0BFF0x0800 0C00 - 0x0800 0FFF0x0800 1000 - 0x0800 13FF0x0800 1400 - 0x0800 17FF0x0800 1800 - 0x0800 1BFF0x0800 1C00 - 0x0800 1FFF0x0800 2000 - 0x0800 23FF0x0800 2400 - 0x0800 27FF0x0800 2800 - 0x0800 2BFF0x0800 2C00 - 0x0800 2FFF0x0800 3000 - 0x0800 33FF0x0800 3400 - 0x0800 37FF
Size(byte)1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte1 Kbyte
NamePage 0Page 1Page 2Page 3Page 4Page 5Page 6Page 7Page 8Page 9Page 10Page 11Page 12Page 13
DescriptionSector 0Sector 0Sector 0Sector 0Sector 1Sector 1Sector 1Sector 1Sector 2Sector 2Sector 2Sector 2Sector 3Sector 3
0x0800 3800 - 0x0800 3BFFFlash memory addresses0x0800 3C00 - 0x0800 3FFF
1 KbyteSize(byte)1 Kbyte
Page 14NamePage 15
Sector 3DescriptionSector 3
STM32F030F4P6的Flash读写参考代码(HAL库)
/* Base address of the Flash sectors */
#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000000) /* Base @ of Page 0, 1 Kbyte */#define ADDR_FLASH_PAGE_1 ((uint32_t)0x08000400) /* Base @ of Page 1, 1 Kbyte */#define ADDR_FLASH_PAGE_2 ((uint32_t)0x08000800) /* Base @ of Page 2, 1 Kbyte */#define ADDR_FLASH_PAGE_3 ((uint32_t)0x08000C00) /* Base @ of Page 3, 1 Kbyte */#define ADDR_FLASH_PAGE_4 ((uint32_t)0x08001000) /* Base @ of Page 4, 1 Kbyte */#define ADDR_FLASH_PAGE_5 ((uint32_t)0x08001400) /* Base @ of Page 5, 1 Kbyte */#define ADDR_FLASH_PAGE_6 ((uint32_t)0x08001800) /* Base @ of Page 6, 1 Kbyte */#define ADDR_FLASH_PAGE_7 ((uint32_t)0x08001C00) /* Base @ of Page 7, 1 Kbyte */#define ADDR_FLASH_PAGE_8 ((uint32_t)0x08002000) /* Base @ of Page 8, 1 Kbyte */#define ADDR_FLASH_PAGE_9 ((uint32_t)0x08002400) /* Base @ of Page 9, 1 Kbyte */#define ADDR_FLASH_PAGE_10 ((uint32_t)0x08002800) /* Base @ of Page 10, 1 Kbyte */#define ADDR_FLASH_PAGE_11 ((uint32_t)0x08002C00) /* Base @ of Page 11, 1 Kbyte */#define ADDR_FLASH_PAGE_12 ((uint32_t)0x08003000) /* Base @ of Page 12, 1 Kbyte */#define ADDR_FLASH_PAGE_13 ((uint32_t)0x08003400) /* Base @ of Page 13, 1 Kbyte */#define ADDR_FLASH_PAGE_14 ((uint32_t)0x08003800) /* Base @ of Page 14, 1 Kbyte */#define ADDR_FLASH_PAGE_15 ((uint32_t)0x08003C00) /* Base @ of Page 15, 1 Kbyte *//* Private define ------------------------------------------------------------*/
#define FLASH_USER_START_ADDR ADDR_FLASH_PAGE_15 /* Start @ of user Flash area */
#define FLASH_USER_END_ADDR ADDR_FLASH_PAGE_15 + FLASH_PAGE_SIZE /* End @ of user Flash area */#define DATA_32 ((uint32_t)0x12345678)/*Variable used for Erase procedure*/
static FLASH_EraseInitTypeDef EraseInitStruct;uint32_t Address = 0;/**
* @brief Main program * @param None * @retval None */
int main(void){
/* STM32F0xx HAL library initialization: - Configure the Flash prefetch
- Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Low Level Initialization */ HAL_Init();
/* Configure the system clock to 48 MHz */ SystemClock_Config();
/* Unlock the Flash to enable the flash control register access *************/ HAL_FLASH_Unlock(); /* Erase the user Flash area
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/ /* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;
EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;
EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE; if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { /*
Error occurred while page erase.
User can add here some code to deal with this error.
PageError will contain the faulty page and then to know the code error on this page, user can call function 'HAL_FLASH_GetError()' */
/* Infinite loop */ while (1) {
/* User doing something here */ } }
/* Program the user Flash area word by word
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/ Address = FLASH_USER_START_ADDR; while (Address < FLASH_USER_END_ADDR) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK) {
Address = Address + 4; } else {
/* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ while (1) {
/* User doing something here */ } } }
/* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ HAL_FLASH_Lock();
/* Check if the programmed data is OK
MemoryProgramStatus = 0: data programmed correctly
MemoryProgramStatus != 0: number of words not programmed correctly ******/ Address = FLASH_USER_START_ADDR; MemoryProgramStatus = 0x0;
while (Address < FLASH_USER_END_ADDR) {
data32 = *(__IO uint32_t *)Address; if (data32 != DATA_32) {
MemoryProgramStatus++; }
Address = Address + 4; }
/*Check if there is an issue to program data*/ if (MemoryProgramStatus == 0) {
/* User doing something here */ } else
else {
while (1) {
/* User doing something here */ } }
/* Infinite loop */ while (1) { }}
因篇幅问题不能全部显示,请点此查看更多更全内容