如何写入STM32 Flash

Posted

技术标签:

【中文标题】如何写入STM32 Flash【英文标题】:How to write to STM32 Flash 【发布时间】:2019-06-07 03:49:58 【问题描述】:

我想从我的用户代码写入 STM32F407VGT 的闪存扇区 11 以存储一些数据。我使用了stm32f4xx_hal_flash.c 库。我首先使用此代码擦除扇区:

void Flash_Init(void)
        
    FLASH_EraseInitTypeDef pEraseInit;

    pEraseInit.Banks = FLASH_BANK_1;
    pEraseInit.NbSectors = 1;
    pEraseInit.Sector = FLASH_SECTOR_10;
    pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
    pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;

    if(HAL_FLASH_Unlock() == HAL_OK)
    
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
        HAL_FLASHEx_Erase(&pEraseInit,0);
        HAL_FLASH_Lock();
    

程序在到达HAL_FLASHEx_Erase(&pEraseInit,0); 函数时挂起。我的分散文件如下所示:

LR_IROM1 0x08000000 0x01000000      ; load region size_region
  ER_IROM1 0x08000000 0x01000000    ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  
  RW_IRAM1 0x20000000 0x00020000    ; RW data
   .ANY (+RW +ZI)
  
  RW_IRAM2 0x10000000 0x00010000  
   .ANY (+RW +ZI)
  

我必须先做些什么才能让这个功能起作用吗?

【问题讨论】:

定义挂起。您的代码从哪里执行(您是否正在擦除存储当前代码的闪存)? 您好,感谢您的回复。当你问它从哪里执行时,我不确定你的意思。该函数是从 main 调用的。在这个例子中,我试图擦除闪存扇区 10(0x080C0000 到 0x080DFFFF),这是主闪存中的一个 12kbyte 块。根据构建输出的程序大小是“程序大小:代码=21432 RO-data=11152 RW-data=152 ZI-data=2152”所以我很难相信我的扇区擦除功能正在覆盖程序的一部分。扇区 0 到 3 每个为 16 kbyte,扇区 4 为 64 kbyte,扇区 5 到 11 为 128 kbyte。 啊,是的,这加起来了。那时可能不会删除您的代码。不过,hangs 是什么意思?数据表中是否提到了擦除闪存时的注意事项? 挂起是指函数HAL_FLASH_Lock(); 永远不会执行。从调试器中我可以看到,当调用它但未调用下一个函数时,该内存区域正在被擦除(所有 F)。我在数据表或 .c 文件中看不到任何会阻止此功能执行的内容。闪存控制寄存器访问必须在任何操作之前解锁,但程序可以成功地进行管理。我在想我的分散文件配置不正确,但除此之外我不确定? 您可以使用以下答案来解决您的问题。 ***.com/questions/44443619/… 【参考方案1】:

您想写入扇区 11,但您的 pEraseInit.Sector 变量在您的 init 函数中是 FLASH_SECTOR_10。所以你应该把 FLASH_SECTOR_10 改为 FLASH_SECTOR_11。 此外,如果您使用 CubeMX,您可以尝试在没有 init 函数的情况下执行写入和读取函数。

uint32_t flash_read(uint32_t address)
    return *(uint32_t*)address;


void flash_write(uint32_t address, uint32_t data)
    HAL_FLASH_Unlock();
    FLASH_Erase_Sector(FLASH_SECTOR_11,VOLTAGE_RANGE_1);
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,address,data);
    HAL_FLASH_Lock();

You can see flash memoty map from here

【讨论】:

谢谢,在查看您的代码后发现HAL_FLASHEx_Erase(); 函数不起作用,但FLASH_Erase_Sector(); 起作用。看了图书馆,我不知道为什么,但至少它解决了我的问题,谢谢。

以上是关于如何写入STM32 Flash的主要内容,如果未能解决你的问题,请参考以下文章

了解STM32参考手册中的写入flash流程

基于STM32的Flash读写详解

基于STM32的Flash读写详解

在货物监控设备研发工作中,如何向Stm32 flash写入数据

如何通过STM32将.bin文件刷入外部FLASH中

STM32 Flash 写入导致多个 HardFault 错误