当前位置:   article > 正文

stm32的HAL库函数flash无法写入的问题_stm32 flash写入不成功

stm32 flash写入不成功

记录一下对flash编程操作时出现的问题以及解决办法

问题:在使用HAL库中的HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)函数时发现总是没办法写入(明明写之前使用void FLASH_PageErase(uint32_t PageAddress)函数擦除了flash),查阅资料说是可能是因为固件库HAL_FLASH_Program函数有问题,建议换成寄存器直接操作,但是换成后发现仍有问题,读写入地址的数据任然是0xffffffff。

多次尝试发现,在第一次使用FLASH_PageErase擦除flash以及HAL_FLASH_Program写flash,烧录后,读取写入地址数据是0xffffffff,但是紧接着在代码中注释掉FLASH_PageErase这行,再次烧录,就会发现写入地址处的数据是程序中要写的数据,但是reset后就会发现,HAL_FLASH_Program函数的写入状态有问题,如下图所示:

 

以上可以猜测一下,可能是固件库 FLASH_PageErase函数有问题,选择用寄存器直接操作,直接照搬正点原子的寄存器函数,如下所示:

  1. static uint8_t stmflash_get_error_status(void)
  2. {
  3. uint32_t res;
  4. res = FLASH->SR;
  5. if (res & (1 << 0))return 1; /* BSY = 1 , 忙 */
  6. if (res & (1 << 2))return 2; /* PGERR = 1 , 编程错误*/
  7. if (res & (1 << 4))return 3; /* WRPRTERR = 1 , 写保护错误 */
  8. return 0; /* 没有任何错误 操作完成. */
  9. }
  10. static uint8_t stmflash_wait_done(uint32_t time)
  11. {
  12. uint8_t res;
  13. do
  14. {
  15. res = stmflash_get_error_status();
  16. if (res != 1)
  17. {
  18. break; /* 非忙, 无需等待了, 直接退出 */
  19. }
  20. time--;
  21. } while (time);
  22. if (time == 0)res = 0XFF; /* 超时 */
  23. return res;
  24. }
  25. /**
  26. * @brief 擦除扇区
  27. * @param saddr : 扇区地址 0 ~ 256
  28. * @retval 执行结果
  29. * @arg 0 : 已完成
  30. * @arg 2 : 编程错误
  31. * @arg 3 : 写保护错误
  32. * @arg 0XFF: 超时
  33. */
  34. static uint8_t stmflash_erase_sector(uint32_t saddr)
  35. {
  36. uint8_t res = 0; /* STM32F103擦除的时候是指定半字地址 */
  37. res = stmflash_wait_done(0X5FFFFF); /* 等待上次操作结束, >20ms */
  38. if (res == 0)
  39. {
  40. FLASH->CR |= 1 << 1; /* 页擦除 */
  41. FLASH->AR = saddr; /* 设置页地址(实际是半字地址) */
  42. FLASH->CR |= 1 << 6; /* 开始擦除 */
  43. res = stmflash_wait_done(0X5FFFFF); /* 等待操作结束, >20ms */
  44. if (res != 1) /* 非忙 */
  45. {
  46. FLASH->CR &= ~(1 << 1); /* 清除页擦除标志 */
  47. }
  48. }
  49. return res;
  50. }

然后主函数中添加如下代码:

  1. /* USER CODE BEGIN 1 */
  2. __IO uint32_t addr = 0x08020000;
  3. uint32_t applength = 0;
  4. uint16_t status;
  5. /* USER CODE END 1 */
  6. /* USER CODE BEGIN 2 */
  7. printf("更换为正点原子的寄存器擦除函数后的结果:\r\n");
  8. HAL_FLASH_Unlock();
  9. stmflash_erase_sector(addr);
  10. status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, 0x01f360b45);
  11. HAL_FLASH_Lock();
  12. applength = *(uint32_t *)addr;
  13. printf("写入flash中的数据是%x\r\n",applength);
  14. printf("flash的写函数返回值是%x\r\n",status);
  15. /* USER CODE END 2 */

 烧录后结果以及reset结果如下:

成功解决问题 !

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/607457
推荐阅读
相关标签
  

闽ICP备14008679号