历史上的今天
返回首页

历史上的今天

今天是:2025年07月26日(星期六)

正在发生

2019年07月26日 | 读写stm32的内置Flash(附代码)

2019-07-26 来源:eefocus

最近尝试了一下对32的内置flash进行读写,众所周知,芯片的flash是用来存放代码指令和变量的,其中的数据即使掉电也不会丢失。而stm32的flash之大,对于初学者的小打小闹完全不用担心不够用的情况。


因此,在需要保存一些芯片掉电之后依旧需要保存的数据(数据量不是特别大)时,运用内置flash的空闲部分可以为我们省去一颗eeprom或外置flash的花销。


知识总结:

1.flash的写入之前需要先擦除,且擦除是直接擦除一页(2KBytes),整个流程为


(1)解锁flash(2)擦除一页或多页(3)写数据(4)锁定flash


2.flash正常写入一次是16bit


3.flash的地址从0x08000000开始,存储代码指令与变量。所以在用户自己写flash时,要注意不要把代码指令与变量给覆盖了。查看编译过的代码使用了多少内存,可在Keil中双击工程名查看*.map文件


基地址加上Size就是代码指令与变量占用的空间。在写入用户数据时,要避开这些地方。


以下是基于正点原子库函数的flash读写代码。在STM32F103RCT6测试通过。可以直接复制使用,好用请为博客点个赞!


flash.h:


#ifndef _FLASH_H

#define _FLASH_H

 

#include "stm32f10x.h"

 

extern uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress);

extern void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress);

 

#endif

 

flash.c


/////////////////////////////////////////

//Author: Read Air

//Version: 1.0

//Date:2019/4/18

/////////////////////////////////////////

 

#include "flash.h"

#include "stm32f10x.h"

///////////////////////////////////////////////////////

//WRITE_START_ADDR -- 开始写的地址

//SizeOf_u32 -- 要写入的32位(双字)的数量

//DataAddress -- 等待被写入的数据数组(32位的)

//返回值 -- 出现擦除失败故障返回写入地址,正常返回0

///////////////////////////////////////////////////////

uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress)

{

char EraseCounter = 0;

static FLASH_Status FLASHStatus;

uint32_t Address;

u16 Remain_u32 = SizeOf_u32;

u8 err_time=0;

/* 解锁 */

FLASH_Unlock();

/* 清空所有标志位 */

FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

/* 擦除一页*/

FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR);

/* 尝试擦除*/

while((FLASHStatus != FLASH_COMPLETE)&&(err_time<5))

{

FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR);

err_time++;

}

/* 擦除失败*/

if (err_time >= 5) return WRITE_START_ADDR;

/* 向内部 FLASH 写入数据 */

Address = WRITE_START_ADDR;

while ((Remain_u32 > 0) && (FLASHStatus == FLASH_COMPLETE)) 

{

FLASHStatus = FLASH_ProgramWord(Address, DataAddress[SizeOf_u32-Remain_u32]);

Address = Address + 4;

Remain_u32--;

}

/* 锁定*/

FLASH_Lock();

return 0;

}

 

///////////////////////////////////////////////////////

//READ_START_ADDR -- 开始写的地址

//SizeOf_u32 -- 要读出的32位(双字)的数量

//DataAddress -- 等待被读出的数据数组(32位的)

///////////////////////////////////////////////////////

void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress)

{

uint32_t Address;

u16 Remain_u32 = SizeOf_u32;

/* 检查写入的数据是否正确 */

Address = READ_START_ADDR;

while ((Remain_u32 > 0)) 

{

DataAddress[SizeOf_u32-Remain_u32] = (*(__IO uint32_t*) Address);

Address += 4;

Remain_u32--;

}

}

 

//注意事项: 

//1、对flash进行写入操作,一定要遵循“先擦除,后写入”的原则 

//2、注意到stm32内置flash的擦除操作都是以页为单位进行,而写入操作则必须以16位半字宽度数据为单位,允许跨页写,尝试写入非16位半字数据将导致stm32内部总线错误。 

//3、进行stm32的内置flash编程操作时(写或擦除),必须打开内部的RC振荡器(HSI) 

//4、注意stm32的内置flash最多只有10万次重复擦写的生命周期,谨记切勿在程序中放任死循环对flash进行持续地重复擦写。



推荐阅读

史海拾趣

Fong Ya Enterprise Co Ltd公司的发展小趣事

Fong Ya Enterprise Co., Ltd在电子行业中的发展故事

故事一:初创与基础奠定

Fong Ya Enterprise Co., Ltd(以下简称“丰雅企业”)成立于某个时期(具体年份可能因资料限制而未知),自那时起便致力于电子元件领域,特别是电阻器的研发与生产。初期,公司面临着市场竞争激烈、技术壁垒高等挑战,但凭借对电子技术的深刻理解和对市场需求的敏锐洞察,丰雅企业逐步确立了自身的产品定位,即专注于高品质、高性能的电阻器产品。通过不断优化生产工艺和提升产品质量,丰雅企业在电子行业逐渐站稳了脚跟。

故事二:技术创新与产品研发

随着电子行业的快速发展,丰雅企业深刻认识到技术创新的重要性。公司加大了对研发的投入,引进了一批高素质的技术人才,并建立了完善的研发体系。通过不断的技术创新,丰雅企业成功开发出了一系列具有自主知识产权的新型电阻器产品,这些产品不仅性能优越,而且满足了市场对电子元器件日益多样化的需求。同时,公司还积极与国内外知名高校和科研机构开展合作,共同推动电子元件技术的进步。

故事三:市场拓展与国际化战略

在稳固国内市场的同时,丰雅企业积极实施国际化战略,将目光投向了更广阔的国际市场。公司参加了多个国际性的电子展会,与全球各地的客户建立了良好的合作关系。通过提供优质的产品和服务,丰雅企业在国际市场上赢得了良好的口碑和信誉。此外,公司还根据不同国家和地区的市场特点,制定了差异化的营销策略,进一步扩大了市场份额。

故事四:供应链管理优化

为了提高生产效率和降低成本,丰雅企业不断优化供应链管理。公司与多家优质供应商建立了长期稳定的合作关系,确保原材料的质量和供应的稳定性。同时,公司还引入了先进的供应链管理系统,实现了对生产、采购、库存等各个环节的精细化管理。通过优化供应链管理,丰雅企业不仅提高了生产效率,还降低了运营成本,为企业的可持续发展奠定了坚实的基础。

故事五:品牌建设与企业文化

在多年的发展过程中,丰雅企业始终注重品牌建设和企业文化建设。公司坚持“质量第一、客户至上”的经营理念,致力于为客户提供优质的产品和服务。同时,公司还注重培养员工的创新精神和团队协作精神,营造了积极向上的企业文化氛围。通过品牌建设和企业文化的推动,丰雅企业在电子行业中的知名度和影响力不断提升,为企业的长远发展注入了强大的动力。

需要注意的是,由于具体年份和详细数据的限制,以上故事在描述时可能存在一定的概括性。然而,这些故事都基于丰雅企业在电子行业中的实际发展情况而构建,旨在展现其在技术创新、市场拓展、供应链管理和品牌建设等方面的努力和成就。

DC Components公司的发展小趣事

DC Components公司成立于1992年,总部位于台湾台中市。公司自创立之初,就专注于二极管桥式整流器的研发与生产。在创立初期,公司面临着资金、技术和市场的诸多挑战。然而,凭借对技术的执着追求和对市场的敏锐洞察,DC Components公司逐渐在二极管桥式整流器领域树立了专业形象,为未来的发展奠定了坚实基础。

电连(ECT)公司的发展小趣事

为了进一步扩大市场份额,ECT积极推进国际化战略。截止2022年初,公司在全球共设立23个分支机构,覆盖了中国台湾、中国香港、韩国、日本、泰国、越南、美国等国家和地区。通过国际化战略的实施,ECT不仅成功将产品推向全球市场,也提升了公司的国际影响力和竞争力。

DDP Engineered LED Solutions公司的发展小趣事

DDP Engineered LED Solutions公司自创立之初,便以技术创新作为公司发展的核心动力。在公司成立的早期,研发团队深入LED照明领域,通过不断实验和改进,成功开发出了一系列高效、稳定的LED照明产品。这些产品不仅具有出色的照明效果,而且具有较长的使用寿命和较低的能耗,迅速在市场上获得了认可。随着技术的不断迭代,DDP不断推出符合市场需求的创新产品,逐渐在电子行业LED照明领域崭露头角。

柯爱亚(ceaiya)公司的发展小趣事

作为一家有社会责任感的企业,柯爱亚积极参与各种公益活动。公司不仅捐款捐物支持灾区重建、教育事业等公益事业,还组织员工参与志愿者活动,为社会做出了积极贡献。这些行为展现了柯爱亚作为一家优秀企业的社会担当和良好形象。

请注意,以上故事框架仅供参考,具体内容需要根据柯爱亚公司的实际发展历程进行编写。

DAYA公司的发展小趣事

大雅智能深知,品质是企业立足之本。因此,在产品研发和生产过程中,大雅智能始终坚持严格的质量控制标准,确保每一台产品都符合高品质要求。同时,大雅智能还建立了完善的售后服务体系,为用户提供及时、专业的技术支持和维修服务。正是这份对品质的执着追求,让大雅智能在消费者中赢得了良好的口碑。

问答坊 | AI 解惑

高性能模/数转换器AD6645及其应用

豪华的单片机开发系统498元 可稳定视频输出的: S3C2410 ARM9开发板780元DSP5402学习开发板II200元 暑期大优惠:S3C44B0开发板(标准版)350元 单片机以太网开发板  180元 DSP5402学习开发板II200元 LABTOOL-48UXP &nb ...…

查看全部问答>

LINUX

电子教案,需要的快下哦…

查看全部问答>

PCB布线的几点经验

1、输入端与输出端的边线应避免相邻平行, 以免产生反射干扰。必要时应加地线隔离;两相邻层的布线要互相垂直,平行容易产生寄生耦合。 2、地线>电源线>信号线,通常信号线宽为:8mil~12mil;电源线为50mil~100mil。对数字电路 ...…

查看全部问答>

EVC中是不是不支持settimer的SLIDER_TIMER参数??

EVC中是不是不支持settimer的SLIDER_TIMER参数??         mSliderTimer = SetTimer(SLIDER_TIMER, 100, NULL); 报错是:error C2065: \'SLIDER_TIMER\' : undeclared identifier…

查看全部问答>

EVC环境下为什么delete对象无法释放内存

我写了一个很简单的程序,窗口上就两个按钮,用于动态分配和释放内存.打开WinCE.net的SystemProperties的Memory选项卡查看内存情况,发现分配可以,但按了释放内存的按钮却不能释放内存,不知原因,望高手指点!…

查看全部问答>

注册公司的步骤

注册公司的步骤一、选择公司的形式: 普通的有限责任公司,最低注册资金3万元,需要2个或2个以上的股东, 从06年1月起新的公司法规定,允许1个股东注册有限责任公司,这种特殊的有限责任公司又称“一人有限公司”(但公司名称中不会有“一人”字 ...…

查看全部问答>

ADI实验室电路DIY项目指南

报名参与:『ADI实验室电路DIY大赛』正式启动!https://bbs.eeworld.com.cn/thread-293726-1-1.html ADI实验室电路品种繁多,涉及面很广,如何选择合适的DIY项目可能是件容易令人困扰的事,但深究起来,其实可玩性是很大的,从今天开始,我将陆续 ...…

查看全部问答>

大家帮看看为什么DeviceIoControl访问OID_802_11_BSSID_LIST老是失败

如题,下面一段程序中,DeviceIoControl访问OID_802_11_BSSID_LIST老是失败(见下面红色),也就是说bResult一直等于0;为什么?请教牛人!!!可能的问题出现在哪?为什么第二个DeviceIoControl失败?#include \"stdafx.h\"#include <windows.h ...…

查看全部问答>

介绍java的接口和原理

       卓跃教育发现随着采用Android系统的谷歌手机、平板电脑等产品逐渐扩大市场占有率,Android平台人才的缺口日益显现。据业内统计,目前国内的3G研发人才缺口有三、四百万,其中Android研发人才缺口至少30万。&n ...…

查看全部问答>