我正在使用 stm32g070,我正在尝试擦除数据并将其编程到闪存中。这是我的代码:
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = 62u;
EraseInitStruct.NbPages = 1;
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_PROGERR | FLASH_FLAG_WRPERR | \ FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_PGSERR);
//Clear the page
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
/*Error occurred while page erase.*/
return HAL_FLASH_GetError ();
}
根据参考手册 0454(来自 STM32G070),此代码返回 HAL_FLASH_GetError() 中的值 96,对应于 0b0110 0000、位 5 (PGA ERR) 和位 6 (SIZ ERR)。有人可以帮助我吗?
我尝试理解为什么会出现这些错误,以及这是否与 HAL 层的问题有关。
我建议采用裸机方法。
#define FLASH_SECTORSIZE 2048
static void FLASH_Unlock(void)
{
FLASH -> KEYR = FLASH_UNLOCK_KEY1;
FLASH -> KEYR = FLASH_UNLOCK_KEY2;
}
static int FLASH_WaitForNotBSY(unsigned maxtime)
{
unsigned result = GERR_SUCCESS;
while(FLASH -> SR & FLASH_SR_BSY)
{
for(volatile unsigned i = 0; i < 500; i++);
if(!--maxtime) {result = GERR_TIMEOUT; break;}
}
return result;
}
static void FLASH_Lock(void)
{
FLASH_WaitForNotBSY(10);
FLASH -> CR |= FLASH_CR_LOCK;
}
#define FLASH_ERRORMASK (FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \
FLASH_SR_PGSERR | FLASH_SR_MISERR | FLASH_SR_FASTERR | FLASH_SR_RDERR | FLASH_SR_OPTVERR)
static void FLASH_CLEAR_ERRORS(void)
{
FLASH -> SR = FLASH_ERRORMASK;
}
static int FLASH_ErasePage(uint32_t address)
{
int result = !!(address % 2048);
if(!result)
{
if(GERR_SUCCEEDED(result = FLASH_WaitForNotBSY(10)))
{
FLASH_CLEAR_ERRORS();
FLASH -> CR &= ~FLASH_CR_PNB_Msk;
FLASH -> CR |= ((address / FLASH_SECTORSIZE) << FLASH_CR_PNB_Pos) | FLASH_CR_PER;
FLASH -> CR |= FLASH_CR_STRT;
if(!(result = FLASH_WaitForNotBSY(10)))
{
result = FLASH -> SR & FLASH_ERRORMASK;
}
}
}
FLASH -> CR &= ~FLASH_CR_PER;
return result;
}
static int FLASH_WriteData(uint32_t address, const void *data, size_t size)
{
int result = GERR_SUCCESS;
const unsigned char *ucdata = data;
size_t dataChunk;
volatile uint32_t *writePtr = (uint32_t *)address;
union
{
uint64_t u64;
uint32_t u32[sizeof(uint64_t) / sizeof(uint32_t)];
uint8_t u8[sizeof(uint64_t)];
} __attribute__((aligned(8))) dataUnion;
if(!(result = FLASH_WaitForNotBSY(10)))
{
FLASH_CLEAR_ERRORS();
FLASH -> CR |= FLASH_CR_PG;
while(size)
{
dataUnion.u64 = 0;
if(size >= sizeof(uint64_t)) dataChunk = sizeof(uint64_t);
else dataChunk = size;
memcpy(dataUnion.u8, ucdata, dataChunk);
*writePtr++ = dataUnion.u32[0];
*writePtr++ = dataUnion.u32[1];
if(GERR_FAILED(result = FLASH_WaitForNotBSY(10)) || (result = (FLASH -> SR & FLASH_ERRORMASK)))
{
break;
}
while(!(FLASH -> SR | FLASH_SR_EOP));
FLASH -> SR = FLASH_SR_EOP;
size -= dataChunk;
ucdata += dataChunk;
}
}
FLASH -> CR &= ~FLASH_CR_PG;
return result;
}
它来自另一个STM,但在编程过程中具有相同的64位(它计算8位ECC,因此您始终需要写入64位)。您的微控制器中可能不存在某些错误位,因此请检查。其余的应该按预期工作。