发新帖我要提问
12
返回列表
打印
[其他ST产品]

STM32G4x FLASH 读写配置结构体(LL库下使用)

[复制链接]
楼主: 等你下课
手机看帖
扫描二维码
随时随地手机跟帖
21
等你下课|  楼主 | 2023-12-29 14:02 | 只看该作者 回帖奖励 |倒序浏览
上面是我修改的HAL库Flash驱动,大部分功能还没有验证,希望大家帮忙测试,提出问题,一起完善。

下面给出我的结构体读写程序,因为是项目里的,我就不全部放出来了,大家按需修改,我是参考官方flash擦除编程的DEMO,因为只支持双字写入,稍稍花了点时间。本着授人以鱼不如授人以渔的态度,希望大家自己修改,复制粘贴学不到啥东西,共勉。有错误,或者有更好的代码,希望大家也教教我,学无止境。就比如判断写入是否正常那里,我试了直接读取和比较内存空间2种方法,应该是都可以的,因为我读配置也是这样读上来的。我不喜欢设置粉丝可见,如果觉得有用,点个赞或者点个收藏,谢谢啦。

使用特权

评论回复
22
等你下课|  楼主 | 2023-12-29 14:02 | 只看该作者
#define PID_CFG_FLASH_ADDR_START    FLASH_ADDR_PAGE_31 // Page31 in DBANK mode
#define PID_CFG_FLASH_ADDR_END      (FLASH_ADDR_PAGE_31 + FLASH_PAGE_SIZE - 1U) // 1Page 2KB
#define PID_CFG_FLASH_PAGE_IDX      31U
#define PID_CFG_FLASH_PAGE_NUM      1U

#define PID_CFG_STRUCT_SIZE64       (sizeof(PID_ObjectTypeDef) % 8U ? \
                                        sizeof(PID_ObjectTypeDef) / 8U : \
                                        sizeof(PID_ObjectTypeDef) / 8U + 1)

typedef struct
{
    float P;
    float I;
    float D;

    int ILimitMIN;
    int ILimitMAX;
    int ISeparate;
    int Accuracy;
    int Mode;
    int Waveform;
    int Enable;

    int OutputMAX;
    int OutputMED;
    int OutputMIN;
    int OutputInterval;
    int OutputPolarity;

    int SPInputMAX;
    int SPInputMIN;
    int FBInputMAX;
    int FBInputMIN;

    int FilterMethod;
    int FilterSampleNum;

    int AnalogInputCH1;
    int AnalogInputCH2;
    int Ana**utput;

    int DigitalInputCH1;
    int DigitalInputCH2;
    int DigitalOutputCH1;
    int DigitalOutputCH2;
} PID_ObjectTypeDef;

int PID_CntlrConfigSave(void)
{
    int Ret = ERROR;
    uint8_t Idx = 0;
    uint32_t PageErr = 0;
    uint32_t WriteAddr = PID_CFG_FLASH_ADDR_START;

    FLASH_EraseInitTypeDef FlashErase =
    {
        .TypeErase = FLASH_TYPEERASE_PAGES,
        .Banks = FLASH_BANK_1,
        .Page = PID_CFG_FLASH_PAGE_IDX,
        .NbPages = PID_CFG_FLASH_PAGE_NUM,
//        .Banks = FLASH_GetAddrPageBank(PID_CFG_FLASH_ADDR_START),
//        .Page = FLASH_GetAddrPageIdx(PID_CFG_FLASH_ADDR_START),
//        .NbPages = FLASH_GetAddrPageOffset(PID_CFG_FLASH_ADDR_START, PID_CFG_FLASH_ADDR_END),
    };

    /* Unlock the Flash to enable the flash control register access *************/
    FLASH_Unlock();
    /* Clear OPTVERR bit set on virgin samples */
    FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
    /* Erase the user Flash area
    (area defined by PID_CFG_FLASH_ADDR_START and PID_CFG_FLASH_ADDR_END) *******/
    /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
       you have to make sure that these data are rewritten before they are accessed during code
       execution. If this cannot be done safely, it is recommended to flush the caches by setting the
       DCRST and ICRST bits in the FLASH_CR register. */
    if (FLASH_Erase(&FlashErase, &PageErr) != FLASH_OK)
    {
        /*
          Error occurred while page erase.
          User can add here some code to deal with this error.
          PageError will contain the faulty page and then to know the code error on this page,
          user can call function 'FLASH_GetError()'
        */
        PID_LOG_PRINT("Flash erase error code: %x, page: %x.\r\n", FLASH_GetError(), PageErr);
        FLASH_Lock();
        return Ret;
    }

    /* Program the user Flash area word by word
    (area defined by PID_CFG_FLASH_ADDR_START and PID_CFG_FLASH_ADDR_END) *******/
    for (Idx = 0; Idx < PID_CFG_STRUCT_SIZE64; Idx++)
    {
        if (FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, WriteAddr, *((uint64_t *)&PID + Idx)) != FLASH_OK)
        {
            /* Error occurred while writing data in Flash memory.
             User can add here some code to deal with this error */
            FLASH_Lock();
            return Ret;
        }
        WriteAddr += 8; /* Increment to next double word*/
    }
    /* Lock the Flash to disable the flash control register access (recommended
       to protect the FLASH memory against possible unwanted operation) *********/
    FLASH_Lock();

    /* Check if the programmed data is OK*/
//    PID_ObjectTypeDef PIDTmp = *(__IO PID_ObjectTypeDef *)ReadAddr;

    if (!memcmp(&PID, (uint32_t *)PID_CFG_FLASH_ADDR_START, sizeof(PID_ObjectTypeDef)))
    {
        Ret = SUCCESS;
    }

    return Ret;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则