stm32f103使用hal库函数读写内部flash



本次使用RT-Thread studio编写,使用为5.02完整版,直接编写函数使用hal库函数读写内部flash。

一、写内部flash

在写数据的逻辑上是比较简单的,因为hal库将底层已经进行了封装,步骤就是解锁flash->擦除要写入的扇区->清除CR寄存器的PER位(这个本来应该在擦除里面的,基础库就是这样做的,但HAL库里面没写)->写入数据->上锁flash。
代码:

void Flash_Write(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len)
{

    HAL_FLASH_Unlock();

    FLASH_PageErase(Address);  //擦除这个扇区
    CLEAR_BIT(FLASH->CR, FLASH_CR_PER);                         //清除CR寄存器的PER位,此操作应该在FLASH_PageErase()中完成!
                                                                            //但是HAL库里面并没有做,应该是HAL库bug!
    if (TypeProgram==TYPEPROGRAM_CHAR) {
        for (int var = 0; var < len/2; var++) {
            uint8_t data1=(uint8_t)*Data;
            uint8_t data2=(uint8_t)*(Data+1);
            uint64_t datar = data2<<8|data1;
            HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address,datar);
            Address+=2;
            Data+=2;
        }
    } else {
        for (int var = 0; var < len; var++) {
            HAL_FLASH_Program(TypeProgram, Address, *Data);
            Address+=(1<<TypeProgram);
            Data+=1;
        }
    }
    HAL_FLASH_Lock();
}

这里面我想要8位,16位,32位,64位的数据都能写入,所以定义了一个写入类型的参数,由于库函数至少是按半字处理的,所以8位需要特殊处理,而且要进行兼容,传入的数据就只能是64位的,这点比较麻烦,就是说传入的数组必须是64位,不然写入的结果会不对,已经测试过。

二、读内部flash

读内部就比较简单了,只需要按照类型返回不同指针强转和不同地址增加就行了,但是同样传入的指针是64位,使用数据时还的强转为自己想要的类型:

void Flash_Read(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len)
{
    int32_t i=0;
    if (TypeProgram==TYPEPROGRAM_CHAR) {
       for (i = 0; i < len; i++, Address+=1, Data++)
       {
           *Data = *(uint8_t *) Address;
       }
    }else if (TypeProgram==TYPEPROGRAM_HALFWORD) {
       for (i = 0; i < len; i++, Address+=2, Data++)
       {
           *Data = *(uint16_t *) Address;
       }
    }else if (TypeProgram==TYPEPROGRAM_WORD) {
      for (i = 0; i < len; i++, Address+=4, Data++)
      {
          *Data = *(uint32_t *) Address;
      }
    }else if (TypeProgram==TYPEPROGRAM_DOUBLEWORD) {
      for (i = 0; i < len; i++, Address+=8, Data++)
      {
          *Data = *(uint64_t *) Address;
      }
    }
}

三、代码

.c文件:

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-12-07     Windows       the first version
 */

#include "flash.h"
extern void    FLASH_PageErase(uint32_t PageAddress);
extern HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
//#define TYPEPROGRAM_CHAR                 0x00U  /*!<Program a char (8-bit) at a specified address.*/
//#define TYPEPROGRAM_HALFWORD             0x01U  /*!<Program a half-word (16-bit) at a specified address.*/
//#define TYPEPROGRAM_WORD                 0x02U  /*!<Program a word (32-bit) at a specified address.*/
//#define TYPEPROGRAM_DOUBLEWORD           0x03U  /*!<Program a double word (64-bit) at a specified address*/
void Flash_Write(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len)
{

    HAL_FLASH_Unlock();

    FLASH_PageErase(Address);  //擦除这个扇区
    CLEAR_BIT(FLASH->CR, FLASH_CR_PER);                         //清除CR寄存器的PER位,此操作应该在FLASH_PageErase()中完成!
                                                                            //但是HAL库里面并没有做,应该是HAL库bug!
    if (TypeProgram==TYPEPROGRAM_CHAR) {
        for (int var = 0; var < len/2; var++) {
            uint8_t data1=(uint8_t)*Data;
            uint8_t data2=(uint8_t)*(Data+1);
            uint64_t datar = data2<<8|data1;
            HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address,datar);
            Address+=2;
            Data+=2;
        }
    } else {
        for (int var = 0; var < len; var++) {
            HAL_FLASH_Program(TypeProgram, Address, *Data);
            Address+=(1<<TypeProgram);
            Data+=1;
        }
    }
    HAL_FLASH_Lock();
}

void Flash_Read(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len)
{
    int32_t i=0;
    if (TypeProgram==TYPEPROGRAM_CHAR) {
       for (i = 0; i < len; i++, Address+=1, Data++)
       {
           *Data = *(uint8_t *) Address;
       }
    }else if (TypeProgram==TYPEPROGRAM_HALFWORD) {
       for (i = 0; i < len; i++, Address+=2, Data++)
       {
           *Data = *(uint16_t *) Address;
       }
    }else if (TypeProgram==TYPEPROGRAM_WORD) {
      for (i = 0; i < len; i++, Address+=4, Data++)
      {
          *Data = *(uint32_t *) Address;
      }
    }else if (TypeProgram==TYPEPROGRAM_DOUBLEWORD) {
      for (i = 0; i < len; i++, Address+=8, Data++)
      {
          *Data = *(uint64_t *) Address;
      }
    }
}

.h文件

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-12-07     Windows       the first version
 */
#ifndef APPLICATIONS_FLASH_H_
#define APPLICATIONS_FLASH_H_

#include "main.h"
#include "stm32f1xx_hal_flash.h"

#define TYPEPROGRAM_CHAR                 0x00U  /*!<Program a char (8-bit) at a specified address.*/
#define TYPEPROGRAM_HALFWORD             0x01U  /*!<Program a half-word (16-bit) at a specified address.*/
#define TYPEPROGRAM_WORD                 0x02U  /*!<Program a word (32-bit) at a specified address.*/
#define TYPEPROGRAM_DOUBLEWORD           0x03U  /*!<Program a double word (64-bit) at a specified address*/
void Flash_Write(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len);
void Flash_Read(uint32_t TypeProgram, uint32_t Address, uint64_t (*Data), uint32_t len);

#endif /* APPLICATIONS_FLASH_H_ */

main函数测试:

uint64_t flash_buf[] = {2,3,31,45};

    Flash_Write(TYPEPROGRAM_HALFWORD,FLASH_DATA_ADDR,flash_buf,4);

    uint64_t data_buf[4];
    rt_kprintf("FLASH_DATA_ADDR:%x\n",(FLASH_DATA_ADDR));
    Flash_Read(TYPEPROGRAM_HALFWORD,FLASH_DATA_ADDR,data_buf,4);
    rt_kprintf("flash_buf:%d\n",(uint16_t)data_buf[0]);
    rt_kprintf("flash_buf:%d\n",(uint16_t)data_buf[1]);
    rt_kprintf("flash_buf:%d\n",(uint16_t)data_buf[2]);
    rt_kprintf("flash_buf:%d\n",(uint16_t)data_buf[3]);
    data_buf[0]=0x123456789abcdef0;
    rt_kprintf("(uint8_t)data_buf[0]:%x\n",(uint8_t)data_buf[0]);
    rt_kprintf("(uint16_t)data_buf[0]:%x\n",(uint16_t)data_buf[0]);
    rt_kprintf("(uint32_t)data_buf[0]:%x\n",(uint32_t)data_buf[0]);
    rt_kprintf("(uint64_t)data_buf[0]:%x\n",(uint64_t)data_buf[0]);
    rt_kprintf("(uint64_t)data_buf[0]:%x\n",(uint32_t)(data_buf[0]>>32));

测试结果:
在这里插入图片描述

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32F103是一款高性价比的通用型微控制器,适用于大量应用场景,如工业控制、物联网设备、医疗设备等。HAL库(Hardware Abstraction Layer硬件抽象层)是ST官方提供的一种方便易用的开发工具,可让开发者快速上手,简化软件开发流程。 STM32F103系列的HAL库函数说明包括以下内容: 1. GPIO口配置:GPIO口可以设置为输入或输出,通过HAL_GPIO_Init函数可以对GPIO口进行配置,还可以设置输入上下拉电阻和输出的初始电平。 2. 外部中断配置:STM32F103支持外部中断,可以在输入引脚输入低电平或下降沿等触发条件时生成中断,通过HAL_GPIO_EXTI_Init函数进行配置。 3. 定时器配置:STM32F103支持多种定时器,可以实现PWM波等功能,通过HAL_TIM_Base_Init函数进行配置。 4. 闪存读写操作:STM32F103内置闪存,可以将程序代码下载到闪存中,通过HAL_FLASH_Program函数实现编程,或者通过HAL_FLASH_Read函数实现读取。 5. ADC模数转换配置:STM32F103支持模数转换,通过HAL_ADC_Init函数进行配置,还可以设置采样时间和转换模式等。 6. UART串口配置:STM32F103支持串口通信,通过HAL_UART_Init函数进行配置,可以设置波特率、数据位数、停止位数等参数。 7. SPI总线配置:STM32F103支持SPI总线,通过HAL_SPI_Init函数进行配置,可以设置传输模式、数据位数等参数。 总的来说,STM32F103系列的HAL库函数非常全面,可以满足绝大部分应用场景,大大简化了软件开发过程。开发者只需要熟悉函数调用的方式和参数设定即可快速进行开发。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k-kun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值