首页| 行业标准| 论文文档| 电子资料| 图纸模型
购买积分 购买会员 激活码充值

您现在的位置是:团子下载站 > 其他 > 博客分享:单片机内部FLASH的字节操作

博客分享:单片机内部FLASH的字节操作

  • 资源大小:327.5KB
  • 上传时间:2021-07-25
  • 下载次数:0次
  • 浏览次数:65次
  • 资源积分:1积分
  • 标      签: FlaSh 单片机

资 源 简 介

一般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"#defineUSER_FLASH_START_ADDR0x01070000//FLASH最后两个扇区供用户使用u32tou8u32data;//定义一个联合体//==================================================================================//获取某个地址所在的页首地址//addr:FLASH地址//返回:该地址所在的页共128页(0~127)//==================================================================================unsignedintFLASH_GetFlashPage(unsignedintaddr){if(IS_FLASH_ADDRESS(addr)){return(addr&(~0xFFF));//清0低12位就是该页的起始地址}}//==================================================================================//从FLASH中读取一个字(32位)//addr:读取地址//返回:读到的字数据//备注:地址为4字节对齐//==================================================================================unsignedintFLSAH_ReadWord(unsignedintaddr){return(*(unsignedint*)addr);}//==================================================================================//从FLASH指定地址读取数据//备注:读取数据类型为32位读取地址为4字节对齐//==================================================================================voidFLASH_Read(unsignedintReadAddr,unsignedchar*pBuffer,unsignedintNumToRead){unsignedinTI;u32tobytecache;for(i=0;iRO=0;//去掉所有扇区写保护//==================================================================================//判断写入地址是否非法起始地址或者结束地址不在FALSH范围内则退出//==================================================================================if(!(IS_FLASH_ADDRESS(startaddr)&&IS_FLASH_ADDRESS(endaddr)))returnFLASH_ERROR_PG;while(startaddrremain)//需要写入的数据量大于缓冲buf剩余字节数{for(i=index;i<4096;i++)//将需要写入FALSH的数据写入缓冲buff { buffer[i]=*(pBuffer++); } NumToWrite-=remain;//需要写入的数据长度-本次已经写入的数据长度 startaddr+=remain;//地址向后偏移本次写入的字节数 } else { for(i=index;i其中还有个联合体的定义:typedefunion{unsignedintdata;unsignedcharbuf[4];}u32tou8;FLASH_ErasePage、FLASH_ProgramWord、IS_FLASH_ADDRESS这三个都是单片机FLASH的库函数各家单片机不同,但功能基本相同,这里不再提供源码。最后提供以下两个FLASH接口即可:FLASH_Write(unsignedintWriteAddr,unsignedchar*pBuffer,unsignedintNumToWrite);FLASH_Read(unsignedintReadAddr,unsignedchar*pBuffer,unsignedintNumToRead)演示:1.为方便查看结果,测试从0x1070FFC的位置开始写入数据,FLASH地址分布如下图所示:这里展示了FLASH连续两页的地址,首先将这两页全部擦除。2.接着从1070FFC的位置开始写入56个1,这样就保证了数据跨越了1页。unsignedcharwrite[]={"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111"};FLASH_Write(0x01070FFC,write,sizeof(write));注意:最后的00是因为字符串的结尾字符是“/0”3.紧接着,在0x1070FFE位置写入新的字符串,也要保证写入长度跨越1页。unsignedcharwrite2[]={"23456789"};FLASH_Write(0x01070FFE,write2,sizeof(write2));可以看出,0x1070FFE~0x1071006的位置被写入了新的字节,但这两页的其他位置数据保持不变。总结:1、实际使用时,如果不是受限于成本或者FLASH大小,不建议这样读写内部FLASH,以为stm32内部FLASH也就10W次寿命,这样频繁擦写会大大降低FLASH寿命。2、如果保存的数据不多,建议每个数据都单独存1页,这样不用考虑擦除时会把其他数据也一并擦除。版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/qq_24835087/article/details/103541322
VIP VIP