stm32f407 内部flash保存数据

发布者:机械梦想家最新更新时间:2022-04-22 来源: eefocus关键字:stm32f407  内部flash  保存数据 手机看文章 扫描二维码
随时随地手机看文章

#include "stm32f4xx.h"

 

//FLASH起始地址

#define STM32_FLASH_BASE 0x08000000     //STM32 FLASH的起始地址

#define FLASH_SAVE_ADDR  0x080A0000    //保存地址

 

 

//FLASH 扇区的起始地址

#define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)     //扇区0起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_1     ((u32)0x08004000)     //扇区1起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_2     ((u32)0x08008000)     //扇区2起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_3     ((u32)0x0800C000)     //扇区3起始地址, 16 Kbytes  

#define ADDR_FLASH_SECTOR_4     ((u32)0x08010000)     //扇区4起始地址, 64 Kbytes  

#define ADDR_FLASH_SECTOR_5     ((u32)0x08020000)     //扇区5起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_6     ((u32)0x08040000)     //扇区6起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_7     ((u32)0x08060000)     //扇区7起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_8     ((u32)0x08080000)     //扇区8起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_9     ((u32)0x080A0000)     //扇区9起始地址, 128 Kbytes  

#define ADDR_FLASH_SECTOR_10    ((u32)0x080C0000)     //扇区10起始地址,128 Kbytes  

#define ADDR_FLASH_SECTOR_11    ((u32)0x080E0000)     //扇区11起始地址,128 Kbytes  

 

 

 

//读取指定地址的半字(16位数据) 

//faddr:读地址 

//返回值:对应数据.

u32 STMFLASH_ReadWord(u32 faddr)

{

    return *(vu32*)faddr; 

}  

//获取某个地址所在的flash扇区

//addr:flash地址

//返回值:0~11,即addr所在的扇区

uint16_t STMFLASH_GetFlashSector(u32 addr)

{

    if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    else if(addr    return FLASH_Sector_11;    

}

//从指定地址开始写入指定长度的数据

//特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数

//         写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以

//         写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里

//         没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写. 

//该函数对OTP区域也有效!可以用来写OTP区!

//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F

//WriteAddr:起始地址(此地址必须为4的倍数!!)

//pBuffer:数据指针

//NumToWrite:字(32位)数(就是要写入的32位数据的个数.) 

void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)    

    FLASH_Status status = FLASH_COMPLETE;

    u32 addrx=0;

    u32 endaddr=0;    

    if(WriteAddr    FLASH_Unlock();     //解锁 

    FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存

 

    addrx=WriteAddr;                //写入的起始地址

    endaddr=WriteAddr+NumToWrite*4;    //写入的结束地址

    if(addrx<0X1FFF0000)            //只有主存储区,才需要执行擦除操作!!

    {

        while(addrx        {

            if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区

            {   

                status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!!

                if(status!=FLASH_COMPLETE)break;    //发生错误了

            }else addrx+=4;

        } 

    }

    if(status==FLASH_COMPLETE)

    {

        while(WriteAddr        {

            if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据

            { 

                break;    //写入异常

            }

            WriteAddr+=4;

            pBuffer++;

        } 

    }

  FLASH_DataCacheCmd(ENABLE);    //FLASH擦除结束,开启数据缓存

    FLASH_Lock();//上锁

 

//从指定地址开始读出指定长度的数据

//ReadAddr:起始地址

//pBuffer:数据指针

//NumToRead:字(4位)数

void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)       

{

    u32 i;

    for(i=0;i    {

        pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.

        ReadAddr+=4;//偏移4个字节.

    }

}

 

 

void FLASHEXT_ReadFlash( u8 *pbData, u32 dwDataLen )

{  

    u32  Len;

    u32  dwData;

    u32  i=0,j=0;

 

    

    Len=  dwDataLen/4+((dwDataLen%4)?1:0); 

 

    STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)(pbData),Len);

  

    return;

}

 

void FLASHEXT_WriteFlash( u8 *pbData, u32 dwDataLen )

{

          

    u32     Len;

    u32     dStartTime;

    u8      pu8ReadData[60];

    u8      i=0;

    Len=  dwDataLen/4+((dwDataLen%4)?1:0);

   

    STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)(pu8ReadData),Len);

 

    for(i=0;i    {

       if(pbData[i]!=pu8ReadData[i])

       {

           STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)(pbData),Len); 

           break;

       }

    }

    

 

    return ;

}

关键字:stm32f407  内部flash  保存数据 引用地址:stm32f407 内部flash保存数据

上一篇:stm32 程序二次加载:串口
下一篇:寄存器版本的跑马灯操作流程(战舰开发板V3)

推荐阅读最新更新时间:2024-11-17 10:47

stm32f407之通用定时器
通用定时器(TIM2 to TIM5)包括由可编程的分频器驱动一个的16位或32位自动重载计数器。它们可用于多种用途,包括测量输入信号的脉冲长度(输入捕获)或生成的输出波形(输出比较和PWM)。可以使用定时器的预分频器和RCC时钟控制器分频器调制从几微秒到几毫秒的脉冲长度和波形周期。它们是完全独立的,不共享任何资源。 主要特点: 通用TIMx定时器功能包括: 1. 16位(TIM3和TIM4)或32位(TIM2和TIM5)计数器,向上,向下,向上/向下自动重装计数。 2. 16位可编程预分频器(可在运行时改变)用于在1到65535之间细分计数器的时钟频率。 3. 多达4个独立的通道可用于: - 输入捕捉 - 输出比较 - P
[单片机]
STM32F407--编写跑马灯
一、跑马灯硬件连接 二、库函数版--程序编写 1、库函数 // 头文件:stm32f4xx_gpio.h 源文件:stm32f4xx_gpio.c // 2、初始化函数 3、GPIO_Init函数初始化样例 // GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟 //GPIOF9,F10初始化设置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口 GPIO_InitStru
[单片机]
STM32F407--编写跑马灯
stm32f407按键输入函数
unsigned char KEY_Scan(unsigned char mode) { static unsigned char key_release = 1; if(mode) key_release = 1; if(key_release && (1 == KEY0 || 1 == KEY1)) { delay_ms(10); key_release = 0; if(1 == KEY0) return 1; else if(1 == KEY1) return 2; } else if(0 == KEY0 && 0 == KEY1) key_release
[单片机]
STM32F407开发板的HTTP模式IAP远程升级之官方例程移植
背景: 在使用RT-Thread RTOS的时候发现官方提出了一种通用的BootLoader方案,支持F1和F4系列的芯片 硬件资源: 正点原子stm32f407zgt6探索者开发板,片上Flash(ROM)大小为1024KB,RAM大小为192KB,板载一个SPI Flash W25Q128 BootLoader配置 根据官方文档:https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/,BootLoader的基本配置如下,加密压缩的配置可以不选。 硬件配置 选择芯片系列:stm32f4 ROM大小:10
[单片机]
使用J-FLASH烧写stm32F407
open data file- connect- program- start application 硬件连接完毕 open data file 软件出现文件框 connected 软件显示connected successfully program(不操作此项直接进行下一步硬件无反应) start application
[单片机]
使用J-<font color='red'>FLASH</font>烧写<font color='red'>stm32F407</font>

推荐帖子

波特率问题
我想知道为什么波特率越大串口通讯时数据越容易出错波特率问题这个想想也能猜出来吧!波特率越大,每个比特分配到的时间越少,从而导致每个比特受干扰和衰减的影响越大,因此就越容易出错波特率影响一般是受硬件还是软件?我目前用ARM7通过UART0往外面发数据,我想知道如果波特率提高了,数据出错也变大了会是哪方面的原因跟通讯距离也有关系………………跟软件程序没啥关系,如果要说有关系就是波特率设置那儿的波特率修正参数,这个越是通讯速率高误码率越高波特率主要受硬件限制主要是传输线的长度和线
beishui 嵌入式系统
【米尔ARM+FPGA架构之作MYD-JX8MMA7开发板】 MYB-JX8MMA7硬件电路的分析学习
1.MYB-JX8MMA7硬件电路的分析学习 所有电路各部分电源均通过磁珠,或者0电阻,连接到对应的电压源,进行隔离和滤波。 插座外壳地EARTH,与电路信号地GND采用ESD防护隔离电路(1M//1nF/2kV,1205)进行保护。 1.1.IO ResetKey连接到SYS_nRST和POR_B,采用二极管并联,防止两个相互影响。 按键采用(电容//TVS)进行硬件滤波和E
mars4zhu 工控电子
TI显示工具mmwave demo visualizer的调用
使用TI的mmwavedemovisualizer工具进行显示及数据保存,现想利用C程序进行代码的编写,以控制mmwavedemovisualizer实现数据的自动开始保存和结束保存操作,求助?TI显示工具mmwavedemovisualizer的调用我有这块的代码,如果需要发给你!
sl_Zoe123 DSP 与 ARM 处理器
EEWORLD大学堂----人工神经网络及其应用
老白菜 DIY/开源硬件专区
TE 官微人工客服功能上线,可以与 TE 技术专家直接微信沟通了!
泰科电子(TEConnectivity,以下简称“TE”)的微信人工客服功能上线啦!所有与TE产品有关的问题,您都可以直接在微信上跟TE的技术专家直接对话啦!你需要了解的TE微信人工客服四大优势:1.利用微信您可以更便捷地享受TE的服务2.工作日8:30-17:30,TE客服都在微信上等着您3.交流方式任您选:文字、图片、视频、语音您随意4.TE客服经验丰富,各种问题来者不拒跟小编一起看看如何与TE的技术专家对话!第一步:
EEWORLD社区 综合技术交流
请问如何调试CE驱动
1)我自己写了一个GPIO驱动,和一个应用,烧到板后,用应用打开驱动时,打开失败,不知道为什么,请教大家怎么样能调试驱动,那些打印信息DEBUGMSG()在串口怎么让他显示呢?2)在自己定制的NK.B0烧到板上,启动的时候,DNW里没有驱动加载的信息,为什么?请大家帮帮忙请问如何调试CE驱动首先注册表有没加进相关的键值DEBUGMSG()改为RETAILMSG()可以用ActivateDeviceEx()调试驱动的加载用RETAILMSG()显示信息用Activat
www123 嵌入式系统
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved