STM32F103RCT6之FLASH读写操作

发布者:Ampoule最新更新时间:2018-10-08 来源: eefocus关键字:STM32F103RCT6  FLASH  读写操作 手机看文章 扫描二维码
随时随地手机看文章

一、STM32F103的FLASH简介

1、如图所示,STM32F103内部FLASH存储区分为三个区域:主存储区、信信息块和闪存存储器接口寄存器。

储存储区是我们读写FLASH的主要的存储区,MCU程序以及一些需要掉电保存的数据都是存储在这个区域的。

信息快:程序启动代码被存储在这部分。

最后的寄存器则是FLASH读写需要配置的一些寄存器位置。

STM32F103RCT6之FLASH读写操作
主存储器的起始位置0x08000000,除去程序占用的空间,剩余部分就可以作为数据保存的区域了,所以在利用内部FLASH存储数据的时候,一定不要占用程序本身所占用的空间,否则会导致死机。

主存储器一共256页,每页2K字节长度。

二、FLASH存储寄存器的配置

1、FPEC键寄存器:

在读写FLASH之前必须进行解锁FPEC,通过该寄存器,向该寄存器写入键值。当要操作FLASH时,需要将相应键值KEY1和KEY2写入寄存器中,同理,操作完成后,还要锁定该FLASH。

2、控制寄存器FLASH_CR

LOCK位:解锁或锁住位,解锁后该位清零,写1可锁住。

STRT位:该位写1,进行一次擦除。

PER位:该位写1,进行页擦除

PG位:读写选择位,写数据时该位需要置1,读数据则该位为0.

3、状态寄存器FLASH_SR

第5位EOP位:操作结束标志

第4位WRPRTERR位:写保护错误

第3位:保留

第2位:PGERR:编程错误

第1位BSY位:当FLASH正在被操作时,该位置1,当操作完成或发生错误时,清零。

4、地址寄存器FLASH_AR

选择要操作的FLASH地址,当BSY位为1时,即FLASH正在被操作,则该寄存器不能进行操作。

三、FLASH读写操作流程/1、STM32复位后,FPEC模块是被保护的,不能去操作各个寄存器,因此需要先解锁,向模块中写入

特定的序列到FLASH_KEYR寄存器,才能打开FPEC模块。如图所示。

STM32F103RCT6之FLASH读写操作

SMT32内部FLASH每次必须写入16位的数据,不能写8位,否则会出错。在对FLASH读写操作的时候,CPU会暂停(好像和SD卡很像,操作SD卡的时候,也是停止了MCU的其他事情,不能对MCU进行操作了)

2、写操作如图所示:

STM32F103RCT6之FLASH读写操作
首先判断FLASH是否解锁,如果没有解锁,将序列写入FLASH_KEYR寄存器解锁,然后将PG置1,选择写操作,然后向指定地址写入数据,检测BSY=1?如果忙碌状态,则=1,否则为0.

3、读操作

读操作比较简单,直接读取一个地址的数据即可,例如:

data = *(*uint16_t *)addr,首先将地址强制转换成uint6_t类型指针, 然后取该地址内容即可。

4、FLASH擦除

STM32F103RCT6之FLASH读写操作
擦除过程分为页擦除和整片擦除。

页擦除流程:首先判断FLASH是否是锁定状态,如果是则进行解锁,然后判断是否是BSY状态,若不是忙碌状态,则设置CR寄存器位为擦除操作,且为页擦除操作。

四、FLASH读写函数解析

1、解锁函数

void STMFLASH_Unlock(void)

{

  FLASH->KEYR=FLASH_KEY1;

  FLASH->KEYR=FLASH_KEY2;

}可以看出该函数是将解锁序列依次写入FLASH->KEYR寄存器。

2、上锁函数

void STMFLASH_Lock(void)

{

  FLASH->CR|=1<<7;//该函数就是将LOCK位置1

}

3、读取FLASH状态寄存器,查看状态,返回值为状态

u8 STMFLASH_GetStatus(void)

{

u32 res;

res=FLASH->SR; 

if(res&(1<<0))return 1;    //忙碌则返回1

else if(res&(1<<2))return 2; //编程错误返回2

else if(res&(1<<4))return 3; //写保护错误返回3

return 0; //非忙碌状态且无任何错误时,返回0,或者说可以读写操作的话返回0

}

4、等待操作完成函数

u8 STMFLASH_WaitDone(u16 time)

{

u8 res;

do

{

res=STMFLASH_GetStatus();//读取FLASH状态是否处于忙碌状态

if(res!=1)break;//非忙碌状态则break

delay_us(1);

time--;

}while(time);

if(time==0)res=0xff;//TIMEOUT超时了,res等于0xff

return res;//操作完成返回0

}

5、擦除页

u8 STMFLASH_ErasePage(u32 paddr)

{

u8 res=0;

res=STMFLASH_WaitDone(0X5FFF);// 首先查看是否是忙碌状态,

if(res==0)//非忙碌状态可以操作

FLASH->CR|=1<<1;//选择页擦除

FLASH->AR=paddr;//擦除地址

FLASH->CR|=1<<6;//  擦除操作 

res=STMFLASH_WaitDone(0X5FFF);//是否操作完成

if(res!=1)//

{

FLASH->CR&=~(1<<1);//完成后,页擦除选择位清零

}

}

return res;

}

6、在指定位置写入半字

u8 STMFLASH_WriteHalfWord(u32 faddr, u16 dat)

{

u8 res;      

res=STMFLASH_WaitDone(0XFF);  

if(res==0)//OK,非忙碌状态下进入

{

FLASH->CR|=1<<0;//设置写操作

*(vu16*)faddr=dat;//向地址中写入数据

res=STMFLASH_WaitDone(0XFF);//等待操作完成

if(res!=1)//

{

FLASH->CR&=~(1<<0);//清零写操作位

}

return res;

7、读函数

u16 STMFLASH_ReadHalfWord(u32 faddr)

{

return *(vu16*)faddr; //返回指向该地址的内容

}

8、直接写入数据,不检查是否非法

void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   

{  

u16 i;

for(i=0;i

{

STMFLASH_WriteHalfWord(WriteAddr,pBuffer[i]);//将pBuffer的内容写入到WriteAddr地址中

   WriteAddr+=2;//因为写入了两个字节,相应的地址+2

}  

9、写数据到FLASH中,会检查地址等信息是否合法,以及长度等

void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)

{

u32 secpos;   //

u16 secoff;   //

u16 secremain; //

  u16 i;    

u32 offaddr;   //

if(WriteAddr=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//要写入的地址是否大于FLASH起始地址,并且不超过FLASH地址的总大小的地址,若果任何一个非法,那么就不执行下面的操作,直接return

STMFLASH_Unlock(); //解锁

offaddr=WriteAddr-STM32_FLASH_BASE; //计算地址偏移量,地址减去FLASH起始地址

secpos=offaddr/STM_SECTOR_SIZE; //将地址偏移量除以扇区大小,计算从第几个扇区开始写,每个扇区大小2K

secoff=(offaddr%STM_SECTOR_SIZE)/2; //在该扇区内,地址的偏移量,由于地址是+2增长的,所以除以2

secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小

if(NumToWrite<=secremain)secremain=NumToWrite;//要写入的数据长度是否大于该扇区剩余长度

while(1) 

{

STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读取该地址开始的整个扇区的数据

for(i=0;i

{

if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//查看扇区是否被擦除

}

if(i

{

STMFLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除该地址开始的一个页的空间

for(i=0;i

{

STMFLASH_BUF[i+secoff]=pBuffer[i];  //将要写入的数据写入到缓冲中 

}

STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//将缓冲中的数据写入该地址中

}else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//如果没必要擦除操作,那么直接写数据就好了   

if(NumToWrite==secremain)break;//完成了要写入的数据长度,则结束

else//如果要写入的数据比剩余空间大,那么执行以下操作

{

secpos++; //扇区地址+1,开始下一个扇区的写数据

secoff=0; //下个扇区的偏移量肯定是0

  pBuffer+=secremain;   //数据指向+secremain的数据地址,从这个地址开始读数据

WriteAddr+=secremain*2;//地址也相应的+数据大小*2,因为每个数据两个字节,对应两个地址   

  NumToWrite-=secremain; //要写入的长度减去之前的已经写入的secremain长度

if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//还是判断接下来要写入的长度,是否是大于整个扇区的大小,如果还是一个扇区还是不够,那么先写入一个扇区的长度

else secremain=NumToWrite;//如果不大于,那么直接将剩余长度写入即可

}  

};

STMFLASH_Lock();//操作结束后,锁定

}

10、从指定的地址读指定长度的数据

void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)  

{

u16 i;

for(i=0;i

{

pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取改地址数据

ReadAddr+=2;// 一次读取两字节的数据,因此地址要相应的+2

}

}

以上是根据正点原子迷你STM32开发板的历程做的解析,其实懂得了操作原理后,完全可以自己去写了。


关键字:STM32F103RCT6  FLASH  读写操作 引用地址:STM32F103RCT6之FLASH读写操作

上一篇:STM32ADC采样时间、采样周期、采样频率计算方法
下一篇:STM32F407之TF卡HAL库的使用

推荐阅读最新更新时间:2024-03-16 16:15

STM32内部flash分配
在Keil中编译工程成功后,在下面的Bulid Ouput窗口中会输出下面这样一段信息: Program Size: Code=6320 RO-data=4864 RW-data=44 ZI-data=1636 代表的意思: Code :是程序中代码所占字节大小 RO-data :程序中所定义的指令和常量大小 (个人理解 :Read Only) RW-data :程序中已初始化的变量大小 (个人理解”:Read/Write) ZI-Data :程序中未初始化的变量大小 (个人理解 :Zero Initialize) ROM(Flash) size = Code+RO-data+RW-data; RAM size = RW-data
[单片机]
兆易创新产能或影响NAND Flash价格
近期编码型存储器(Nor Flash)因市场需求不减,价格依旧持续维持高档。不过,目前大陆有新产能开出,加上新的解决方案应用,导致供需双方面都有变化的情况下,整体市场价格开始有松动倾向。 根据业界人士透露,近期 Nor Flash 价格松动,在供应面上,日前中芯国际拿出每月 1 万片的产能给兆易创新使用,用以生产 Nor Flash 后,武汉新芯也可能因 NAND Flash 量产进度落后,所以将部分闲置产能也拿出来提供兆易创新,使兆易创新有比较多产能影响市场价格。 另外,除了兆易创新陆续在中芯国际与武汉新芯投片,增加产能之外,另一家晶圆代工厂上海华力微,据传也开始拿出约每月万片产能,招揽 Nor Flash 厂商到上海华
[嵌入式]
xs128 D-Flash读写
#include includes.h uint16 Buffer ={0x1111,0x2222,0x3333,0x4444};//数据缓存区,只能一次写入四个数据 uint16 data_Address = 0x0000; uint16 date_read ; /*********************************************************** ** 名 称:void DFlash_Init(void) ** 功 能:DFlash初始化 ** 入口参数:无 ** 出口参数:无 ** 使用说明:无 ************************************
[单片机]
从Nand特性谈其烧录关键点
为什么烧录Nand Flash经常失败?为什么烧录成功了,一部分Nand芯片贴板之后系统却运行不起来? ,等等,问了那么多为什么,那我反问一个问题:你了解Nand Flash的特性及其烧录关键点吗? 一、Nand flash的特性 1、位翻转 在 NAND 闪存是通过对存储单元(Cell)进行充电来完成数据存储的,存储单元的阈值电压就对应着数据值。当读取的时候,通过将它的阈值电压与参考点对比来获得其数据值。对SLC 而言,就只有两种状态和一个参考点。而对于2-Bits 的MLC 而言,它有4 种状态和三个参考点。TLC就更多状态和参考点。当读出的数据值与编程时数据值对应的阈值电压不相匹配时,表明数据发生了位翻转,就带
[手机便携]
从Nand特性谈其烧录关键点
DSP+FLASH引导装载系统的设计与实现
摘要:介绍了利用DSP编程实现对FLASH的读写操作,设计并实现子一个引志装载系统的模型,给出了一个简单的测试用的实例。整个方案有较大的灵活性和实用性。 关键词:数字信号处理器 FLASH存储器 引导装载 在一些脱机运行的DSP系统中,用户代码需要在加电后自动装载运行。DSP系统的引导装载(Bootload)是指在系统加电时,DSP将一段存储在外部的非易失性存储器的代码移植到内部的高速存储器单元中去执行。这样既利用了外部的存储单元扩展DSP本身有限的ROM资源,又充分发挥了DSP内部资源的效能。尽管用户代码在一段时间相对是固定的,但是如果直接将其掩膜到内部ROM中去的话,一方面受容量以及价格的限制,另一方面则在系统代码级上显得
[嵌入式]
武林教你学PIC32(十七)SPI操作M25P16 FLASH存储器
首先介绍下TI 的 M25P16,它是 16Mbit(2Mbyte)的FLASH存储器,与常用的华邦公司的W25X16,ATMEL公司的AT51DB161比较接近。最高支持50M的SPI时钟,存储器可以以1到256字节byte,使用页编程操作将2M的容量分为32个块(Block),每个块含有256页,每页里有256字节宽带,因此整个存储器包含8192页或者2,097,152字节。操作命令为: 我们根据这些命令,做好下面封装函数: //需要外接函数 extern unsigned char SPI_FLASH_SendByte(unsigned char ch); extern unsigned char SPI_FLASH
[单片机]
武林教你学PIC32(十七)SPI<font color='red'>操作</font>M25P16 <font color='red'>FLASH</font>存储器
STM32F103RCT6的脉冲宽度调制(PWM)的输出设定
关键词:重映射 连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。 连接在APB2(高速外设)上的设备有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口、第二功能IO口。 注意:查看32 位基于 ARM 微控制器 STM32F101xx 与 与 STM32F103xx固件函数库 pwm.c文件: #include pwm.h //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM2_PWM_Init(u16 arr1,u1
[单片机]
<font color='red'>STM32F103RCT6</font>的脉冲宽度调制(PWM)的输出设定
NAND Flash市场规模 2012年将超越DRAM
    随着个人电脑(PC)市场萎缩及可携式产品的热卖,长久以来一直占据着记忆体市场销售最大宗的DRAM,可能在2012年首次被NAND Flash超越。     根据EETimes引用市调公司IC Insights报告指出,NAND Flash销售将在2012年达到328亿美元,较2011年成长11个百分点,相较之下DRAM销售却预计在同时期下滑3个百分点,来到303亿美元。该公司解释,智慧型手机、平板电脑、SSD等多种装置的兴起不断带动NAND Flash市场,在此同时,DRAM却面临价格崩盘的困境。     而同时间用于DRAM的资本支出也有逐年下滑的趋势,据了解,2010年资本支出占整体销售的11.3%,然到了2011年却
[手机便携]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved