一、任务要求
1、Flash地址空间的数据读取。stm32f103c8t6只有20KB 内存(RAM)供程序代码和数组变量存放,因此,针对内部Flash的总计64KB存储空间(地址从0x08000000开始),运行一次写入8KB数据,总计复位运行代码4次,将32KB数据写入Flash。并验证写入数据的正确性和读写速率。
二、flash原理
1、Flash 存储基本单元 - 浮栅晶体管(Floating - Gate Transistor)
Flash 存储技术主要基于浮栅晶体管。这种晶体管有一个被绝缘层包围的浮栅(Floating Gate)。在普通的晶体管中,栅极(Gate)的电压控制着源极(Source)和漏极(Drain)之间的电流通断。而在浮栅晶体管中,浮栅可以存储电荷。当向浮栅中注入电子(写入数据)时,浮栅上的电荷会改变晶体管的阈值电压。例如,在没有电荷存储时,晶体管的阈值电压较低,在施加一定电压时就可以导通,代表数据 “0”;当向浮栅注入电子后,阈值电压升高,在相同的读取电压下晶体管无法导通,代表数据 “1”。
2、写入数据原理
(1)热电子注入(Hot - Electron Injection):
这是一种写入数据的方式。在这种方法中,通过对源极、漏极和控制栅极施加高电压,使得沟道中的电子获得足够的能量(成为热电子)。这些热电子能够穿越氧化层,进入浮栅中存储起来。例如,在传统的 NOR Flash 中,这种写入方式比较常见。以一个简单的电路为例,当要写入数据 “1” 时,通过特定的电压施加电路,使电子被注入浮栅。
(2)F - N 隧穿(Fowler - Nordheim Tunneling):
这是另一种写入机制。当在控制栅极和源极 / 漏极之间施加一个高电场时,电子可以通过量子隧穿效应穿过绝缘层进入浮栅。这种方式在 NAND Flash 中广泛使用。比如,在一个 3D NAND Flash 芯片的写入操作中,通过精确控制电场强度和时间,实现电子的隧穿注入,从而将数据写入存储单元。
3、读取数据原理
读取数据时,会在控制栅极施加一个适当的电压。这个电压低于写入时的电压。如果浮栅中有电荷(存储数据 “1”),晶体管的阈值电压会变高,在读取电压下不会导通,通过检测电路可以判断出存储的数据是 “1”;如果浮栅中没有电荷(存储数据 “0”),晶体管的阈值电压较低,在读取电压下会导通,检测电路会判断存储的数据是 “0”。
以一个字节(8 位)的数据读取为例,存储芯片中的读取电路会逐一对 8 个存储单元进行上述的读取操作,将每个单元的状态(0 或 1)组合起来,就得到了存储的字节数据。
4、擦除数据原理
擦除数据主要是将浮栅中的电荷移除。在 Flash 存储中,通常是采用 F - N 隧穿的逆过程。
对于 NAND Flash 来说,擦除操作是按块(Block)进行的。在擦除时,通过在衬底和控制栅极之间施加一个高电压,使得浮栅中的电子通过隧穿效应回到衬底,从而将整个块中的数据擦除。这就好比把一个装满东西的仓库清空,为下一次写入数据做好准备。而 NOR Flash 擦除操作相对复杂一些,通常也是通过类似的电荷释放机制,但可能在操作单元等方面有所不同。
三、CUBE工程配置
0、硬件及其软件工具
STM32F103C8T6、STlink
软件:Keil、STM32CubeMX
建立工程的具体操作不再赘述,这里只提几个地方
1、RCC配置
2、SYS配置
3、引脚gpio配置,默认即可
4、NVIC配置
5、时钟树配置
6、设置堆栈大小2k或者4k
7、code
配置完成之后点击右上角生成工程开始编写修改代码。
四、keil代码配置
源码分享
通过网盘分享的文件:stm32_Flash
链接: https://pan.baidu.com/s/1dd9EtpRSoeSnPDK0_9mA_g
提取码: pzq3
这边分享了工程源码,但是如果读者直接下载编译使用,肯定会报错,具体原因可能是因为所使用的keil版本不同导致。笔者搬运自张十三大佬的源码,可以跟笔者一样,自己另外创建新工程,将里面需要添加的源码自行复制到自己创建的新工程当中。
1、flash代码
将事先准备好的flash.c 及flash.h加入到工程中(flash.h文件放在INC文件夹下即可):
2、main.c添加
这里引号部分就是你想要写入读取的内容,可以自行修改,但不要有中文,flash读取时遇到中文会自动生成乱码
#include "flash.h"
uint8_t FlashWBuff [255];
uint8_t FlashRBuff [255];
uint8_t i;
uint8_t FlashTest[] = "cqjtu632207030127WJH";
/* USER CODE BEGIN SysInit */
FlashWriteBuff( DEVICE_INFO_ADDRESS, FlashTest,sizeof(FlashTest) ); // дÈëÊý¾Ýµ½Flash
for(i=0;i<255;i++)
FlashWBuff = i;
FlashWriteBuff( DEVICE_INFO_ADDRESS + sizeof(FlashTest), FlashWBuff,255 ); // дÈëÊý¾Ýµ½Flash
FlashReadBuff( DEVICE_INFO_ADDRESS + sizeof(FlashTest),FlashRBuff,255 ); // ´ÓFlashÖжÁÈ¡Êý
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
3、调试程序
需要链接stlink才能点击
View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800c000,观察将要修改的flash区间区容:
输入地址后记得按回车
View->Watch windows->Watch 1打开一个变量观察窗口,将变量FlashWBuff 和 FlashRBuff加入到 Watch 1 观察窗口:
View->Periodic Windows Update开启变量自动更新:
勾选
全速运行前
可以看到观察的两个都是全0
点击全速运行或者直接f5
可以看到两边观察的数据变为一致
同时可以看到memory里数据成功写入
断电重插,不点全速运行,里面写入的数据依旧还在
同时,可以尝试增加写入字符,尽可能多的写入数据,可以发现flash写入到达一定数量后后面的不再显示,说明达到了最大数组规模。
实验完成
五、总结
通过本实验了解到片内flash的重要作用,可以不借助外设即可实现存放。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_74774287/article/details/144760743
|