STM32 对内部FLASH读写接口函数
因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序。
原理:先要把整页FLASH的内容搬到RAM中,然后在RAM中改动,然后擦除整页FLASH,再把改动后的内容写入原Flash页。下面程序调试通过。
/*******************************************************************************
* Function Name : I2C_EE_BufferRead
* Description : Reads a block of data from the EEPROM.
* Input :
* -RomAddr
* -NumByteToRead
* -pRomData
* Output : None
* Return : None
*******************************************************************************
void I2C_EE_BufferRead(u16 RomAddr,u16 NumByteToRead,u8 *pRomData)
{
u32 param_flashbase;
u8* ptr;
param_flashbase = 0x8000000+(300+20)*1024;
ptr = (u8*)(param_flashbase + RomAddr);
while( NumByteToRead-- >0)
{
*pRomData = *ptr; //直接赋值即可
printf("0x%x ",*pRomData);
pRomData++;
ptr++;
}
return;
}
/*******************************************************************************
* Function Name : I2C_EE_BufferWrite
* Description : Write a block of data to the EEPROM.
* Input :
* -RomAddr
* -NumByteToRead
* -pRomData
* Output : None
* Return : None
*******************************************************************************
void I2C_EE_BufferWrite(u8 DeviceType,u8 SlaveAddr,u16 RomAddr,u16 NumByteToWrite,u8 *pRomData)
{
uint32_t param_flashbase;
uint32_t tempaddress;
uint32_t startaddress;
uint32_t FlashAddress;
uint32_t datasource;
u8 buf1[PAGE_SIZE];
u8 buf2[PAGE_SIZE];
u32 pagenumber = 0x0;
u32 EraseCounter = 0x0;
u32 i = 0;
FLASH_Status FLASHStatus = FLASH_COMPLETE;
param_flashbase = 0x8000000+(300+20)*1024;
startaddress=tempaddress = param_flashbase+RomAddr;
/*********************起始指针不在Flash页的开始端*********************
if( (tempaddress%PAGE_SIZE) != 0)
{ printf("startptr not in Page head \r\n");
if( ((startaddress%PAGE_SIZE)+NumByteToWrite) > PAGE_SIZE ) /*超出一页范围
{
I2C_EE_BufferRead(0,0,(tempaddress-(tempaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*把起始地址所在页的内容读到内存buf1中
memcpy(buf1+(tempaddress % PAGE_SIZE),pRomData,PAGE_SIZE-(tempaddress % PAGE_SIZE)); /*把需要写入的数据覆盖到buf1中
while( FLASHStatus == FLASH_ErasePage(tempaddress) ) /*buf1写入到Flash
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
NumByteToWrite -= PAGE_SIZE-(startaddress % PAGE_SIZE); 需要写入字节数减去,上面覆盖上去的数据的字节数
tempaddress += PAGE_SIZE-(tempaddress % PAGE_SIZE); /*把ptr指针指向下一个页起始位置
if((NumByteToWrite % PAGE_SIZE) != 0) /*末指针不在Flash页的开始端
{
//读取1 PAGE 数据到内存,修改,然后写进去
I2C_EE_BufferRead(0,0,tempaddress,PAGE_SIZE,buf2);
memcpy(buf2,pRomData+PAGE_SIZE-startaddress%PAGE_SIZE+NumByteToWrite-NumByteToWrite%PAGE_SIZE,(NumByteToWrite%PAGE_SIZE));
while( FLASHStatus == FLASH_ErasePage( tempaddress+NumByteToWrite) ) /*把buf2写入到Flash中*
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf2;
FlashAddress = (tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)); /*末地址指针的页首
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
}
NumByteToWrite -= NumByteToWrite % PAGE_SIZE;
//擦除Flash
pagenumber = NumByteToWrite/PAGE_SIZE;
for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage( tempaddress + PAGE_SIZE*EraseCounter );
}
//写Flash
datasource = *(uint32_t *)(pRomData+ PAGE_SIZE-(startaddress % PAGE_SIZE) );
FlashAddress = tempaddress;
while( pagenumber-- > 0 )
{
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
}
else /*写的内容没有超出一页范围
{
printf("FlashWrire --in one page \r\n");
I2C_EE_BufferRead(0,0,(startaddress-(startaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*把起始地址所在页的内容读到内存buf1中
memcpy( (buf1+(tempaddress % PAGE_SIZE)),pRomData, NumByteToWrite ); /*把需要写入的数据覆盖到buf1中
while( FLASHStatus == FLASH_ErasePage(tempaddress) )
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource) /*读取Flash中的数据,看是否写入正确
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
}
}
/*******************起始指针在Flash页的开始端****************************
else
{ printf("startptr in Page head \r\n");
if((NumByteToWrite % PAGE_SIZE) != 0)
{
//读取1 PAGE 数据到内存,修改,然后写进去
I2C_EE_BufferRead(0,0,(u16)(tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)),PAGE_SIZE,buf1);
printf("already copy to bug1 \r\n");
memcpy(buf1,pRomData+NumByteToWrite-(NumByteToWrite % PAGE_SIZE),(NumByteToWrite % PAGE_SIZE));
//end of debug
}
//擦除Flash
if( (NumByteToWrite%PAGE_SIZE) == 0 )
{
pagenumber = NumByteToWrite/PAGE_SIZE;
}
else
{
pagenumber = NumByteToWrite/PAGE_SIZE + 1;
}
for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(startaddress + (PAGE_SIZE * EraseCounter));
}
//写Flash
if( pagenumber == 1) /*只有一页
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = startaddress;
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t *)datasource);
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource +=4;
FlashAddress +=4;
}
}
else /*很多页时,先写前面页,最后写buf1
{
while( pagenumber-- > 1 )
{
datasource = (u32)pRomData;
FlashAddress = startaddress;
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
//写后面的页
datasource = (uint32_t)buf1;
FlashAddress = startaddress+(pagenumber-1)*PAGE_SIZE;
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
}
}
STM32 对内部FLASH读写接口函数的更多相关文章
- STM32 对内部FLASH读写接口函数(转)
源:STM32 对内部FLASH读写接口函数 因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序. ...
- 【转】STM32擦除内部FLASH时间过长导致IWDG复位分析
@20119-01-29 [小记] STM32擦除内部FLASH时间过长导致IWDG复位分析
- stm32 Flash读写独立函数[库函数]
一. stm32的FLASH分为 1.主存储块:用于保存具体的程序代码和用户数据,主存储块是以页为单位划分的, 一页大小为1KB.范围为从地址0x08000000开始的128KB内. 2.信息块 ...
- [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写
一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...
- STM32 实现内部Flash的读写(HAL库版)
Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器.可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除.一个Nand Flash由多个块(Block ...
- 第50章 读写内部FLASH—零死角玩转STM32-F429系列
第50章 读写内部FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- STM32学习笔记:读写内部Flash(介绍+附代码)
一.介绍 首先我们需要了解一个内存映射: stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同. RAM起 ...
- STM32 内部flash的读写程序
/* Base address of the Flash sectors */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base ...
- stm32——Flash读写
stm32——Flash读写 一.Flash简介 通过对stm32内部的flash的读写可以实现对stm32的编程操作. stm32的内置可编程Flash在许多场合具有十分重要的意义.如其支持ICP( ...
随机推荐
- 05-树8 File Transfer
并查集 简单并查集:输入N,代表有编号为1.2.3……N电脑.下标从1开始.初始化为-1.合并后根为负数,负数代表根,其绝对值代表个数. We have a network of computers ...
- 编译android程序时DEX过程出现错误
今天编译高级设置时出现了错误,这好坑爹啊~ 于是我开始检查代码,发现代码没有错误啊,然后观察MAKE的步骤才发现是DEX时出现了问题!! 下面是错误的LOG: Information:Using ja ...
- C 基于UDP实现一个简易的聊天室
引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...
- 为了android sdk下载,必须修改hosts
#Download 下载 203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.com #Groups 203.208.46.146 gr ...
- Java入门到精通——基础篇之static关键字
一.概述 static 关键字是声明静态变量,静态方法用的.static的含义是属于类且不属于类对象的变量和函数. 二.static的产生. 在创建对象的时候除非用new ...
- struts2框架基本操作总结
struts技术说明 一:第一配置开发环境 1.struts.xml文件 <?xml version="1.0" encoding="UTF-8" ?&g ...
- db2查询锁表
--查询锁表情况,可以获取哪个表被锁,其中agent_id为哪个DB2进程锁了表(db2inst1用户下) select * from sysibmadm.LOCKS_HELD with ur; -- ...
- meteor 安装 android sdk慢的改进方法
网上方法很多,最后总结一下比较靠谱的一个,到~/.meteor/android_bundle/ 目录下, 执行tools/android,手动下载 API 19 和 intel X86 Atom Sy ...
- iOS学习之C语言数组
一.一维数组 数组:具有相同类型的成员组成的一组数据 1.定义 元素:数组中存放的数据成为数组的元素 数组是构造类型 用{}来给构造类型赋初始值 类型修 ...
- webservice soapclient报错Error fetching http headers
设置: ini_set('default_socket_timeout', 600); // or whatever new value you want 参考:http://stackoverflo ...