0. 简介
在STM32F429 上用FLASH 模拟 EEPROM,工程是STM32CubeIDE里面创建和生成的。调试时发现第一次写FLASH时总是出错,第二次及之后再写FLASH则没问题。
1. 问题原因
写FLASH之前会擦除FLASH Sector,第一次擦除时出错。进一步跟踪,发现是调用FLASH_WaitForLastOperation
时返回错误。以下是HAL库里FLASH_WaitForLastOperation的源码。
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
uint32_t tickstart = 0U;
/* Clear Error Code */
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
Even if the FLASH operation fails, the BUSY flag will be reset and an error
flag will be set */
/* Get tick */
tickstart = HAL_GetTick();
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
{
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
{
return HAL_TIMEOUT;
}
}
}
/* Check FLASH End of Operation flag */
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
{
/* Clear FLASH End of Operation pending bit */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
}
#if defined(FLASH_SR_RDERR)
if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
#else
if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET) // **这里出错**
#endif /* FLASH_SR_RDERR */
{
/*Save the error code*/
FLASH_SetErrorCode();
return HAL_ERROR;
}
/* If there is no error flag set */
return HAL_OK;
}
发现在__HAL_FLASH_GET_FLAG 时, FLASH_FLAG_PGPERR 和 FLASH_FLAG_PGSERR置位了。所以会返回擦除失败。
但是 FLASH_SetErrorCode 里又会reset 这两位,所以第二次擦除成功。
2. FLASH_FLAG_PGPERR & FLASH_FLAG_PGSERR 错误含义
在查看STM32F4参考手册发现:
FLASH_FLAG_PGSERR : Programming sequence error
FLASH_FLAG_PGPERR : Programming parallelism error
原因可能是 FLASH->CR 里的 PSIZE设置错误。
3. Debug
3.1 上电debug 查找 FLASH->SR何时被置位
发现在上电后初始化时钟时, 即执行到 HAL_Init();
,FLASH->SR 的 bit6&7 就会被置位,而到此时,执行的都是 cubemx自动生成的 HAL库代码。
3.2 追踪FLASH->CR
上电之后, FLASH->CR只有bit31置位,其他均为0.查看FLASH->CR寄存器说明
PSIZE = 0 时对应的是8位, 而STM32F429是32位,所以应该将 PSIZE设置为 0b10。
设置后继续debug
FLASH->SR bit6 的错误没了,但 bit7错误 Programming sequence error 还在。
PGSERR: Programming sequence error
Set by hardware when a write access to the Flash memory is performed by the code while the
control register has not been correctly configured.
FLASH->CR配置不正确,查看下来只有 CR 的 bit0 有可能。
3.3 问题解决
将 FLASH->CR bit0 置1.
以上,在初始化时,正确配置 FLASH->CR的 PSIZE 和 PG,则消除 FLASH->SR的 bit6&7 错误。文章来源:https://www.toymoban.com/news/detail-766113.html
注:上述未经过稳定性测试。文章来源地址https://www.toymoban.com/news/detail-766113.html
到了这里,关于STM32 FLASH error: FLASH_FLAG_PGPERR & FLASH_FLAG_PGSERR的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!