Insert title here

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

参考这篇: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

posted @ 2024-05-15 21:11  这一切足够了  阅读(26)  评论(0编辑  收藏  举报
复制代码