STM32L412KB FLASH页无法擦除问题求助
Hey Harry, let's work through why your FLASH erase function only worked once and now fails. I'll break down the potential issues in your code and share actionable fixes and checks:
Key Issues in Your Current Code
Let's start with the code you provided—there are a few critical oversights that could cause intermittent or repeated erase failures:
1. Incomplete Error Handling & Flag Management
- You only clear FLASH error flags once at the start of the function. If an error occurs during any page erase, those flags will stay set and block subsequent operations.
- The
while((FLASH->SR & FLASH_SR_PGSERR));line is risky: if the PGSERR flag is ever set, this will lock your code in an infinite loop. Since you said the code still runs, this flag likely isn't triggering—but other unhandled errors (like WRPERR) are the real culprit. - You don't wait for the erase operation to fully complete before moving to the next page, nor do you verify the erase finished successfully with the EOP (End of Operation) flag.
2. Missing Post-Erase Cleanup
After triggering an erase with FLASH_CR_STRT, you don't:
- Wait for the
BSY(Busy) flag to clear, which means you might start the next erase before the current one finishes. - Clear the
EOPflag after each erase, which can interfere with subsequent operations. - Explicitly clear the
PER(Page Erase Enable) flag between operations (while some STM32 models auto-clear this, it's safer to handle it explicitly).
3. Unchecked Write Protection
Since your target pages (35-40) are in the latter half of FLASH, it's possible these pages have write protection enabled via the FLASH WRP (Write Protection) registers. A single successful erase might mean protection wasn't enabled initially, but something (like a reset or option byte change) enabled it afterward.
Fixed Code Implementation
Here's a revised version of your function with proper error handling, operation validation, and flag management:
int clearFlash(uint8_t numberOfPages, uint8_t firstPageNumber){ // Unlock FLASH and check if unlock succeeded if (HAL_FLASH_Unlock() != HAL_OK) { return -1; // Unlock failed } // Clear all FLASH error flags upfront __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); for (int i = 0; i < numberOfPages; i++){ uint8_t currentPage = firstPageNumber + i; // Wait for FLASH to be ready (BSY flag cleared) while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)); // Check for pending errors before starting erase if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR | FLASH_FLAG_OPERR)) { __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); HAL_FLASH_Lock(); return -2; // Pre-existing error detected } // Configure page erase: clear PER, set new page number, enable PER FLASH->CR &= ~(FLASH_CR_PER | FLASH_CR_PNB_Msk); FLASH->CR |= (currentPage << FLASH_CR_PNB_Pos) | FLASH_CR_PER; // Start erase operation FLASH->CR |= FLASH_CR_STRT; // Wait for erase to complete (BSY flag clears) while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)); // Verify erase succeeded via EOP flag if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); // Clear EOP for next operation } else { // Capture error flags for debugging uint32_t errorFlags = FLASH->SR; __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); HAL_FLASH_Lock(); return -3; // Erase failed for current page } } HAL_FLASH_Lock(); return 1; }
Additional Troubleshooting Steps
If the fixed code still fails, run these checks to narrow down the issue:
Read FLASH Error Flags After Failure
- When the function returns an error, read
FLASH->SRto see which flags are set:WRPERR: Target pages are write-protected. You'll need to disable write protection via the option bytes.PGAERR/PGSERR: Programming sequence error (the fixed code addresses this, but double-check page number calculations).OPERR: Invalid operation (e.g., trying to erase while FLASH is busy).
- When the function returns an error, read
Verify Write Protection Status
- Check the
FLASH->WRPR1register. For STM32L412KB:- Each bit in
WRPR1corresponds to 8 pages. Page 35 falls in the 32-39 range (bit 4), and page 40 falls in 40-47 (bit 5). If either bit is set, those pages are write-protected.
- Each bit in
- To disable protection: unlock the option bytes (
HAL_FLASH_OB_Unlock()), clear the relevant WRP bits, then lock the option bytes again.
- Check the
Check Power Supply Stability
- FLASH erase operations require stable power. If your board's VDD drops below ~2.0V (the minimum for STM32L4 FLASH operations), this can cause intermittent failures. Use an oscilloscope to check for voltage fluctuations during erase.
Final Notes
- The first successful erase confirms your hardware and page addressing are correct—this is almost certainly a code error handling or write protection issue.
- Use STM32CubeIDE's built-in FLASH programmer to manually erase pages 35-40. If this works, the problem is in your code; if it fails, write protection or hardware is the root cause.
内容的提问来源于stack exchange,提问作者arry_h




