STM32内部FLASH打包读写

阅读: 评论:0

STM32内部FLASH打包读写
最近做到的项⽬在运⾏需要把⼀组uint8_t(unsigned char)的数据进⾏掉电储存,想到单⽚机STM32f030f4p6内部flash可以直接由程序操作,写了以下代码⽤于uint8_t数据打包保存和读取。
1、程序清单与测试结果
本程序包含5个⽂件,分别是:
1、Flash.c:内部flash读取储存相关函数
2、Flash.h:flash头⽂件
3、USART1.c:STM32F030F4P6的串⼝驱动,串⼝仅⽤于打印数据观察。
4、USART1.h:串⼝头⽂件
5、main.c:防⽌程序主⼊⼝
1、Flash.c
View Code
2、Flash.h
View Code
3、USART1.c
View Code
4、USART1.h
View Code
5、main.c
View Code
测试结果:
第54-199省略..
2、程序详解
2.1、内存结构:
STM32F0xx的flash结构如下:最多具有64页,每页1KByte⼤⼩。
我使⽤的STM32F030F4P6 flash区域有16K,所以实际上只有0-15页,本程序中把需要保存的数据数据存放在最后⼀页(第15页)中。
2.2、定义数据包结构
为了保证储存和读出flash的数据是正确的,本程序将写⼊flash数据分为3个区域
1. 报头区:写⼊数据的时候,将第15页的第1、2字节写⼊0xaa55,在读出的时候如果此位置不是0xaa55,则表⽰这段数据数据⽆效,不
是由⾃⼰存⼊的数据或者程序出现了异常;
2. 长度:写⼊数据的时候,第15页的第3、4字节写⼊有效数据的长度,读出这个字段,就知道上次⾃⼰⼀共存⼊了多少数据;
3. 数据段:从第15页的第5字节开始,全部字节(1020byte)⽤于储存uint8_t类型的数据;
2.3、写操作
写操作有如下步骤:
保护:由于我们只有1Kbyte空间,出去4个字节的报头和长度,实际只能存储1020个u8类型,写太多返回失败。
解flash锁
页擦除
写⼊数据包
上锁
/*******************************************************************************
* Function Name  : Flash_eeprom_WriteWithPacked
* Description    : Write a group of datas to flash.
* Input          : buff:pointer of first data, length: write length
* Output        :
* Return        : true/false
*******************************************************************************/
bool writeMessageToFlash( uint8_t *buff , uint16_t length)
{
uint16_t temp;
int i;
/*Protection*/
if( (length+4) > STM32F0xx_PAGE_SIZE )
{
return false;
}
FLASH_Unlock(  );
/*Clear all flags*/
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR );
/*Erase first . Do not rember.*/
if(FLASH_COMPLETE != FLASH_ErasePage(STM32F0xx_FLASH_PAGE15_STARTADDR))//°üº¬Á˵ȴýbusy
{
return false;
}
/*Write head*/
FLASH_ProgramHalfWord( STM32F0xx_FLASH_PAGE15_STARTADDR, EEPPROM_PACKAGEHEAD );
/*Write length*/
FLASH_ProgramHalfWord( STM32F0xx_FLASH_PAGE15_STARTADDR+2 , length );
/*Write datas*/
for(i=0 ;i<length/2 ;i++)
{
temp = buff[2*i]|(uint16_t)buff[2*i+1]<<8;
FLASH_ProgramHalfWord( STM32F0xx_FLASH_PAGE15_STARTADDR+4+2*i , temp);
}
if( isItOddNumber(length) )//Write one more if length is odd number.
{
temp = (uint16_t)buff[length-1];
FLASH_ProgramHalfWord( STM32F0xx_FLASH_PAGE15_STARTADDR+4+(length-1) , temp);
}
/*Read out and check*/
for(i=0 ;i<length ;i++)
{
if( *(uint8_t*)(STM32F0xx_FLASH_PAGE15_STARTADDR+4+i) != buff[i] )
{
FLASH_Lock();
return false;
}
}
FLASH_Lock();
return true;
}
2.3.1、解锁操作:
⽤户⼿册描述如下:
在(芯⽚)重置过后,为了防⽌多余的擦写操作flash会被保护。除了OBL_LAUNCH位⽤于重载option
bit,FLASH_CR寄存器的其他部分都不可以访问。
需要把以下两个解锁序列写⼊FLASH_KEY寄存器,才能访问FLASH_CR:
0x45670123
0xCDEF89AB
检索官⽅库定位FLASH_Unlock()这个函数,它的底层实现与⽂档描述相符,另外增加了防⽌重复解锁的操作,直接使⽤FLASH_Unlock()这个函数即可以完成解锁。
2.3.2、页擦除
⽤户⼿册描述如下:
1、通过检查FLASH_SR寄存器的BSY位来确认flash没有使⽤
2、把FLASH_CR寄存器的PER位置SET
3、通过编写FLASH_AR寄存器来确认要擦除的页
4、将FLASH_CR寄存器的STRT位置SET
5、等待BSY位rst
6、检查FLASH_SR寄存器中的EOP标记(成功会置SET)(流程图没有、库函数没检查)
7、清除EOP标记(流程图没有、库函数没清除)
检索官⽅库定位到FLASH_ErasePage(uint32_t Page_Address)这个函数,它的底层实现与⽂档流程图描述相符,值得注意的是,⼿册描述中6、7步并没有出现在⼿册的流程图和库函数中(库版本V1.2.0)。但在使⽤中没有出现问题,这⾥先记录看以后使⽤中会不会出现问题
2.3.3、往flash中写⼊数据
⽤户⼿册描述如下
  1、通过检查FLASH_SR寄存器的BSY位来确认flash没有使⽤
  2、设置FLASH_CR寄存器的PG位
  3、在⽬标地址上写⼊半个word的数据
  4、等BSY位reset
  5、检查FLASH_SR寄存器的EOP标记(SET表⽰成功)(流程图没有出现、库函数中没检查)
检索官⽅库定位到FLASH_ErasePage(uint32_t Page_Address)这个函数,它的底层实现与⽂档流程图描述相符,同样地,库函数没有检查第五步的EOP标记
2.3.4、上锁操作
根据⼿册提⽰,定位到库函数void FLASH_Lock(void)。只要置位LOCK位就上锁了。
2.4、读操作
程序如下
/*******************************************************************************
* Function Name  : readPackedMessageFromFlash
* Description    : Read packed message form flash
* Input          : buff:point to first location of received buffer.length:Maxmum length of reception
* Output        :
* Return        : reception length
*******************************************************************************/
uint16_t readPackedMessageFromFlash( uint8_t *buff , uint16_t length)
{
int i;

本文发布于:2023-05-06 11:16:54,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/3/89610.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   寄存器   没有   流程图   字节
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图