你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F407 flash写入失败,请高手指点指教...

[复制链接]
立码赚 提问时间:2023-3-7 14:19 / 未解决

想做个STM32F407 flash写入数据程序,从CDNS(博主Ch_champion)找了个案例,原来是STM32F103CBT6芯片的案例,现改成STM32F407,写入不成功,贴出代码:

bsp_flash.c

#include "bsp_flash.h"
#include "stdio.h"
#include "string.h"
#include "usart.h"

          /*判断使能读保护*/
HAL_StatusTypeDef FLASH_If_EnableReadProtection(void)
{
    FLASH_OBProgramInitTypeDef OptionsBytesStruct = { 0 };
    HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
    HAL_StatusTypeDef result = HAL_OK;

    if (OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL_0)
    {
        OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;
        OptionsBytesStruct.RDPLevel = OB_RDP_LEVEL_1;

        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();

        if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK)
        {
            /* Launch the option byte loading */
            HAL_FLASH_OB_Launch();
            /* Lock the FLASH Option Control Registers access */
            HAL_FLASH_OB_Lock();
            HAL_FLASH_Lock();
            return result;
        }
        /* Launch the option byte loading */
        HAL_FLASH_OB_Launch();
        /* Lock the FLASH Option Control Registers access */
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
        result = HAL_ERROR;
    }
    return result;
}

                /*判断读保护等级*/
HAL_StatusTypeDef Flash_If_DisableReadProtection(void)
{
    FLASH_OBProgramInitTypeDef OptionsBytesStruct = { 0 };
    HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
    HAL_StatusTypeDef result = HAL_OK;

  if (OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL_1)
    {
        OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;
        OptionsBytesStruct.RDPLevel = OB_RDP_LEVEL_0;

        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();

        if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK)
        {
            /* Launch the option byte loading */
            HAL_FLASH_OB_Launch();
            /* Lock the FLASH Option Control Registers access */
            HAL_FLASH_OB_Lock();
            HAL_FLASH_Lock();
            return result;
        }
        /* Launch the option byte loading */
        HAL_FLASH_OB_Launch();
        /* Lock the FLASH Option Control Registers access */
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
        result = HAL_ERROR;
    }
    return result;
}
          /*设置flash读保护*/
HAL_StatusTypeDef Set_FlashReadProtection(uint8_t mode)
{
    HAL_StatusTypeDef result = HAL_ERROR;

    if (mode == 1)
    {
        FLASH_If_EnableReadProtection();
        printf("EnableReadProtection!!!\r\n");
        result = HAL_OK;
    }
    else
    {
        Flash_If_DisableReadProtection();
        printf("DisableReadProtection!!!\r\n");
        result = HAL_OK;
    }
    return result;
}

       /*flash初始化*/
void FLASH_If_Init(void)
{
  /* Unlock the Program memory */
  HAL_FLASH_Unlock();

  /* Clear all FLASH flags */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGSERR | FLASH_FLAG_WRPERR);
//  /* Unlock the Program memory */
  HAL_FLASH_Lock();
}

           /*flash写入*/
uint8_t FLASH_If_Write(uint32_t WriteAddr, uint32_t * pBuffer, uint32_t length)
{
    static FLASH_EraseInitTypeDef pEraseInit;
    uint32_t pageerror = 0;  //定义擦除出错时,返回的Flash地址
         /*以下原是STM32F103CBT6,用在STM32F407VET6编译出错*/
//  HAL_FLASH_Unlock();
//  pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
//  pEraseInit.PageAddress = WriteAddr;  //定义数据地址
//  pEraseInit.NbPages = 1;  //定义擦除页面数 - 页 = 1024byte
         /*以下改成STM32F407VET6*/
    pEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;//
    pEraseInit.Sector = WriteAddr;  //定义数据地址 
    pEraseInit.NbSectors = 1;  //定义擦除页面数 - 页 = 1024byte 
    HAL_FLASHEx_Erase(&pEraseInit, &pageerror);  //擦除Flash


    for (uint32_t i = 0; i < length; i++)
    {
        //HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, WriteAddr + i * 2, *(pDATA + i));   //半字节:FLASH_TYPEPROGRAM_HALFWORD
#if 0
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, WriteAddr + i * 4, *(pBuffer + i)); //字节:LASH_TYPEPROGRAM_WORD
#else
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, WriteAddr, *(uint32_t*)(pBuffer+i)) == HAL_OK)  
    {
     /* Check the written value */
      if (*(uint32_t*)WriteAddr != *(uint32_t*)(pBuffer+i))
      {
          HAL_FLASH_Lock();
        /* Flash content doesn't match SRAM content */
        return(FLASHIF_WRITINGCTRL_ERROR);
      }
      /* Increment FLASH destination address */
      WriteAddr += 4;
    }
    else
    {
      HAL_FLASH_Lock();
      /* Error occurred while writing data in Flash memory */
      return (FLASHIF_WRITING_ERROR);
    }
#endif
    }
    HAL_FLASH_Lock();
    return (FLASHIF_OK);
}

uint8_t FLASH_If_Read(uint32_t ReadAddr, uint32_t *pBuffer, uint32_t DataLength)
{
    uint32_t i;

    for(i = 0; i < DataLength; i++)
    {
        pBuffer[i] = *(__IO uint32_t*)(ReadAddr);////读取4个字节.
        ReadAddr += 4;//偏移4个字节.
    }
    return (FLASHIF_OK);
}


void Flash_Test(void)
{

    SystemParamTypeDef SystemParam_default = {
        .Device_id              = 0x00000111,
        .Hardware_Version       = 0x10000111,
        .Application_Version    = 0x00000111,
        .Application_Status     = APPLICATION_NORMAL
  };

    SystemParamTypeDef SystemParam_update = {
        .Device_id              = 0x00000222,
        .Hardware_Version       = 0x10000222,
        .Application_Version    = 0x10000222,
        .Application_Status     = APPLICATION_UPDATED
  };

    SystemParamTypeDef SystemParam_read;

    uint32_t page = sizeof(SystemParam_default) / sizeof(uint32_t);

    printf("Flash_Test!!!\r\n");
    Set_FlashReadProtection(0);  //1解除读保护,0设置读保护。

    FLASH_If_Init();

    //memset(SystemParam_default, 0, sizeof(SystemParam_default));
    memset(&SystemParam_read, 0, sizeof(SystemParam_read)); //清空结构体内容
    FLASH_If_Write(DATASTOREADDR, (uint32_t*)&SystemParam_default, page);//SystemParam_default, page
    FLASH_If_Read(DATASTOREADDR, (uint32_t*)&SystemParam_read, page);


    printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX, Application_Status:0x%08lX \r\n",
                        SystemParam_read.Device_id,           SystemParam_read.Hardware_Version,
                        SystemParam_read.Application_Version, SystemParam_read.Application_Status);

    HAL_Delay(100);

    printf("UPDATA!!! \r\n");
    //memset(&SystemParam_default, 0, sizeof(SystemParam_default)); //清空结构体内容
    memset(&SystemParam_read, 0, sizeof(SystemParam_read)); //清空结构体内容

    FLASH_If_Write(DATASTOREADDR, (uint32_t*)&SystemParam_update, page);
    FLASH_If_Read(DATASTOREADDR, (uint32_t*)&SystemParam_read, page);
    printf("Device_id:0x%08lX, Hardware_Version:0x%08lX, Application_Version:0x%08lX, Application_Status:0x%08lX \r\n",
                        SystemParam_read.Device_id,                      SystemParam_read.Hardware_Version,
                        SystemParam_read.Application_Version, SystemParam_read.Application_Status);     
}


bsp_flash.h

#ifndef __BSP_FLASH_H
#define __BSP_FLASH_H

#ifdef __cplusplus
extern "C" {
#endif



/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"



#define  DATASTOREADDR  0x0807F800   //数据存放地址 0x0800F800  0x080C0000


/* Error code */ 
typedef enum 
{
  FLASHIF_OK = 0,
  FLASHIF_ERASEKO,
  FLASHIF_WRITINGCTRL_ERROR,
  FLASHIF_WRITING_ERROR,
  FLASHIF_PROTECTION_ERRROR
}Flash_Status_t;


typedef enum {
    APPLICATION_NORMAL = 0,         // APP能正常稳定运行
    APPLICATION_UPDATED,            // APP刚更新完成,等待测试启动
    APPLICATION_ERROR,              // APP错误,不能正常工作
}Application_Status_t;

typedef __PACKED_STRUCT{
    uint32_t Device_id;                             // 设备号
    uint32_t Hardware_Version;              // 硬件版本信息
    uint32_t Application_Version;         // APP软件版本
    uint32_t Application_Status;          // APP的状态. @Application_Status_t
    uint32_t SystemParamCRC;
}SystemParamTypeDef;


void Flash_Test(void);


#ifdef __cplusplus
}
#endif

#endif

打印测试,只显示:

Flash_Test!!!

DisableReadProtection!!! 写入数据没有打印出来,应该是写入不成功。

收藏 评论5 发布时间:2023-3-7 14:19

举报

5个回答
xmshao 回答时间:2023-3-7 14:49:56
STM32F1和STM32F4系列的片内flash参数有诸多不一样,支持的写宽度、页大小等。


建议你基于STM32F4系列的相关例程来编写代码吧。


STM32F4系列的Cube库里有相关例程参考,有写、有擦操作。


比方:


\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.1\Projects\STM324xG_EVAL\Examples\FLASH\FLASH_EraseProgram
废鱼 回答时间:2023-3-8 11:04:31

103和407的擦写不一样,注意擦除时的输入参数。在线仿真可以看到指定FLASH地址内容。写不进去可能是擦的区域和写的区域不一致导致的。

立码赚 回答时间:2023-3-7 15:50:40

xmshao 发表于 2023-3-7 14:49
STM32F1和STM32F4系列的片内flash参数有诸多不一样,支持的写宽度、页大小等。</p>
<p>

你不说我都不知道有官方案例,谢谢建议

立码赚 回答时间:2023-3-7 15:53:11

写入数据不正常

[md]![VVV.png](data/attachment/forum/202303/07/155243hxl8qsuym5rmygy1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "VVV.png")
写入数据不正常
VVV.png
立码赚 回答时间:2023-3-7 16:02:36

串口打印结果: Flash_Test!!! DisableReadProtection!!! Device_id:0xFFFFFFFF, Hardware_Version:0xFFFFFFFF, Application_Version:0xFFFFFFFF, Application_Status:0xFFFFFFFF UPDATA!!!

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版