[STM32F1]

STM32基础篇 flash 模拟 EEPROM 实验

[复制链接]
3412|20
手机看帖
扫描二维码
随时随地手机跟帖
aizaixiyuanqian|  楼主 | 2018-2-17 09:16 | 显示全部楼层 |阅读模式
STM32 本身没有自带 EEPROM,但是 STM32 具有 IAP(在应用编程)功能,
所以我们可以把它的 FLASH 当成 EEPROM 来使用。本次试验,我们将利用 STM32 内
部的 FLASH 实现数据的存放,通过串口打印显示存放数据,不过我们是将数据
直接存放在 STM32 内部,而不是存放在 W25Q64。
实验目标:
1. 学习操作 STM32 内部 flash

aizaixiyuanqian|  楼主 | 2018-2-17 09:17 | 显示全部楼层
STM32 FH LASH  简介
不同型号的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字节,最大的则达到
了 1024K 字节。我们的 STM32 开发板选择的 STM32F103ZET6 的 FLASH 容量为 512K 字节,
属于大容量产品(另外还有中容量和小容量产品),大容量产品的闪存模块组织如图所示:

1.PNG

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:18 | 显示全部楼层
STM32 的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等 3 部分组成。
主存储器,该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品,
其被划分为 256 页,每页 2K 字节。注意,小容量和中容量产品则每页只有 1K 字节。从
上图可以看出主存储器的起始地址就是 0X08000000, Boot0、 Boot1 都接 GND 的时候,
就是从 0X08000000 开始运行代码的。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:18 | 显示全部楼层
信息块,该部分分为 2 个小部分,其中启动程序代码,是用来存储 ST 自带的启动程
序,用于串口下载代码,当 Boot0 接 V3.3, Boot1 接 GND 的时候,运行的就是这部分代
码。用户选择字节,则一般用于配置写保护、读保护等功能,本次试验不作介绍。
闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。对
主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压
由内部产生。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:19 | 显示全部楼层
在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能
正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。
下面我们介绍本次实验要使用到的闪存状态寄存器: FLASH_SR。该寄存器各位描述如图所
示:
1.PNG

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:20 | 显示全部楼层
FLASH  解锁
在对 FLASH 进行写操作前必须先解锁,固件库函数实现很简单:
FLASH_Unlock();//解锁

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:21 | 显示全部楼层
  清除相关的标志位
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPR
TERR);//清除标志位

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:21 | 显示全部楼层
  擦除 函数
固件库提供三个 FLASH 擦除函数:
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
FLASH_Status FLASH_EraseAllPages(void);
FLASH_Status FLASH_EraseOptionBytes(void);
这三个函数可以顾名思义了,非常简单。本设计使用的是第一个擦除函数 。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:21 | 显示全部楼层
写操作 函数
固件库提供了三个 FLASH 写函数:
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
顾名思义分别为: FLASH_ProgramWord 为 32 位字写入函数, 其他分别为 16 位半字
写入和 8 位字节写入函数。这里需要说明, 32 位字节写入实际上是写入的两次 16 位数
据,写完第一次后地址+2。 写入 8 位实际也是占用的两个地址了,跟写入 16 位基本上没
啥区别。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:26 | 显示全部楼层
  锁定 函数
在对 FLASH 写操作完成之后,我们要锁定 FLASH,使用的库函数是:
void FLASH_Lock(void);

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:26 | 显示全部楼层
初始化
void FLASHINIT_FLASH()
{
FLASH_Unlock();//解锁
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|
FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
FLASH_ErasePage(flash_adr);//要擦出页的起始地址
FLASH_ProgramWord(flash_adr,flash_data);//写数据
//FLASH_ProgramWord(FLASH_ADR+4,data);//接着上面写内容给 flash,每写一次
是一个字即四个字节
FLASH_Lock();//锁定
flash_data=0;
flash_data=(*(u32*)(flash_adr));  //__IO uint32_t
printf("输出 flash_data=%d\r\n",flash_data);
}

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:27 | 显示全部楼层
我们要写入的地址是:
#define flash_adr 0x0801f000  //定义主存储器的保存数据的起始地 0x0807F800
写入的数据是:
u32 flash_data=13;

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:28 | 显示全部楼层
int main()
{
printf_init(); //printf 初始化
FLASHINIT_FLASH();//flash 初始化
while(1);
}
该函数实现将要写入的数据 13 保存在芯片 FLASH 内,只要复位按下即可读取此数据,通过
串口打印输出

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-17 09:32 | 显示全部楼层
1.PNG 当程序下载进去后,打开串口,对 DTR 前进行勾选,然后在取消。再通过发送字符即可以显示。

使用特权

评论回复
CaLipton| | 2018-2-22 11:54 | 显示全部楼层
写之前解锁,写之后上锁

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-2-23 19:28 | 显示全部楼层
CaLipton 发表于 2018-2-22 11:54
写之前解锁,写之后上锁

是的

使用特权

评论回复
gmgmgm| | 2018-6-3 18:01 | 显示全部楼层
aizaixiyuanqian 发表于 2018-2-17 09:21
写操作 函数
固件库提供了三个 FLASH 写函数:
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_ ...

为什么我调试时一执行写函数FLASH_ProgramWord()就死机,是哪里的原因,求助,谢谢

使用特权

评论回复
gmgmgm| | 2018-6-3 18:04 | 显示全部楼层
aizaixiyuanqian 发表于 2018-2-17 09:21
擦除 函数
固件库提供三个 FLASH 擦除函数:
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);


我把函简化成下面,就是会死机,万分求助
void FLASHINIT_FLASH(void)
{
FLASH_Unlock();//解锁
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
FLASH_ErasePage(0x08002a50);//要擦出页的起始地址
FLASH_ProgramWord(0x08002a50,0x1234);//写数据
//是一个字即四个字节
FLASH_Lock();//锁定
}

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-6-17 20:45 | 显示全部楼层
gmgmgm 发表于 2018-6-3 18:01
为什么我调试时一执行写函数FLASH_ProgramWord()就死机,是哪里的原因,求助,谢谢 ...

是不是卡在某个死循环中了。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-6-17 20:46 | 显示全部楼层
gmgmgm 发表于 2018-6-3 18:04
我把函简化成下面,就是会死机,万分求助
void FLASHINIT_FLASH(void)
{

边注释边调试,看下那条语句影响的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝