解锁

void flash_unlock(void)
{
/* (1) Wait till no operation is on going */
/* (2) Check if the PELOCK is unlocked */
/* (3) Perform unlock sequence */
while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
{
/* For robust implementation, add here time-out management */
}
if ((FLASH->PECR & FLASH_PECR_PELOCK) != 0) /* (2) */
{
FLASH->OPTKEYR = 0xFBEAD9C8;
FLASH->OPTKEYR = 0x24252627;
FLASH->PEKEYR = 0x89ABCDEFU;
FLASH->PEKEYR = 0x02030405U;
}
FLASH->PRGKEYR = 0x8C9DAEBF;
FLASH->PRGKEYR = 0x13141516;
}

擦除,这个芯片每页是128字节,别当成256

void flash_erase(void)
{
uint32_t addr = 0;

/* 解锁flash */
__disable_irq();
flash_unlock();

/* 擦除对应扇区 */
for(addr = UPDATE_ADDR; addr < END_ADDR; addr += 128)
{
FLASH->PECR |= FLASH_PECR_ERASE | FLASH_PECR_PROG; /* (1) */
*(__IO uint32_t *)addr = (uint32_t)0; /* (2) */
while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (3) */
{
/* For robust implementation, add here time-out management */
}
if ((FLASH->SR & FLASH_SR_EOP) != 0) /* (4) */
{
FLASH->SR = FLASH_SR_EOP; /* (5) */
}
else
{
/* Manage the error cases */
}
FLASH->PECR &= ~(FLASH_PECR_ERASE | FLASH_PECR_PROG); /* (6) */
}

/* 加锁flash */
while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
{
/* For robust implementation, add here time-out management */
}
FLASH->PECR |= FLASH_PECR_PELOCK; /* (2) */
__enable_irq();
}

写Flash

void flash_write(uint32_t addr, uint8_t* data, uint16_t len)
{
uint32_t old_addr = addr;
uint32_t i = 0;

__disable_irq();
flash_unlock();

/* 写数据 */
while(1)
{
/* (1) Perform the data write (32-bit word) at the desired address */
/* (2) Wait until the BSY bit is reset in the FLASH_SR register */
/* (3) Check the EOP flag in the FLASH_SR register */
/* (4) clear it by software by writing it at 1 */
*(__IO uint32_t*)(addr + UPDATE_ADDR + i) = ((uint32_t)data[i+3]<<24)+((uint32_t)data[i+2]<<16)+((uint32_t)data[i+1]<<8)+((uint32_t)data[0]);
while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (2) */
{
/* For robust implementation, add here time-out management */
}
if ((FLASH->SR & FLASH_SR_EOP) != 0) /* (3) */
{
FLASH->SR = FLASH_SR_EOP; /* (4) */
}
LL_mDelay(1);
i+=4;
if(i>=len)
{
break;
}
}
/* 加锁flash */
while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
{
/* For robust implementation, add here time-out management */
}
FLASH->PECR |= FLASH_PECR_PELOCK; /* (2) */

flash_test_read(old_addr);
__enable_irq();
}

STM32L031写Flash不使用HAL库_单片机