相關資料鏈接:https://blog.csdn.net/weixin_41542513/article/details/94356514
STM32F103C8T6的內部FLASH容量有64K,如果需要使用到內部FLASH來保存我們自定義的一些數據,則一般會選擇存儲后面的頁,這里我使用的時第62和63頁;
代碼實現如下:
頭文件:
1 /************************************************************ 2 * Copyright (C) 2021 , 伽椰子真可愛 3 * All right reserved. 4 * 文件名稱:DRIVE_STMFLASH.h 5 * 作 者:伽椰子(GD) 6 * 原始版本:V1.0 7 * 創建日期:2021/12/17 8 * 文件描述:STM32F103C8T6片內FLASH模擬EEPROM 9 * 函數列表: 10 * 11 * 歷 史: 12 * <作者> <時間> <版本> <功能描述> 13 * 14 * **********************************************************/ 15 #ifndef _DRIVE_STMFLASH_H_ 16 #define _DRIVE_STMFLASH_H_ 17 #include "stm32f10x.h" 18 19 #define FLASH_SIZE 64 //所選MCU的FLASH容量大小 20 21 22 #if FLASH_SIZE < 256 23 #define SECTOR_SIZE 1024 //單位Byte 24 #define STM32_FLASH_BASE 0x800FC00 //FLASH起始地址 25 #else 26 #define SECTOR_SIZE 2048 //單位Byte 27 #define STM32_FLASH_BASE 0x800F800 //FLASH起始地址 28 #endif 29 30 typedef enum 31 { 32 FLASH_OK, 33 FLASH_ERROR 34 }FLASH_E; 35 36 FLASH_E LibDriveFlashReadMoreData(uint32_t startAddress, uint16_t* readData0, uint32_t* readData1, uint16_t countToRead, uint8_t dataBit); 37 FLASH_E LibDriveFlashWriteMoreData(uint32_t startAddress, uint16_t *writeData, uint16_t countToWrite); 38 39 #endif
源文件:
1 /************************************************************ 2 * Copyright (C) 2021 , 伽椰子真可愛 3 * All right reserved. 4 * 文件名稱:DRIVE_STMFLASH.c 5 * 作 者:伽椰子 6 * 原始版本:V1.0 7 * 創建日期:2021/12/17 8 * 文件描述:STM32F103C8T6片內FLASH模擬EEPROM 9 * 函數列表: 10 * 11 * 歷 史: 12 * <作者> <時間> <版本> <功能描述> 13 * 14 * **********************************************************/ 15 #include "DRIVE_STMFLASH.h" 16 17 /************************************************* 18 函 數 名 稱 : LibDriveFlashReadHalfWord 19 功 能 描 述 : 讀取指定地址的半字(16位數據) 20 被 調用清單 : 無 21 調 用 清 單 : 22 輸 入 參 數 : Address讀取的地址 23 輸 出 參 數 : 無 24 返 回 參 數 : 無 25 其 他 : 無 26 *************************************************/ 27 static uint16_t LibDriveFlashReadHalfWord(uint32_t Address) 28 { 29 return *(__IO uint16_t*)Address; 30 } 31 32 /************************************************* 33 函 數 名 稱 : LibDriveFlashReadWord 34 功 能 描 述 : 讀取指定地址的全字(32位數據) 35 被 調用清單 : 無 36 調 用 清 單 : 37 輸 入 參 數 : Address讀取的地址 38 輸 出 參 數 : 無 39 返 回 參 數 : 無 40 其 他 : 無 41 *************************************************/ 42 static uint32_t LibDriveFlashReadWord(uint32_t Address) 43 { 44 uint32_t localData0 = 0; 45 uint32_t localData1 = 0; 46 47 localData0 = *(__IO uint16_t*)Address; 48 localData1 = *(__IO uint16_t*)(Address + 2); 49 return (localData1 << 16) + localData0; 50 } 51 52 /************************************************* 53 函 數 名 稱 : LibDriveFlashReadMoreData 54 功 能 描 述 : 從指定地址開始讀取多個數據 55 被 調用清單 : 無 56 調 用 清 單 : 57 輸 入 參 數 : startAddress 指定讀取地址(STM32F103C8T6的FLASH大小為64K,選擇最后一個扇區作為我們存儲數據的存儲區,地址范圍為:0x800FC00~0x800FFF), 58 readData0 讀取半字數據時數據緩存, 59 readData1讀取全字數據時數據緩存, 60 countToRead需要讀取數據的個數, 61 dataBit讀取數據的類型(半字為16,全字為32) 62 輸 出 參 數 : 無 63 返 回 參 數 : 無 64 其 他 : 無 65 *************************************************/ 66 FLASH_E LibDriveFlashReadMoreData(uint32_t startAddress, uint16_t* readData0, uint32_t* readData1, uint16_t countToRead, uint8_t dataBit) 67 { 68 uint16_t localIte = 0; 69 #if FLASH_SIZE < 256 70 if((startAddress < STM32_FLASH_BASE) || ((startAddress + countToRead * 2) >= (STM32_FLASH_BASE + 1024))) 71 { 72 return FLASH_ERROR;//非法地址 73 } 74 #else 75 if((startAddress < STM32_FLASH_BASE) || ((startAddress + countToRead * 2) >= (STM32_FLASH_BASE + 1024 * 2))) 76 { 77 return FLASH_ERROR;//非法地址 78 } 79 #endif 80 switch (dataBit) 81 { 82 case 16: 83 for (localIte = 0; localIte < countToRead; localIte++) 84 { 85 readData0[localIte] = LibDriveFlashReadHalfWord(startAddress + (localIte * 2)); 86 } 87 break; 88 case 32: 89 for (localIte = 0; localIte < countToRead; localIte++) 90 { 91 readData1[localIte] = LibDriveFlashReadWord(startAddress + (localIte * 4)); 92 } 93 break; 94 default: 95 break; 96 } 97 return FLASH_OK; 98 } 99 100 101 /************************************************* 102 函 數 名 稱 : LibDriveFlashWriteMoreData 103 功 能 描 述 :向指定地址寫入多個數據 104 被 調用清單 : 無 105 調 用 清 單 : 106 輸 入 參 數 : startAddress寫入的地址, 107 writeData待寫入數據, 108 countToWrite寫入數據字節數 109 輸 出 參 數 : 無 110 返 回 參 數 : 無 111 其 他 : 無 112 *************************************************/ 113 FLASH_E LibDriveFlashWriteMoreData(uint32_t startAddress, uint16_t *writeData, uint16_t countToWrite) 114 { 115 uint16_t localIndex = 0; 116 uint32_t offsetAddress = 0; 117 uint32_t sectorPosition = 0; 118 uint32_t sectorStartAddress = 0; 119 120 #if FLASH_SIZE < 256 121 if((startAddress < STM32_FLASH_BASE) || ((startAddress + countToWrite * 2) >= (STM32_FLASH_BASE + 1024))) 122 { 123 return FLASH_ERROR;//非法地址 124 } 125 #else 126 if((startAddress < STM32_FLASH_BASE) || ((startAddress + countToWrite * 2) >= (STM32_FLASH_BASE + 1024 * 2))) 127 { 128 return FLASH_ERROR;//非法地址 129 } 130 #endif 131 132 FLASH_Unlock(); //解鎖寫保護 133 134 offsetAddress = startAddress - STM32_FLASH_BASE; //計算去掉0X08000000后的實際偏移地址 135 sectorPosition = offsetAddress / SECTOR_SIZE; //計算扇區地址 136 sectorStartAddress = (sectorPosition * SECTOR_SIZE) + STM32_FLASH_BASE;//對應扇區的首地址 137 138 FLASH_ErasePage(sectorStartAddress); //擦除這個扇區 139 140 for (localIndex = 0; localIndex < countToWrite; localIndex++) 141 { 142 FLASH_ProgramHalfWord(startAddress + localIndex * 2, writeData[localIndex]); 143 } 144 145 FLASH_Lock(); //上鎖寫保護 146 147 return FLASH_OK; 148 }