首页 > 其他分享 >stm32f103c8t6对flash进行操作,Hal库,擦除1页数据大小,写入128字节大小,读取指定地址128字节大小,bootloader准备工作

stm32f103c8t6对flash进行操作,Hal库,擦除1页数据大小,写入128字节大小,读取指定地址128字节大小,bootloader准备工作

时间:2024-05-15 21:21:07浏览次数:28  
标签:FLASH hal 字节 flash uint8 大小 128 mcu uint32

参考这篇:STM32 IAP应用开发——自制BootLoader-CSDN博客

把工程转到HAL库使用的函数,用HAL自带的

HAL_FLASHEx_Erase

HAL_FLASH_Program

 

串口显示结果

 验证没问题

flash在hal库使用的驱动程序

#include "flash.h"

extern void FLASH_PageErase(uint32_t PageAddress);//外部引用
//extern void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);//外部引用

/*********************
*mcu_flash_erase
*addr:需要擦除的地址起始位置
*count:需要擦除多少页,stm32f103c8t6的页大小为1K=1024字节
**************************/
//https://doc.embedfire.com/mcu/stm32/f103/hal_general/zh/latest/doc/chapter42/chapter42.html
//uint8_t mcu_flash_erase(uint32_t addr, uint8_t count) 
//{
//  HAL_FLASH_Unlock();// 解锁 FLASH 存储器
//    for(uint8_t i=0; i<count; i++)
//    {
//        FLASH_PageErase(addr + (i * FLASH_PAGE_SIZE));//地址add开始按页擦除
//    }
//  HAL_FLASH_Lock();    // 锁定 FLASH 存储器
//    return 1;//未验证,随便返回1
//}
uint8_t mcu_flash_erase(uint32_t addr, uint8_t count) 
{
    uint32_t SECTORError = 0;
    static FLASH_EraseInitTypeDef EraseInitStruct;
  HAL_FLASH_Unlock();// 解锁 FLASH 存储器
    /* 计算要擦除多少页 */
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;//页擦除模式
    EraseInitStruct.NbPages   = count;//要擦除的页数
    EraseInitStruct.PageAddress   = addr;//擦除开始的地址
    
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK) {
         /*擦除出错,返回,实际应用中可加入处理 */
         return 0;
     }
  HAL_FLASH_Lock();    // 锁定 FLASH 存储器
    return 1;//未验证,随便返回1
}



/*********************
*mcu_flash_write
*addr:需要写入的地址起始位置
*length:需要写入的长度,每次半字写入

https://blog.csdn.net/qq_27508477/article/details/104970097
STM32F1系列最小擦除粒度为页面(1K),最小写入粒度为半字(2byte)
https://blog.csdn.net/weixin_45003437/article/details/102846730
!!!字、半字是根据处理器的特性决定的;字节则都是8bit
!!!stm32是32bit处理器,所以它的字是32bit的(一次处理4字节长度的数据)。半字自然就是16bit(2字节);字节是8bit。

例子::
                for (i = 0; i < APP_ERASE_SECTORS * 8; i++)
                {
                    mcu_flash_read(down_addr, &down_buf[0], 128);
                    delay_ms(5);
                    mcu_flash_write(app_addr, &down_buf[0], 128);
                    delay_ms(5);
                    down_addr += 128;
                    app_addr += 128;
                }

假设app的内存分配为1K
mcu_flash_write(app_addr, &down_buf[0], 128);//因为down_buf是uint8_t,所以是128个字节
APP_ERASE_SECTORS假设为1,stm32f103c8t6的一个页就是1K
循环8次:8*128=1024字节=1K,刚刚好写入一个页
**************************/
////uint8_t mcu_flash_write(uint32_t addr, uint8_t *buffer, uint32_t length) 
////{
////    uint16_t i, data = 0;
////    HAL_FLASH_Unlock();// 解锁 FLASH 存储器
////    for (i = 0; i < length; i += 2) //每次写入两个8位,就是16位=两字节
////    {
////        data = (*(buffer + i + 1) << 8) + (*(buffer + i));//左移8位,和原8位组成16位=半字
////        FLASH_Program_HalfWord((uint32_t)(addr + i), data);
////        
////    }
////    HAL_FLASH_Lock();    // 锁定 FLASH 存储器
////    
////    return 1;//未验证,随便返回1
////}
//https://doc.embedfire.com/mcu/stm32/f103/hal_general/zh/latest/doc/chapter42/chapter42.html
uint8_t mcu_flash_write(uint32_t addr, uint8_t *buffer, uint32_t length) 
{
    uint16_t i, data = 0;
    HAL_FLASH_Unlock();// 解锁 FLASH 存储器
    for (i = 0; i < length; i += 2) //每次写入两个8位,就是16位=两字节
    {
        data = (*(buffer + i + 1) << 8) + (*(buffer + i));//左移8位,和原8位组成16位=半字
        if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data) != HAL_OK)//写入半字
        {
            //某一步写入失败了
            return 0;
        }
    }
    HAL_FLASH_Lock();    // 锁定 FLASH 存储器
    
    return 1;//未验证,随便返回1
}



/************************
*addr:读取的地址
*buffer:用来保存读取的数据
*需要读取的数据长度
*************************************/
void mcu_flash_read(uint32_t addr, uint8_t *buffer, uint32_t length) 
{
    memcpy(buffer, (void *)addr, length);
}
flash.c flash.h
#ifndef __FLASH_H
#define __FLASH_H
#include "main.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_def.h"
#include "stm32f1xx_hal_flash.h"

uint8_t mcu_flash_erase(uint32_t addr, uint8_t count);
uint8_t mcu_flash_write(uint32_t addr, uint8_t *buffer, uint32_t length);
void mcu_flash_read(uint32_t addr, uint8_t *buffer, uint32_t length);

#endif

 

 工程链接:

链接:https://pan.baidu.com/s/1s-XJxv1TWlT2aGiZwWyAlg?pwd=18e7
提取码:18e7

标签:FLASH,hal,字节,flash,uint8,大小,128,mcu,uint32
From: https://www.cnblogs.com/hjf-log/p/18194715

相关文章

  • mysql表名大小写敏感
    通过搜索了解到mysql在win下大小写不明感,在linux下大小写敏感本欲让ai写个脚本转表名,两次回答的结果都不能用后发现修改mysqld.conf中的lower_case_table_names=1可以忽略大小写但修改过后启动失败官方回答是初始化后不能再修改该参数,如需要修改需要重新初始化为了不折腾,......
  • Qt获取屏幕分辨率,可用区域大小,标题栏高度
    一、获取屏幕分辨率、可用区域大小//Qt5之前,获取屏幕分辨率、可用区域QDesktopWidget*desk=QApplication::desktop();QRectscreen_rect=desk->screenGeometry();//完整屏幕大小QRectavailable_rect=desk->availableGeometry();//可用区域大......
  • OpenAI 发布全新生成式模型 GPT-4o;字节收购音频设备公司 Oladance丨 RTE 开发者日报 V
      开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑......
  • jumpserver windows 上传文件大小限制配置
    jumpserverYoudonothavepermissiontouploadthisfile.Ifyourequireaccess,pleasecheckyoursystemsettings,orcheckwithyoursystemadministratorif["$SECRET_KEY"=""];thenSECRET_KEY=`cat/dev/urandom|tr-dcA-Za-z0......
  • 文件IO完成libjpeg库的移植,并设计程序实现在LCD上的任意位置显示一张任意大小的jpg图
    文件IO:完成libjpeg库的移植,并设计程序实现在LCD上的任意位置显示一张任意大小的jpg图片,注意不要越界。1.库的移植1.下载需要移植的库的源码包,libjpeg库源码包在官网可以下载www.ijg.org2.解压压缩包,解压后找到自述文件README,打开README了解libjpeg库的使用规则!3.打开源码包......
  • js 取滚动条 和视口大小
    functiongetScrollSize(){if(window.pageXOffset){return{x:window.pageXOffset,y:window.pageYOffset}}else{return{x:document.body.offsetLeft+document.documentElement.offsetLeft,......
  • 设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真
    文件IO练习题设计程序,实现在LCD上任意位置显示一张任意大小的色深为24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。代码:/****************************************************************************************************************** * filename : Show......
  • 在LCD上的任意位置显示一张任意大小的jpg图片
    /***************************************************filename:lcdshowjpg.c*author:[email protected]*date:2024/05/13*brief:完成libjpeg库的移植,并设计程序实现在LCD上的任意位置显示一张任意大小的jpg图片,注意不要越界。*note:......
  • 字节面试:说说Java中的锁机制?
    Java中的锁(Locking)机制主要是为了解决多线程环境下,对共享资源并发访问时的同步和互斥控制,以确保共享资源的安全访问。锁的作用主要体现在以下几个方面:互斥访问:确保在任何时刻,只有一个线程能够访问特定的资源或执行特定的代码段。这防止了多个线程同时修改同一资源导致的数据......
  • 采用双dsPIC DSC内核配置,DSPIC33CH128MP208-E/PT DSPIC33CH128MP208-I/PT DSPIC33CH12
    dsPIC33CH系列数字信号控制器简介dsPIC33CH系列控制器采用单芯片、双dsPICDSC内核配置,将为设计高端嵌入式控制应用的系统开发人员带来福音。根据设计,dsPIC33CH的两个内核一个是主核,一个是副核。副核用于执行时间关键型专用控制代码,主核负责运行用户接口、系统监控和通信功能,专为......