stm32 利用Flash进行储存数据

来源:互联网 发布:文华财经交易模型源码 编辑:程序博客网 时间:2024/06/06 03:42

由于Flash具有擦写速度快,读取方便,掉电不丢失等优点,在工程项目中,常常开辟一块儿数据来存放各个传感器的数据!


在stm32中,无需对于flash进行特别的初始化,但是还是先要去掉写保护,在写这个程序遇到的最大问题是无法进行debug,因为根本就看不到数据,最后只能使用串口发送数据来进行调试抓狂 


需要注意的是

stm32只能一字(u32)或者半字(u16)输入,且利用flash写入时,其实地址必须为偶数,为奇数无法继续执行

擦除只能是全擦除或者单页擦除

用的是stm32F103VE,下面是调试过的代码

bsp_storge.h

#ifndef _BSP_STORAGE_H#define _BSP_STORAGE_H #include "stm32f10x_flash.h"#include"stdint.h"#include "bsp_usart.h"#define Sector_DataSize    256uint32_t  MonthData_TempAddr=(uint32_t)0x0807f700;  // 地址计数指针uint32_t  MonthDataStaAddr=(uint32_t)0x08032000;//当前月扇区起始地址uint32_t  MonthDataEndAddr=(uint32_t)0x0807f800;// 当前月扇区终止地址static FLASH_Status PutDataIntoFlash(uint32_t Address1,uint8_t *buf,uint32_t len);void ReadFromFlash(uint32_t Addr,uint8_t *buf,uint32_t len);FLASH_Status  WriteToFlash(uint32_t TempAddr,uint8_t *RomData,uint32_t len,uint32_t DataStaAddr,uint32_t DataEndAddr);void flashtext(void) ;#endif /*_BSP_STORAGE_H   */


bsp_storage.c

#include "bsp_storage.h"#define PageSize  2048//#define MonthDataStaAddr   ((uint32_t)0x08032000)  //sector:100//#define MonthDataEndAddr   ((uint32_t)0x08039FFF)  //sector:115 end//#define LastMonthDataStaAddr   ((uint32_t)0x0803A000)//sector:116//#define LastMonthDataEndAddr ((uint32_t)0x08041FFF)//sector:131end////#define BeforeLastMonthDataStaAddr((uint32_t)0x08042000) //sector:132//#define BeforeLastMonthDataStaAddr((uint32_t)0x0804AFFF) //sector:149end/****************************************************************************************************\Function      PutDataIntoFlash(uint32_t Address1,uint8_t *buf,uint8_t len)*\Description   将数据放入到flash中*\Parameter     uint32_t Address1*\Parameter     uint8_t *buf*\Parameteruint8_t len*\Return        void*\Note          2014年7月19日  地址只能是偶数*\Log          PutDataIntoFlash(0x0807F800,aaa,5);*              ***************************************************************************************************/static FLASH_Status PutDataIntoFlash(uint32_t Address1,uint8_t *buf,uint32_t len){uint32_t i;uint16_t TempData16;// 十六位临时数据变量FLASH_Status status = FLASH_COMPLETE;if(len%2==0)     // 数据长度奇偶判断{for(i=0;i<len;)  {      TempData16=(uint16_t)buf[i]; // 数据进行高低位置调换,人为的将大端模式转换为小端模式,便于数据的读取TempData16= TempData16|0xFF00;TempData16= ((((uint16_t)buf[i+1])<<8)|0x00FF)&TempData16; if(status == FLASH_COMPLETE){ status=FLASH_ProgramHalfWord(Address1,TempData16);Address1+=2;  }else {    break;   }i=i+2;}  }else{for(i=0;i<len;)  {TempData16=(uint16_t)buf[i]; // 数据进行高低位置调换,人为的将大端模式转换为小端模式,便于数据的读取TempData16&=buf[i];   // 数据进行高低位置调换,人为的将大端模式转换为小端模式,便于数据的读取if(i+2<len)   // 数据长度为奇数的时候,将最后一位数据置为(00) {TempData16= TempData16|0xFF00;TempData16= ((((uint16_t)buf[i+1])<<8)|0x00FF)&TempData16;}elseTempData16&=0x00FF;  if(status == FLASH_COMPLETE){ status=FLASH_ProgramHalfWord(Address1,TempData16);Address1+=2;  }else {    break;   }i=i+2;}  }return status;}/****************************************************************************************************\Function      ReadFromFlash(uint32_t Addr,uint8_t *buf,uint32_t len)*\Description   读flash中特定位置的值*\Parameter     uint32_t Addr*\Parameter     uint8_t *buf*\Parameter     uint32_t len*\Return        void*\Note         2014年7月19日*\Log          ReadFromFlash(0x0807F800,buf,5);     ***************************************************************************************************/void ReadFromFlash(uint32_t Addr,uint8_t *buf,uint32_t len){ uint32_t address=Addr;      while(len--){*buf=*(uint32_t*)address;buf++;address++;  }return;}/****************************************************************************************************\Function      FLASH_Status  WriteToFlash(uint32_t TempAddr,uint8_t *RomData,uint32_t len,uint32_t DataStaAddr,uint32_t DataEndAddr)*\Description   将数据写入到Flash中 *\Parameter     uint32_t Addr   实际存入起始地址   全局变量写入*\Parameter     uint8_t *RomData   需要写入的数据*\Parameter     uint32_t len   数据长度*\Parameter     uint32_t DataStaAddr   扇区总数据起始地址*\Parameter     uint32_t DataEndAddr   扇区总数据结束地址*\Return        FLASH_Status *\Note         起始地址必须为偶数,且必须为256的倍数2014年7月20日*\Log          WriteToFlash(MonthData_TempAddr,buf,256,MonthDataStaAddr,MonthDataEndAddr);      ***************************************************************************************************/FLASH_Status  WriteToFlash(uint32_t TempAddr,uint8_t *RomData,uint32_t len,uint32_t DataStaAddr,uint32_t DataEndAddr){/*///////////////////////////////////////////////////数据长度 256字节  一页共8组数据 第一组数据            起始:0   终止 :255 第二组数据       起始:256 终止 :511 第三组数据      起始:512 终止 :767 第四组数据      起始:768 终止 :1023 .......                  .......... .......                  .......... 第八组数据起始:1792  终止 :2047 每组数据中: 起始20字节 : 标志使用码,当前储存数据组, 终止20字节 : ///////////////////////////////////////////////// */ FLASH_Status  status;uint32_t staAddr;    // 将要写入的扇区起始地址 uint32_t count;        // 对于扇区内的分组进行计数uint8_t  buf1[PageSize]={0};  uint32_t i,j; FLASH_Unlock();FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);staAddr=TempAddr-(TempAddr%PageSize); count=(TempAddr%PageSize)/Sector_DataSize;/* 读出*/ReadFromFlash(staAddr,buf1,PageSize);   // 从flash中读出当前页的值/*更改数据*/for(i=count*Sector_DataSize,j=0;i<count*Sector_DataSize+Sector_DataSize;i++,j++){  buf1[i]=RomData[j];  }/* 擦除整页 */status=FLASH_ErasePage(staAddr);/* 写回 */status=PutDataIntoFlash(staAddr,buf1,PageSize);MonthData_TempAddr=TempAddr+Sector_DataSize;  //  为下一次写入更新地址if(MonthData_TempAddr>=DataEndAddr)// DataEndAddr,DataStaAddr即使开始的时候定为全局变量,但仍旧无法传值,估计是因为写flash的原因,对于地址的传入还是用参数传入{MonthData_TempAddr=DataStaAddr; } FLASH_Lock();return  status;}/****************************************************************************************************\Function      flashtext(void)*\Description   flash测试函数*\Return        void*\Note         2014年7月21日*\Log               ***************************************************************************************************/void flashtext(void){//uint32_t temp3;//uint32_t Addr;//uint8_t aaa[5]={0x01,0x02,0x03,0x04,0x05};//uint8_t buf[7]={0};uint8_t buf[256]={0x01,0x02,0x03,0x04,0x05};//FlagStatus status=RESET;//status=FLASH_GetReadOutProtectionStatus();//Usart_Sendchar(USART2,0x12);//    WriteToFlash(0x08032000,buf,256);//WriteToFlash(0x08032100,buf,256);//WriteToFlash(0x08032200,buf,256);WriteToFlash(MonthData_TempAddr,buf,256,MonthDataStaAddr,MonthDataEndAddr);WriteToFlash(MonthData_TempAddr,buf,256,MonthDataStaAddr,MonthDataEndAddr);WriteToFlash(MonthData_TempAddr,buf,256,MonthDataStaAddr,MonthDataEndAddr);// WriteToFlash(MonthData_TempAddr,buf,256);//WriteToFlash(MonthData_TempAddr,buf,256);//FLASH_ErasePage(0x0807F800); ///PutDataIntoFlash(0x0807F800,aaa,5);//ReadFromFlash(0x0807F800,buf,5);//NumDisplayOnLCD(buf,5);//  FLASH_ProgramHalfWord(0x0807F800,0x0123);while(1);//      //Addr=*(__IO uint16_t *) (((uint32_t)0x0807F801));// Usart_Sendchar(USART2,(uint8_t)Addr); //Addr=(uint32_t)0x0801FC00;//temp3=*(__IO uint32_t*)Addr;}




0 0
原创粉丝点击