STM32G070的flash读写问题
STM32G070xx的flash分布如下图,打算将Page 63用于保存用户数据。
问题
开始一直出现flash写入失败,从返回码来看是FLASH_FLAG_PGSERR,一直找不到原因,代码如下:
- #define ADDR_USER_DATA 0x0801F800
- HAL_FLASH_Unlock();
- FLASH_PageErase(63);
- ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, ADDR_USER_DATA, (uint64_t)data);
- HAL_FLASH_Lock();
- if (ret != HAL_OK)
- {
- printf("\r\nuser data save failed, ret = %u, flash err = 0x%x", ret, HAL_FLASH_GetError());
- }
复制代码
后来终于在community.st找到了答案:
STM32G070 flash驱动代码
好了,话不多说,直接上最终的代码,亲测有效:
- HAL_StatusTypeDef flash_write(uint32_t address, uint64_t data)
- {
- HAL_StatusTypeDef ret = HAL_OK;
- HAL_FLASH_Unlock();
- ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, address , data);
- HAL_FLASH_Lock();
- return ret;
- }
- void flash_page_erase(uint32_t page)
- {
- HAL_StatusTypeDef test = HAL_FLASH_Unlock();
- test = FLASH_WaitForLastOperation(1000); //1s timeout
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
- FLASH_PageErase(page);
- test = FLASH_WaitForLastOperation(1000);
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
- HAL_FLASH_Lock();
- }
- /* 调用上述两个函数即可实现flash的擦除和写入 */
- flash_page_erase(63);
- ret = flash_write(ADDR_USER_DATA, (uint32_t)u_data);
- /* 读取的话就简单了,直接使用地址即可 */
- uint32_t u_data1 = 0;
- u_data1 = *((uint32_t*)ADDR_USER_DATA);
复制代码
注意点
flash_write每次写入的是一个uint64_t类型的数据,其最终调用的函数为:
- static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
- {
- /* Set PG bit */
- SET_BIT(FLASH->CR, FLASH_CR_PG);
- /* Program first word */
- *(uint32_t *)Address = (uint32_t)Data;
- /* Barrier to ensure programming is performed in 2 steps, in right order
- (independently of compiler optimization behavior) */
- __ISB();
- /* Program second word */
- *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
- }
复制代码
该函数每调用一次,其实是写入了2个word,所以在使用时需要注意Address的递增。
|