STM32F103C8T6 FLASH模拟EEPROM

相关资料链接: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 }

 

posted @ 2022-01-21 14:09  伽椰子真可爱  阅读(1526)  评论(0编辑  收藏  举报