你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G070进行flash读写操作

[复制链接]
STMCU小助手 发布时间:2021-11-10 18:02
STM32G070的flash读写问题
STM32G070xx的flash分布如下图,打算将Page 63用于保存用户数据。

2019102511214233.png


问题
开始一直出现flash写入失败,从返回码来看是FLASH_FLAG_PGSERR,一直找不到原因,代码如下:

  1. #define ADDR_USER_DATA  0x0801F800

  2. HAL_FLASH_Unlock();
  3. FLASH_PageErase(63);
  4. ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, ADDR_USER_DATA, (uint64_t)data);
  5. HAL_FLASH_Lock();

  6. if (ret != HAL_OK)
  7. {
  8.     printf("\r\nuser data save failed, ret = %u, flash err = 0x%x", ret, HAL_FLASH_GetError());
  9. }
复制代码

2019102511181630.png


后来终于在community.st找到了答案:

20191025112810625.png


STM32G070 flash驱动代码
好了,话不多说,直接上最终的代码,亲测有效:

  1. HAL_StatusTypeDef flash_write(uint32_t address, uint64_t data)
  2. {
  3.     HAL_StatusTypeDef ret = HAL_OK;

  4.     HAL_FLASH_Unlock();
  5.     ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, address , data);
  6.     HAL_FLASH_Lock();

  7.     return ret;
  8. }

  9. void flash_page_erase(uint32_t page)
  10. {
  11.     HAL_StatusTypeDef test = HAL_FLASH_Unlock();

  12.     test = FLASH_WaitForLastOperation(1000); //1s timeout
  13.     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
  14.     FLASH_PageErase(page);
  15.     test = FLASH_WaitForLastOperation(1000);
  16.     CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

  17.     HAL_FLASH_Lock();
  18. }

  19.     /* 调用上述两个函数即可实现flash的擦除和写入 */
  20.     flash_page_erase(63);
  21.     ret = flash_write(ADDR_USER_DATA, (uint32_t)u_data);

  22.     /* 读取的话就简单了,直接使用地址即可 */
  23.     uint32_t u_data1 = 0;
  24.     u_data1 = *((uint32_t*)ADDR_USER_DATA);
复制代码

注意点
flash_write每次写入的是一个uint64_t类型的数据,其最终调用的函数为:

  1. static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
  2. {
  3.   /* Set PG bit */
  4.   SET_BIT(FLASH->CR, FLASH_CR_PG);

  5.   /* Program first word */
  6.   *(uint32_t *)Address = (uint32_t)Data;

  7.   /* Barrier to ensure programming is performed in 2 steps, in right order
  8.     (independently of compiler optimization behavior) */
  9.   __ISB();

  10.   /* Program second word */
  11.   *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
  12. }
复制代码

该函数每调用一次,其实是写入了2个word,所以在使用时需要注意Address的递增。


20210405170242660.png
20210405170242660.png
收藏 评论0 发布时间:2021-11-10 18:02

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版