目錄
一、前言
二、實現步驟
? ? ? ? 1.STM32CUBEMX配置
? ? ? ? 2.導入Flash庫
? ? ? ? 3.分析地址范圍
? ? ? ? 4.找到可用的地址
? ? ? ? 5.寫入讀取普通數據
? ? ? ? 6.寫入讀取字符串
? ? ? ? 6.1 存儲相關信息
? ? ? ? 6.2 存取多個參數
三、總結及源碼
一、前言
? ? ? ? 在面對需要持久化存儲的數據時,除了掛載TF卡,我們能用到的最方便的方法就是將數據粗存入Flash,比如存儲密碼、存儲記錄等。本文中的Flash庫由我開發,具有存取和寫出各類型數據和字符串的功能。
二、實現步驟
? ? ? ? 1.STM32CUBEMX配置
? ? ? ? 此處正常配置相關參數,本文使用STM32F103C6T6,時鐘頻率為72MHz,Flash操作無需配置其他參數。
? ? ? ? 2.導入Flash庫
? ? ? ? 下載并解壓壓縮包,可以得到一個.c文件和.h文件,將其導入到工程中,此處簡單就不再贅述,不會的話可以看之前的文章。
? ? ? ? 3.分析地址范圍
? ? ? ? 要寫入Flash,我們必須知道要寫入的內存地址,以STM32F103C8T6為例,依照下圖的命名規則可知其Flash大小為64K,根據計算,(64*1024)-1=65535,其對應的十六進制是0xFFFF,加上起始地址0x0800 0000,可知其Flash地址范圍為0x0800 0000-0x0800 FFFF
? ? ? ? 在實際開發中如果我們使用了不同的芯片,比如本文使用STM32F103C6T6,那么其地址范圍也不同,其地址范圍是0x0800 0000~0x0800 7FFF,如果我們向0x0800 E000去寫入數據,那必然不會成功,讀取亦然。
????????
? ? ? ? 4.找到可用的地址
? ? ? ? 其實即使我們分析出地址范圍是0x0800 0000~0x0800 7FFF,但這里邊的地址并非全部可用的,比如程序編譯后(如下圖)燒寫進去是會占用一部分地址的,因此你需要把考慮進去,本文就不做論述了,有興趣可以去其他地方查一查(如果有時間我也會出一篇文章說一下這個部分)。
? ? ? ? 5.寫入讀取普通數據
? ? ? ? 打開flash.h,可以看到我封裝了很多函數。當然還有一部分數據分割代碼,這個稍后再介紹。從聲明中,我們可以知道如何存儲和讀取uint8、uint16類型的數據。
? ? ? ? 寫入并讀取uint8_t類型數據。
uint8_t data_1='A';
Earse_Page(0x08006000,1);//擦除
Write_uint8(0x08006000,data_1);data_1=Read_uint8(0x08006000);
? ? ? ? 6.寫入讀取字符串
? ? ? ? 6.1 存儲相關信息
? ? ? ? 本庫完成了對字符串的讀寫操作,以地址0x0800 7000為例,寫入字符串“ABC”并讀取出來。
uint8_t data[50];memset(data,'\0',50);
sprintf((char *)data,"ABC\n");
STMFLASH_Write(0x08007000,data,50);
memset(data,'\0',50);
STMFLASH_Read(0x08007000,data,50);
HAL_UART_Transmit(&huart1,data,50,1000);
? ? ? ? 6.2 存取多個參數
? ? ? ? 通過這種辦法,其實我們可以一次存取多個參數信息,例如我將生成四個float類型的參數,將其轉換成字符串,其中以固定字符分割(,),隨后每次啟動時,從flash讀取字符串,并進行數據分割,即可實現去除數據的效果(這段代碼就是頭文件最后的數據分割代碼)。
//存取多個參數
memset(data,'\0',50);
sprintf((char *)data,"%.2f,%.2f,%.2f,%.2f",temp,hum,water,ch4);
STMFLASH_Write(0x08007000,data,50);STMFLASH_Read(0x08007000,data,50);
temp=atof(strtok((char *)data,","));
hum=atof(strtok(NULL,","));
water=atof(strtok(NULL,","));
ch4=atof(strtok(NULL,","));
sprintf((char *)data,"%.2f,%.2f,%.2f,%.2f",temp,hum,water,ch4);
HAL_UART_Transmit(&huart1,data,50,1000);
三、總結及源碼
? ? ? ? 文章至此,已經完成Flash的各類操作,需要注意的是,存儲單個類型的數據時需要先執行擦除操作,不擦除無法寫入。而存儲字符串時不需要,因為在字符串函數內我已經寫了擦除函數,直接調用即可。同時,本文也通過字符串讀寫為大家提供了一種存儲參數的方案。
? ? ? ? 庫文件:Flash-HAL庫文件-字符串讀寫
? ? ? ? 本文工程:Flash-HAL庫-STM32CUBEMX工程