STM32CUBEMX-读写内部Flash

1、STM32内部Flash

1.1 Flash介绍

  在STM32芯片内部有一个 FLASH 存储器,它主要用于存储代码,我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部 FLASH 中,由于 FLASH 存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部 FLASH 中加载代码并运行。
STM32 flash

1.2 STM32内部Flash详解

  STM32 的内部 FLASH 包含主存储器、系统存储器以及选项字节区域,它们的地址分布及大小见下表:
STM32 FLASH地址

1.2.1 主存储器

  一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 256K FLASH、512K FLASH 都是指这个区域的大小。
  主存储器分为 256 页,每页大小为 2KB,共 512KB。这个分页的概念,实质就是 FLASH 存储器的扇区,与其它 FLASH 一样,在写入数据前,要先按页(扇区)擦除。
  注意上表中的主存储器是本实验板使用的 STM32VET6 型号芯片的参数,即 STM32F1 大容量产品。若使用超大容量、中容量或小容量产品,它们主存储器的页数量、页大小均有不同,使用的时候要注意区分。
  主存储器是以页为单位划分的。stm32根据FLASH主存储块容量、页面的不同,系统存储器的不同,分为小容量、中容量、大容量、互联型,共四类产品。

  • 小容量产品:主存储块1-32KB, 每页1KB。系统存储器2KB
  • 中容量产品:主存储块64-128KB, 每页1KB。系统存储器2KB
  • 大容量产品:主存储块256KB以上, 每页2KB。系统存储器2KB
  • 互联型产品:主存储块256KB以上, 每页2KB。系统存储器18KB

1.2.2 系统存储区

  系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB 以及 CAN 等 ISP 烧录功能。

1.2.3 选型字节

  选项字节用于配置 FLASH 的读写保护、待机/停机复位、软件/硬件看门狗等功能,这部分共 16 字节。可以通过修改 FLASH 的选项控制寄存器修改。

2、STM32CUBEMX配置

  本工程采用的芯片型号是STM32F103C8T6,CUBEMX的配置按照这个行骗型号进行配置。

2.1 时钟源配置

时钟源配置

2.2 调试接口配置

调试接口配置

2.3 工程配置

工程配置

2.4 工程文件配置

工程文件配置

2.5 时钟配置

时钟配置

3、代码讲解

3.1 flash读写代码的.h文件

#ifndef __FLASH_H__
#define __FLASH_H__

#include "main.h"
#include "string.h"

#define       STM32_FLASH_SIZE 64   //所选STM32的FLASH容量大小(单位为K);本产品选用的型号为:STM32F103C8T6;FALSH大小为64K

     #if      STM32_FLASH_SIZE < 256
		 #define  STM32_SECTOR_SIZE 1024  //一页为1K
		 #else
		 #define  STM32_SECTOR_SIZE 2048   //一页为2K
		 #endif
		 
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH起始地址

//写入的FLASH地址,这里为从倒数第一个扇区地址(0x807f800)开始写
//STM32_FLASH_BASE + STM32_SECTOR_SIZE*255 = 0x08000000 + (2048*255) = 0x0807f800
#define FLASH_SAVE_ADDR  STM32_FLASH_BASE+STM32_SECTOR_SIZE*255
		 

void FLASH_WriteData(uint32_t FLASH_Addr, uint16_t *FLASH_Data, uint16_t Size);
uint16_t FLASH_ReadHalfWord(uint32_t faddr);
void FLASH_ReadData(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead);


#endif

3.2 flash读写代码的.c文件

#include "flash.h"

/*从指定地址开始写入数据*/
//FLASH_Addr:起始地址
//FLASH_Data:写入数据指针(写入的数据为16位,至少都要16位)
//Size:写入数据长度

void FLASH_WriteData(uint32_t FLASH_Addr, uint16_t *FLASH_Data, uint16_t Size)
{
	/*内部FLASH测试*/
	//1.解锁FLASH
	HAL_FLASH_Unlock();
	
	//2.擦除FALSH
	//初始化FLASH_EraseInitTypeDef
	FLASH_EraseInitTypeDef FLASH_Init;
	FLASH_Init.TypeErase = FLASH_TYPEERASE_PAGES;
	FLASH_Init.PageAddress = FLASH_Addr;
	FLASH_Init.NbPages = 1;
	
	uint32_t PageError = 0;
	
	//3.调用擦除函数
	HAL_FLASHEx_Erase(&FLASH_Init,&PageError);
	
	//4.对FLASH烧写
	uint16_t TempBuf = 0;
	for(uint16_t i=0;i<Size;i++)
	{
		TempBuf = *(FLASH_Data+i);
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,(FLASH_Addr + (i*2)),TempBuf);
	}
	
	//5.锁住FLASH
	HAL_FLASH_Lock();
}

//从指定地址读出数据
//faddr:地址
uint16_t FLASH_ReadHalfWord(uint32_t faddr)
{
	return *(__IO uint16_t*)faddr;
}

//从指定地址开始读出指定长度的数据
//ReadAddr:起始指针
//pBuffer:数据指针
//NumToRead:大小(至少半字(16位)数)
void FLASH_ReadData(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead)
{
	for(uint16_t i=0;i<NumToRead;i++)
	{
		pBuffer[i] = FLASH_ReadHalfWord(ReadAddr);
		ReadAddr+=2;
	}
}

3.3 代码的主函数(main)

int main(void)
{
  /* USER CODE BEGIN 1 */
   char Write_Data[10]="0123456789";
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	
	/*将Write_Data数据的内容写进FLASH*/
	FLASH_WriteData(FLASH_SAVE_ADDR,(uint16_t *)&Write_Data,10);
	
	/*从STM32 FLASH中读出写入的数据,将数据储存在Read_Data中*/
	FLASH_ReadData(FLASH_SAVE_ADDR,(uint16_t *)&Read_Data,10);
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		printf("FALSH = %s\r\n",Read_Data);
		HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
HAL库(Hardware Abstraction Layer,硬件抽象层)是STM32CubeMX的一部分,它提供了一种标准化的方式来访问STM32微控制器的各种功能,包括读写内部闪存。在STM32F4系列中,内部Flash通常用于存储程序代码、配置数据等。 以下是使用STM32CubeMX和HAL库通过代码来操作内部Flash的基本步骤: 1. **初始化**: 首先,在你的C代码中,需要包含相关的HAL库头文件,并初始化HAL库,例如 `stm32f4xx_hal_flash.h` 和 `stm32f4xx_hal_flash_ex.h`。 ```c #include "stm32f4xx_hal_flash.h" ... HAL_Init(); FLASH年由HAL_FLASH_Init()函数初始化; ``` 2. **选择Flash分区**: STM32F4有多种Flash分区,如Program Flash、Option Bytes等。你需要明确你要操作的是哪一块分区,比如使用`FLASH分区管理结构体`,如`FLASH分区结构体` (FLASH分区结构体)。 ```c FLASH分区_t flash分区; flash分区.Address = FLASH_REGION_1; // 设置分区地址 ``` 3. **擦除**: 使用`HAL_FLASH erased_ranges`函数选择要擦除的范围并执行擦除操作。 ```c FLASH_EraseOptionsTypeDef erase_options; erase_options.TypeOfOperation = FLASH_TYPEERASE; erase_options.EraseAllPages = ENABLE; HAL_FLASHEx_Erase(&flash分区, &erase_options); ``` 4. **编程**: 使用`HAL_FLASH_Program`函数将数据写入Flash。 ```c uint8_t data[] = {0x01, 0x02, 0x03}; // 数据字节数组 HAL_FLASH_Program(FLASH_WRITE, flash分区.Address, 0, sizeof(data), data); ``` 5. **等待操作完成**: 对于一些长时间的操作(如擦除),可能会有延时或确认请求,可以使用`HAL_Delay`等待或检查操作状态。 6. **处理异常**:记得捕获和处理可能出现的错误,比如`HAL_StatusTypeDef status = HAL_FLASHEx_WaitForLastOperationUntilEnd()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值