0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何让内部FLASH“支持”字节操作

电子设计 来源:电子设计 作者:电子设计 2022-02-10 11:09 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一般32位单片机的内部FALSH是不支持字节操作的,有的可以按字节读取,但是不能按字节写入。

而且,一般单片机内部FALSH擦除的最小单位都是页,如果向某页中的某个位置写入数据,恰好这个位置的前面存了其他数据,那么就必须把这页擦除,存的其他数据也会丢失。

实际上就是说内部的FALSH不好做改写的操作,如果有很多数据需要存放,最好是分页存储。这也是FALSH与E2PROM最大的区别,后者支持按字节操作且无需擦除,即使某一个地址写坏了,也不影响其他地址。

下面介绍一种方法让内部FLASH“支持”字节操作,且同一页的其他数据不受影响。

方法原理很简单,下面简单介绍下原理:

1.根据要写入地址,计算出该地址位于哪一页;

2.读出整个页,存入缓存BUF;

3.将要写入的数据按位置更新到BUF中;

4.擦除该页;

5.写入整个BUF。

可以看出这种方法弊端很明显:

1.耗时长 每次写都要读整个BUF,然后还要先把数据存到BUF里,然后再写入整个BUF;

2.FALSH擦写次数增加,降低使用寿命;

下面给出测试代码:

#include

#include

#include //C语言标准库

#include “flash.h”

#define USER_FLASH_START_ADDR 0x01070000 //FLASH最后两个扇区 供用户使用

u32tou8 u32data;//定义一个联合体

//==================================================================================

// 获取某个地址所在的页首地址

// addr:FLASH地址

// 返回:该地址所在的页 共128页(0~127)

//==================================================================================

unsigned int FLASH_GetFlashPage(unsigned int addr)

{

if (IS_FLASH_ADDRESS(addr))

{

return (addr&(~0xFFF));//清0低12位就是该页的起始地址

}

}

//==================================================================================

// 从FLASH中读取 一个字(32位)

// addr:读取地址

// 返回: 读到的字数据

//备注: 地址为4字节对齐

//==================================================================================

unsigned int FLSAH_ReadWord(unsigned int addr)

{

return (*(unsigned int *)addr);

}

//==================================================================================

//从FLASH指定地址 读取数据

//备注: 读取数据类型为32位 读取地址为4字节对齐

//==================================================================================

void FLASH_Read(unsigned int ReadAddr,unsigned char *pBuffer,unsigned int NumToRead)

{

unsigned int i;

u32tobyte cache;

for(i=0; iRO = 0;//去掉所有扇区写保护

//==================================================================================

// 判断写入地址是否非法 起始地址或者结束地址不在FALSH范围内则退出

//==================================================================================

if(!(IS_FLASH_ADDRESS(startaddr)&& IS_FLASH_ADDRESS(endaddr))) return FLASH_ERROR_PG;

while(startaddr remain)//需要写入的数据量大于缓冲buf剩余字节数

{

for(i=index;i《4096;i++)//将需要写入FALSH的数据写入缓冲buff

{

buffer[i]=*(pBuffer++);

}

NumToWrite-=remain;//需要写入的数据长度-本次已经写入的数据长度

startaddr+=remain;//地址向后偏移本次写入的字节数

}

else

{

for(i=index;i

其中还有个联合体的定义:typedef union

{

unsigned int data;

unsigned char buf[4];

}

u32tou8;FLASH_ErasePage、FLASH_ProgramWord、IS_FLASH_ADDRESS 这三个都是单片机FLASH的库函数各家单片机不同,但功能基本相同,这里不再提供源码。最后提供以下两个FLASH接口即可:FLASH_Write(unsigned int WriteAddr,unsigned char *pBuffer,unsigned int NumToWrite);

FLASH_Read(unsigned int ReadAddr,unsigned char *pBuffer,unsigned int NumToRead)演示:1.为方便查看结果,测试从0x1070FFC的位置开始写入数据,FLASH地址分布如下图所示:这里展示了FLASH连续两页的地址,首先将这两页全部擦除。

100059523-115019-1.jpg

100059523-115020-2.jpg

2.接着从1070FFC的位置开始写入56个1,这样就保证了数据跨越了1页。unsigned char write[]= {“1111111111111111111111111111111111111111111111111111111111111111111111111111111111111”};

FLASH_Write(0x01070FFC,write,sizeof(write));

100059523-115021-3.jpg

注意:最后的00是因为字符串的结尾字符是“/0”3.紧接着,在0x1070FFE位置写入新的字符串,也要保证写入长度跨越1页。unsigned char write2[]={“23456789”};

FLASH_Write(0x01070FFE,write2,sizeof(write2));

100059523-115022-4.jpg

可以看出,0x1070FFE~0x1071006的位置被写入了新的字节,但这两页的其他位置数据保持不变。总结:1、实际使用时,如果不是受限于成本或者FLASH大小,不建议这样读写内部FLASH,以为stm32内部FLASH也就10W次寿命,这样频繁擦写会大大降低FLASH寿命。2、如果保存的数据不多,建议每个数据都单独存1页,这样不用考虑擦除时会把其他数据也一并擦除。版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/qq_24835087/article/details/103541322审核编辑:何安

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6074

    文章

    45351

    浏览量

    663923
  • FlaSh
    +关注

    关注

    10

    文章

    1715

    浏览量

    154738
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32F030的FLASH存储器支持擦写PC页的保护功能

    CW32F030 的 FLASH 存储器支持擦写 PC 页保护功能。 当用户程序运行 FLASH 时,如果当前程序指针 PC 正好位于待擦写的 FLASH 地址页范围内,则该擦写
    发表于 12-11 07:38

    【原创】【RA4M2-SENSOR开发板评测】内部flash读写测试

    。 RA4M2 内部 Flash 相关的模块框图如下图所示 内部FLASH的写入过程 1.擦除先擦除 Block。 擦除操作将擦除所提供地址
    发表于 12-06 18:32

    CW32L052 FLASH存储器介绍

    概述CW32L052内部集成了64KB嵌入式FLASH供用户使用,可用来存储应用程序和用户数据。 芯片支持FLASH 存储器的读、擦除和写操作
    发表于 12-05 08:22

    单片机内部FLASH字节操作

    ); [*]} [*] [*] [*]//================================================================================== [*]//从FLASH指定地址 读取数据 [*]//备注: 读取数据类型为32位读取地址为4
    发表于 11-24 06:40

    智能显示模块支持掉电保存数据吗?智能模块支持操作Flash吗?

    智能显示模块支持掉电保存数据吗?智能模块支持操作Flash吗?
    发表于 11-14 08:41

    STM32C011开发(3)----Flash操作

    STM32C011 系列微控制器内置 Flash 存储器,支持程序存储与数据保存,具备页面擦除、双字写入、读写保护等功能。本文将简要介绍 STM32C011 的 Flash 结构与特性,并通过实际代码示例,讲解
    的头像 发表于 09-18 16:48 3701次阅读
    STM32C011开发(3)----<b class='flag-5'>Flash</b><b class='flag-5'>操作</b>

    请问STM32的内部Flash操作是不是优先级最高?

    STM32的内部Flash操作是不是优先级最高?目前在内部Flash的单独一页存储了数据,发现在进行页擦除的时候正常工作的定时器中断无法进入
    发表于 08-13 07:03

    hpm6364内部flash使用时的openocd配置问题.

    /yasuoHPM6000xilieMCUFlashshiyongzhinanyiruheshiyongpianneiFlash120231101151455.pdf)中提到使用内部flash时openocd 的脚本文件应改为如下: f
    发表于 07-12 19:48

    第二十九章 读写内部FLASH

    本文介绍了W55MH32内部FLASH,其含主存储、系统存储等,可存储代码及掉电保存数据。读写需解锁、擦除页等步骤,标准库提供相关函数。还展示了擦除编程测试及模拟EEPROM读写的实验。
    的头像 发表于 06-20 14:09 1009次阅读
    第二十九章 读写<b class='flag-5'>内部</b><b class='flag-5'>FLASH</b>

    如何通过SFL为设备添加Flash编程支持

    SEGGER Flash Loader(SFL)是J-Link设备支持套件(DSK)的一部分,通过SFL,用户可以为自己的新设备添加Flash编程支持
    的头像 发表于 05-19 16:35 1139次阅读
    如何通过SFL为设备添加<b class='flag-5'>Flash</b>编程<b class='flag-5'>支持</b>

    MCU片上Flash

    保留能力,支持多次擦写操作,是MCU程序存储的核心介质。 主要类型‌ NOR Flash‌:支持随机访问,可直接运行代码,适用于实时性要求高的场景。 NAND
    的头像 发表于 05-06 14:26 874次阅读

    调试时Memory窗口中Flash内容不更新的原因和解决办法

    调试时在代码中对Flash进行写操作时(比如Bootloader对Code Flash进行升级操作,Application对Data Flash
    的头像 发表于 04-01 09:18 992次阅读
    调试时Memory窗口中<b class='flag-5'>Flash</b>内容不更新的原因和解决办法

    存储技术探秘 NAND Flash vs NOR Flash:藏在芯片里的&quot;门道之争&quot;

    非易失存储:断电后数据不丢失 可重复编程:支持擦写操作(需先擦除后写入) 二进制操作:擦除后全为 1,写操作将 1 变为 0 核心差异 一、物理结构对比 NOR 特性 独立存储单元并
    的头像 发表于 03-18 12:06 1066次阅读

    cubeide的代码怎么编译到内部+外部FLASH里面去?

    我有一个项目,准备使用GUI和AI,准备使用STM32U5,但是编译出来的代码很多,STM32U5的内部FLASH不够用,准备使用OSPI扩展外部FLASH。但是遇到一个问题,我不知道怎么将编译
    发表于 03-07 07:48

    DLPDLCR4710EVM-G2是否可以在flash内部存储中设置投射的彩色图像?

    刚刚开始使用DLPDLCR4710EVM-G2,目前是用HDMI显示PC的屏幕的方式。 但是有什么办法设置flash内部存储中的彩色图像,光机自己运行投射相应光场? 谢谢
    发表于 02-20 07:40