代码[C] 纯文本查看 复制代码 void stmflash_write(uint32_t waddr, uint32_t *pbuf, uint32_t length)
{
FLASH_EraseInitTypeDef FlashEraseInit;
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t SectorError = 0;
uint32_t addrx = 0;
uint32_t endaddr = 0;
uint32_t bankFlag = 0;
if (waddr < STM32_FLASH_BASE || waddr % 32 || /* 写入地址小于 STM32_FLASH_BASE, 或不是32的整数倍, 非法. */
waddr > (STM32_FLASH_BASE + STM32_FLASH_SIZE)) /* 写入地址大于 STM32_FLASH_BASE + STM32_FLASH_SIZE, 非法. */
{
return;
}
HAL_FLASH_Unlock(); /* 解锁 */
addrx = waddr; /* 写入的起始地址 */
endaddr = waddr + length * 4; /* 写入的结束地址 */
if(IS_FLASH_PROGRAM_ADDRESS_BANK1(addrx))
{
bankFlag = FLASH_BANK_1;
}
// else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(addrx))
// {
// bankFlag = FLASH_BANK_2;
// }
if (addrx < 0X1FF00000)
{
while (addrx < endaddr) /* 扫清一切障碍.(对非FFFFFFFF的地方,先擦除) */
{
if (stmflash_read_word(addrx) != 0XFFFFFFFF) /* 有非0XFFFFFFFF的地方,要擦除这个扇区 */
{
FlashEraseInit.Banks = bankFlag;
FlashEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; /* 擦除类型,扇区擦除 */
FlashEraseInit.Sector = FLASH_If_addr_to_setor(addrx); /* 要擦除的扇区 */
FlashEraseInit.NbSectors = 1; /* 一次只擦除一个扇区 */
FlashEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3; /* 电压范围,VCC=2.7~3.6V之间!! */
if (HAL_FLASHEx_Erase(&FlashEraseInit, &SectorError) != HAL_OK)
{
break; /* 发生错误了 */
}
// SCB_CleanInvalidateDCache(); /* 清除无效的D-Cache */
}
else
{
addrx += 4;
}
FLASH_WaitForLastOperation(FLASH_WAITETIME, bankFlag); /* 等待上次操作完成 */
}
}
FlashStatus = FLASH_WaitForLastOperation(FLASH_WAITETIME, bankFlag); /* 等待上次操作完成 */
if (FlashStatus == HAL_OK)
{
while (waddr < endaddr) /* 写数据 */
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, waddr, (uint64_t)pbuf) != HAL_OK) /* 写入数据 */
{
break; /* 写入异常 */
}
waddr += 32;
pbuf += 8;
}
}
HAL_FLASH_Lock(); /* 上锁 */
}
|