stm32的內部flash在我們實際運行的時候。很多時候並沒有用完,還有許許多多的空閑內存,因此可以利用內部flash存儲一些數據。我使用的是stm32f407vet6 ,所以就用這個芯片來進行演示。
認識內部的存儲划分。
這是芯片內部的存儲划分,需要注意的是,我們自己的程序也是存儲在這些位置,所以需要存儲在應用程序沒有使用的內存區域,關於如何查看內存的划分,可以去查看map文件,在此不展開敘述。
由於讀寫內部flash不需要特別的外設,只需要開啟一個串口就好了。
使用的是cube生成的
開始讀寫
讀寫內部flash只需要幾個結構體,函數就可以了。
HAL_FLASH_Unlock(); 解鎖內部flash函數,默認內部flASH是鎖上的,使用的時候,需要解鎖。
FLASH_EraseInitTypeDef 擦除內部flash的結構體,
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) 擦除函數
需要注意的是 與flash有關的函數,在兩個文件中
#include “stm32f4xx_hal_flash.h”
#include "stm32f4xx_hal_flash_ex.h"
因此需要包含着兩個頭文件。
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) flash寫入數據函數,需要注意的是第一個參數,決定寫入數據的類型 八位,16位 32 位。
uint8_t erase_flash(uint32_t sector_start,uint32_t sector_end)
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t SECTORError = 0;
uint32_t address,i;
HAL_FLASH_Unlock(); 解鎖內部flash
//FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; 以扇區進行擦除
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;/* ÒÔ¡°×Ö¡±µÄ´óС½øÐвÙ×÷ */
EraseInitStruct.Sector = sector_start; 擦除扇區的首 如果要擦除第五扇區,此處就填入5
EraseInitStruct.NbSectors = sector_end; 擦除扇區的尾,如果擦除第五扇區,就填入6
{
}
//address=add;
}
{
HAL_FLASH_Unlock();
//FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
uint32_t i=0,temp;
for(i=0;i<len;i++)
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, (uint32_t)address, *data) == HAL_OK)
注意我是以8位數據寫入的,因此第一個參數寫入的byte ,如果要想寫入32位的數據,改為對應的參數就行了。
{
address = address + 1;
data=data+1;
else
{
/*дÈë³ö´í£¬·µ»Ø£¬Êµ¼ÊÓ¦ÓÃÖпɼÓÈë´¦Àí */
return -1;
}
HAL_FLASH_Lock();
}
此函數是將一個uint8_t類型的數組,寫入對應的內部flash。
有了這來個函數,就能對內部flash進行讀寫的
在主函數進行申明
uint8_t flag=10,a[8]={22,33,44,55,66,77,88}; 即將寫入到內存的數據
uint32_t writeFlashData = 0x55555555;
uint32_t addr = ((uint32_t)0x08020000);這是第五扇區的開始地址
erase_flash(5,6); 擦除第五扇區
writedata_to_flash(a, 8,addr);將數組寫入
讀取數據,查看是否寫入成功
printf("at address:0x%x, read value:0x%d\r\n", addr, *(__IO uint8_t*)addr);
printf("at address:0x%x, read value:0x%d\r\n", addr+1, *(__IO uint8_t*)(addr+1));
printf("at address:0x%x, read value:0x%d\r\n", addr+2, *(__IO uint8_t*)(addr+2));
printf("at address:0x%x, read value:0x%d\r\n", addr+3, *(__IO uint8_t*)(addr+3));