STM32的FLASH 读取

stm32内部存储分为两种:RAM和ROM。

RAM:随机存储器。特点是 :1、可以随机访问空间内的某地址,并且速度快(通常和CPU通过总线交互),可以用来存放程序运算过程中产生的中间数据,即内存。2、掉电不能保存数据。
ROM:只读存储器。特点是:1、掉电可以保存数据。2、保存程序代码和const一类常量。

ROM中分为三部分:1、bootload(启动代码)、上电后最先执行此部分(主要用来检测系统基本情况如:晶振、电源等)。 2、存储区,用户编写的程序代码 (程序代码地址从0x08000000开始)。3、一些键值和flash管理寄存器。当系统复位后,程序指针首先指向0x08000000,即从此处开始执行程序。
大容量的芯片flash有512k。主存储区从0x08000000开始到0x08080000结束,将flash划分成128个区块,每个区块共2K字节。在这里插入图片描述
此处尝试在主存储区中代码部分之外的区域存放一些常量数据,并在程序中读取出来。如果没有特定的存储设备,但是还想存储一些程序中运行的量在掉电后不丢失的情况可以试试。

实际运行:
在这里插入图片描述
具体代码如下(库函数):
一些常量个用到的头文件

#include "usart.h"  //正点原子通用串口1配置
#include "sys.h" 	//正点原子通用系统配置
#include "delay.h"  //正点原子通用延时函数
#include "stm32f10x_flash.h" //官方flash操作库函数
#define  BASE_ADDR  0x08000000  //定义主存储区基地址
#define  SAVE_ADDR  0x08050000	//定义数据存放的地址
#define  sector_size  2048		//定义每个区的大小
#define  flash_size   512		//定义flash的大小
u8 buffer1[]={"this will been locaed flash"}; //要写入的数据,注意:字符串只能用u8类型的数据,后期要转换成32位。
u16  buffersize =sizeof(buffer1); //从flash中读取出来存放数据的缓存,串口将此地址中的值发送。
u8 buffer2[sizeof(buffer1)];   //定义数据大小

main函数很简单,做一些初始化和串口准备工作。
此处关于flash的读写就俩函数(已经标注)。
正点原子源码中操作读写半字(16位)。此处读写一个字(32位)。

int main()
{
    u16 i;
    delay_init();
    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);
    uart_init(4800);
    
    write_to_falsh(SAVE_ADDR,(u32 *) buffer1, buffersize); //写入flash
    read_from_flash(SAVE_ADDR,(u32*) buffer2,buffersize);  //从flash中读取
            while(1)
            {
              for(i=0;i<buffersize;i++)
              {
                USART_SendData( USART1, buffer2[i]); 
                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
                    }
            }

}

主要看下面两个读写函数:
从flash中地址为addr的地方读取num个数据存放到buff中

void read_from_flash(u32 addr,u32* buff,u16 num)
{
    u16 i;
    for(i=0;i<num;i++)
    {
        buff[i]=* addr; 
        addr+=4;  //每次读取32位数据,共4个字节。下次读取4个字节后的地址
    }
}

下面是写入flash

u8  write_to_falsh(u32 addr,u32* buf,u16 num)
{
    u16 i;
    u32  off_addr=addr-BASE_ADDR;   //基地址的偏移地址
    u32  sector_addr= off_addr/sector_size;  //扇区地址  
    u32  sector_off = off_addr%sector_size;  //扇区内偏移地址
    u32  secremain=sector_size-sector_addr;  //剩余量
    if(addr<BASE_ADDR||addr>BASE_ADDR+1024*flash_size) return  0;  //如果需要操作的地址超出主存储区,则视为非法地址,结束程序。
    
    FLASH_Unlock();  //解锁,向两个KEY中写入键值,类似于开锁,用来保护flash防止误操作。
     FLASH_ErasePage(sector_addr*sector_size+BASE_ADDR);  //擦除整扇区,flash写入之前一定要检查该扇区是否被擦除,只有被擦了才能写入,库里有两种擦除,一种是擦除一个区,一种是擦除整页。
    
    for(i=0;i<num;i++)
        {
            FLASH_ProgramWord(addr, (u32)buf[i]);  //写一个字
            addr+=4;   //每次写入32位数据,共4个字节。下次写到4个字节后的地址
        }
   
    FLASH_Lock();//上锁,向两个KEY中写入键值,类似于开锁,用来保护flash防止误操作。
   return 1;
}
  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值