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<ADDR_FLASH_SECTOR_1)return FLASH_Sector_0;
    else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_Sector_1;
    else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_Sector_2;
    else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_Sector_3;
    else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_Sector_4;
    else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_Sector_5;
    else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_Sector_6;
    else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_Sector_7;
    else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_Sector_8;
    else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_Sector_9;
    else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_Sector_10; 
    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<STM32_FLASH_BASE||WriteAddr%4)return;    //非法地址
    FLASH_Unlock();     //解锁 
    FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存

    addrx=WriteAddr;                //写入的起始地址
    endaddr=WriteAddr+NumToWrite*4;    //写入的结束地址
    if(addrx<0X1FFF0000)            //只有主存储区,才需要执行擦除操作!!
    {
        while(addrx<endaddr)        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
        {
            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<endaddr)//写数据
        {
            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<NumToRead;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<dwDataLen;i++)
    {
       if(pbData[i]!=pu8ReadData[i])
       {
           STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)(pbData),Len); 
           break;
       }
    }
    

    return ;
}

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您好!关于将DHT11数据保存STM32F407FLASH存储器上,您可以按照以下步骤进行操作: 1. 首先,确保您已经正确配置了STM32F407FLASH存储器,并且已经使能了对FLASH的编程和擦除功能。 2. 在您的代码中,首先需要定义一个用于保存DHT11数据的变量。例如,您可以创建一个结构体来保存温度和湿度的值。 ```c typedef struct { float temperature; float humidity; } DHT11_Data; ``` 3. 在读取到DHT11传感器的数据后,将数据保存到定义的变量中。 ```c DHT11_Data dht11Data; // 假设您已经读取到了温度和湿度值 float temperature = ...; float humidity = ...; dht11Data.temperature = temperature; dht11Data.humidity = humidity; ``` 4. 接下来,将数据写入到FLASH存储器中。您可以使用STM32提供的FLASH编程函数来实现。 ```c // 获取要写入的地址 uint32_t flashAddress = /* 指定FLASH存储器的地址 */; // 解锁FLASH存储器 HAL_FLASH_Unlock(); // 擦除指定地址上的扇区 FLASH_Erase_Sector(FLASH_SECTOR_7, FLASH_VOLTAGE_RANGE_3); // 将数据写入到FLASH存储器 HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLOAT, flashAddress, dht11Data.temperature); HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLOAT, flashAddress + sizeof(float), dht11Data.humidity); // 锁定FLASH存储器 HAL_FLASH_Lock(); ``` 请注意,上述代码仅为示例,并且需要根据您的具体情况进行修改。 这样,您就可以将DHT11的数据保存STM32F407FLASH存储器中了。希望对您有所帮助!如果您有任何疑问,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值