目录

一、代码

二、运行结果

三、总结



概述

        本文章内部Flash,驱动代码参考ST官网代码综合修改完成,调试没有问题,在此提供该大家参考,同时做个笔录也方便后续自己查阅,直接上代码。Flash合理分配方便后续添加IAP功能做准备。

硬件:STM32F103CBT6最小系统板
软件:Keil 5.29  + STM32CubeMX5.6.1
 

每个型号对应的FLASH操作都不一样,需要查阅对应的datasheet,这里不再赘述,也可以参考我这篇文章前面部分
 链接,网上也有类似文章。

想更详细的了解,请阅读《STM32中文参考手册》,自行上网查找资料下载。

一、代码

1、usart.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

UART_HandleTypeDef huart1;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
#include "stdio.h"

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
 
  return ch;
}
 
int fgetc(FILE * f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
/* USER CODE END 1 */

2、flash_if.h

/*
 * flash_if.h
 *
 *  Created on: September 5th, 2020
 *      Author: Champion
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FLASH_IF_H
#define __FLASH_IF_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

/* Base address of the Flash sectors -----------------------------------------*/
#define ADDR_FLASH_PAGE_0     ((uint32_t)0x08000000) /* Base @ of Page 0, 1 Kbytes */
#define ADDR_FLASH_PAGE_1     ((uint32_t)0x08000400) /* Base @ of Page 1, 1 Kbytes */
#define ADDR_FLASH_PAGE_2     ((uint32_t)0x08000800) /* Base @ of Page 2, 1 Kbytes */
#define ADDR_FLASH_PAGE_3     ((uint32_t)0x08000C00) /* Base @ of Page 3, 1 Kbytes */

#define ADDR_FLASH_PAGE_4     ((uint32_t)0x08001000) /* Base @ of Page 4, 1 Kbytes */
#define ADDR_FLASH_PAGE_5     ((uint32_t)0x08001400) /* Base @ of Page 5, 1 Kbytes */
#define ADDR_FLASH_PAGE_6     ((uint32_t)0x08001800) /* Base @ of Page 6, 1 Kbytes */
#define ADDR_FLASH_PAGE_7     ((uint32_t)0x08001C00) /* Base @ of Page 7, 1 Kbytes */

#define ADDR_FLASH_PAGE_8     ((uint32_t)0x08002000) /* Base @ of Page 8, 1 Kbytes */
#define ADDR_FLASH_PAGE_9     ((uint32_t)0x08002400) /* Base @ of Page 9, 1 Kbytes */
#define ADDR_FLASH_PAGE_10    ((uint32_t)0x08002800) /* Base @ of Page 10, 1 Kbytes */
#define ADDR_FLASH_PAGE_11    ((uint32_t)0x08002C00) /* Base @ of Page 11, 1 Kbytes */

#define ADDR_FLASH_PAGE_12    ((uint32_t)0x08003000) /* Base @ of Page 12, 1 Kbytes */
#define ADDR_FLASH_PAGE_13    ((uint32_t)0x08003400) /* Base @ of Page 13, 1 Kbytes */
#define ADDR_FLASH_PAGE_14    ((uint32_t)0x08003800) /* Base @ of Page 14, 1 Kbytes */
#define ADDR_FLASH_PAGE_15    ((uint32_t)0x08003C00) /* Base @ of Page 15, 1 Kbytes */

#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08004000) /* Base @ of Page 16, 1 Kbytes */
#define ADDR_FLASH_PAGE_17    ((uint32_t)0x08004400) /* Base @ of Page 17, 1 Kbytes */
#define ADDR_FLASH_PAGE_18    ((uint32_t)0x08004800) /* Base @ of Page 18, 1 Kbytes */
#define ADDR_FLASH_PAGE_19    ((uint32_t)0x08004C00) /* Base @ of Page 19, 1 Kbytes */

#define ADDR_FLASH_PAGE_20    ((uint32_t)0x08005000) /* Base @ of Page 20, 1 Kbytes */
#define ADDR_FLASH_PAGE_21    ((uint32_t)0x08005400) /* Base @ of Page 21, 1 Kbytes */
#define ADDR_FLASH_PAGE_22    ((uint32_t)0x08005800) /* Base @ of Page 22, 1 Kbytes */
#define ADDR_FLASH_PAGE_23    ((uint32_t)0x08005C00) /* Base @ of Page 23, 1 Kbytes */

#define ADDR_FLASH_PAGE_24    ((uint32_t)0x08006000) /* Base @ of Page 24, 1 Kbytes */
#define ADDR_FLASH_PAGE_25    ((uint32_t)0x08006400) /* Base @ of Page 25, 1 Kbytes */
#define ADDR_FLASH_PAGE_26    ((uint32_t)0x08006800) /* Base @ of Page 26, 1 Kbytes */
#define ADDR_FLASH_PAGE_27    ((uint32_t)0x08006C00) /* Base @ of Page 27, 1 Kbytes */

#define ADDR_FLASH_PAGE_28    ((uint32_t)0x08007000) /* Base @ of Page 28, 1 Kbytes */
#define ADDR_FLASH_PAGE_29    ((uint32_t)0x08007400) /* Base @ of Page 29, 1 Kbytes */
#define ADDR_FLASH_PAGE_30    ((uint32_t)0x08007800) /* Base @ of Page 30, 1 Kbytes */
#define ADDR_FLASH_PAGE_31    ((uint32_t)0x08007C00) /* Base @ of Page 31, 1 Kbytes */

#define ADDR_FLASH_PAGE_32    ((uint32_t)0x08008000) /* Base @ of Page 32, 1 Kbytes */
#define ADDR_FLASH_PAGE_33    ((uint32_t)0x08008400) /* Base @ of Page 33, 1 Kbytes */
#define ADDR_FLASH_PAGE_34    ((uint32_t)0x08008800) /* Base @ of Page 34, 1 Kbytes */
#define ADDR_FLASH_PAGE_35    ((uint32_t)0x08008C00) /* Base @ of Page 35, 1 Kbytes */

#define ADDR_FLASH_PAGE_36    ((uint32_t)0x08009000) /* Base @ of Page 36, 1 Kbytes */
#define ADDR_FLASH_PAGE_37    ((uint32_t)0x08009400) /* Base @ of Page 37, 1 Kbytes */
#define ADDR_FLASH_PAGE_38    ((uint32_t)0x08009800) /* Base @ of Page 38, 1 Kbytes */
#define ADDR_FLASH_PAGE_39    ((uint32_t)0x08009C00) /* Base @ of Page 39, 1 Kbytes */

#define ADDR_FLASH_PAGE_40    ((uint32_t)0x0800A000) /* Base @ of Page 40, 1 Kbytes */
#define ADDR_FLASH_PAGE_41    ((uint32_t)0x0800A400) /* Base @ of Page 41, 1 Kbytes */
#define ADDR_FLASH_PAGE_42    ((uint32_t)0x0800A800) /* Base @ of Page 42, 1 Kbytes */
#define ADDR_FLASH_PAGE_43    ((uint32_t)0x0800AC00) /* Base @ of Page 43, 1 Kbytes */

#define ADDR_FLASH_PAGE_44    ((uint32_t)0x0800B000) /* Base @ of Page 44, 1 Kbytes */
#define ADDR_FLASH_PAGE_45    ((uint32_t)0x0800B400) /* Base @ of Page 45, 1 Kbytes */
#define ADDR_FLASH_PAGE_46    ((uint32_t)0x0800B800) /* Base @ of Page 46, 1 Kbytes */
#define ADDR_FLASH_PAGE_47    ((uint32_t)0x0800BC00) /* Base @ of Page 47, 1 Kbytes */

#define ADDR_FLASH_PAGE_48    ((uint32_t)0x0800C000) /* Base @ of Page 48, 1 Kbytes */
#define ADDR_FLASH_PAGE_49    ((uint32_t)0x0800C400) /* Base @ of Page 49, 1 Kbytes */
#define ADDR_FLASH_PAGE_50    ((uint32_t)0x0800C800) /* Base @ of Page 50, 1 Kbytes */
#define ADDR_FLASH_PAGE_51    ((uint32_t)0x0800CC00) /* Base @ of Page 51, 1 Kbytes */

#define ADDR_FLASH_PAGE_52    ((uint32_t)0x0800D000) /* Base @ of Page 52, 1 Kbytes */
#define ADDR_FLASH_PAGE_53    ((uint32_t)0x0800D400) /* Base @ of Page 53, 1 Kbytes */
#define ADDR_FLASH_PAGE_54    ((uint32_t)0x0800D800) /* Base @ of Page 54, 1 Kbytes */
#define ADDR_FLASH_PAGE_55    ((uint32_t)0x0800DC00) /* Base @ of Page 55, 1 Kbytes */

#define ADDR_FLASH_PAGE_56    ((uint32_t)0x0800E000) /* Base @ of Page 56, 1 Kbytes */
#define ADDR_FLASH_PAGE_57    ((uint32_t)0x0800E400) /* Base @ of Page 57, 1 Kbytes */
#define ADDR_FLASH_PAGE_58    ((uint32_t)0x0800E800) /* Base @ of Page 58, 1 Kbytes */
#define ADDR_FLASH_PAGE_59    ((uint32_t)0x0800EC00) /* Base @ of Page 59, 1 Kbytes */

#define ADDR_FLASH_PAGE_60    ((uint32_t)0x0800F000) /* Base @ of Page 60, 1 Kbytes */
#define ADDR_FLASH_PAGE_61    ((uint32_t)0x0800F400) /* Base @ of Page 61, 1 Kbytes */
#define ADDR_FLASH_PAGE_62    ((uint32_t)0x0800F800) /* Base @ of Page 62, 1 Kbytes */
#define ADDR_FLASH_PAGE_63    ((uint32_t)0x0800FC00) /* Base @ of Page 63, 1 Kbytes */

#define ADDR_FLASH_PAGE_64    ((uint32_t)0x08010000) /* Base @ of Page 64, 1 Kbytes */
#define ADDR_FLASH_PAGE_65    ((uint32_t)0x08010400) /* Base @ of Page 65, 1 Kbytes */
#define ADDR_FLASH_PAGE_66    ((uint32_t)0x08010800) /* Base @ of Page 66, 1 Kbytes */
#define ADDR_FLASH_PAGE_67    ((uint32_t)0x08010C00) /* Base @ of Page 67, 1 Kbytes */

#define ADDR_FLASH_PAGE_68    ((uint32_t)0x08011000) /* Base @ of Page 68, 1 Kbytes */
#define ADDR_FLASH_PAGE_69    ((uint32_t)0x08011400) /* Base @ of Page 69, 1 Kbytes */
#define ADDR_FLASH_PAGE_70    ((uint32_t)0x08011800) /* Base @ of Page 70, 1 Kbytes */
#define ADDR_FLASH_PAGE_71    ((uint32_t)0x08011C00) /* Base @ of Page 71, 1 Kbytes */

#define ADDR_FLASH_PAGE_72    ((uint32_t)0x08012000) /* Base @ of Page 72, 1 Kbytes */
#define ADDR_FLASH_PAGE_73    ((uint32_t)0x08012400) /* Base @ of Page 73, 1 Kbytes */
#define ADDR_FLASH_PAGE_74    ((uint32_t)0x08012800) /* Base @ of Page 74, 1 Kbytes */
#define ADDR_FLASH_PAGE_75    ((uint32_t)0x08012C00) /* Base @ of Page 75, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_76    ((uint32_t)0x08013000) /* Base @ of Page 76, 1 Kbytes */
#define ADDR_FLASH_PAGE_77    ((uint32_t)0x08013400) /* Base @ of Page 77, 1 Kbytes */
#define ADDR_FLASH_PAGE_78    ((uint32_t)0x08013800) /* Base @ of Page 78, 1 Kbytes */
#define ADDR_FLASH_PAGE_79    ((uint32_t)0x08013C00) /* Base @ of Page 79, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_80    ((uint32_t)0x08014000) /* Base @ of Page 80, 1 Kbytes */
#define ADDR_FLASH_PAGE_81    ((uint32_t)0x08014400) /* Base @ of Page 81, 1 Kbytes */
#define ADDR_FLASH_PAGE_82    ((uint32_t)0x08014800) /* Base @ of Page 82, 1 Kbytes */
#define ADDR_FLASH_PAGE_83    ((uint32_t)0x08014C00) /* Base @ of Page 83, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_84    ((uint32_t)0x08015000) /* Base @ of Page 84, 1 Kbytes */
#define ADDR_FLASH_PAGE_85    ((uint32_t)0x08015400) /* Base @ of Page 85, 1 Kbytes */
#define ADDR_FLASH_PAGE_86    ((uint32_t)0x08015800) /* Base @ of Page 86, 1 Kbytes */
#define ADDR_FLASH_PAGE_87    ((uint32_t)0x08015C00) /* Base @ of Page 87, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_88    ((uint32_t)0x08016000) /* Base @ of Page 88, 1 Kbytes */
#define ADDR_FLASH_PAGE_89    ((uint32_t)0x08016400) /* Base @ of Page 89, 1 Kbytes */
#define ADDR_FLASH_PAGE_90    ((uint32_t)0x08016800) /* Base @ of Page 90, 1 Kbytes */
#define ADDR_FLASH_PAGE_91    ((uint32_t)0x08016C00) /* Base @ of Page 91, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_92    ((uint32_t)0x08017000) /* Base @ of Page 92, 1 Kbytes */
#define ADDR_FLASH_PAGE_93    ((uint32_t)0x08017400) /* Base @ of Page 93, 1 Kbytes */
#define ADDR_FLASH_PAGE_94    ((uint32_t)0x08017800) /* Base @ of Page 94, 1 Kbytes */
#define ADDR_FLASH_PAGE_95    ((uint32_t)0x08017C00) /* Base @ of Page 95, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_96    ((uint32_t)0x08018000) /* Base @ of Page 96, 1 Kbytes */
#define ADDR_FLASH_PAGE_97    ((uint32_t)0x08018400) /* Base @ of Page 97, 1 Kbytes */
#define ADDR_FLASH_PAGE_98    ((uint32_t)0x08018800) /* Base @ of Page 98, 1 Kbytes */
#define ADDR_FLASH_PAGE_99    ((uint32_t)0x08018C00) /* Base @ of Page 99, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_100   ((uint32_t)0x08019000) /* Base @ of Page 100, 1 Kbytes */
#define ADDR_FLASH_PAGE_101   ((uint32_t)0x08019400) /* Base @ of Page 101, 1 Kbytes */
#define ADDR_FLASH_PAGE_102   ((uint32_t)0x08019800) /* Base @ of Page 102, 1 Kbytes */
#define ADDR_FLASH_PAGE_103   ((uint32_t)0x08019C00) /* Base @ of Page 103, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_104   ((uint32_t)0x0801A000) /* Base @ of Page 104, 1 Kbytes */
#define ADDR_FLASH_PAGE_105   ((uint32_t)0x0801A400) /* Base @ of Page 105, 1 Kbytes */
#define ADDR_FLASH_PAGE_106   ((uint32_t)0x0801A800) /* Base @ of Page 106, 1 Kbytes */
#define ADDR_FLASH_PAGE_107   ((uint32_t)0x0801AC00) /* Base @ of Page 107, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_108   ((uint32_t)0x0801B000) /* Base @ of Page 108, 1 Kbytes */
#define ADDR_FLASH_PAGE_109   ((uint32_t)0x0801B400) /* Base @ of Page 109, 1 Kbytes */
#define ADDR_FLASH_PAGE_110   ((uint32_t)0x0801B800) /* Base @ of Page 110, 1 Kbytes */
#define ADDR_FLASH_PAGE_111   ((uint32_t)0x0801BC00) /* Base @ of Page 111, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_112   ((uint32_t)0x0801C000) /* Base @ of Page 112, 1 Kbytes */
#define ADDR_FLASH_PAGE_113   ((uint32_t)0x0801C400) /* Base @ of Page 113, 1 Kbytes */
#define ADDR_FLASH_PAGE_114   ((uint32_t)0x0801C800) /* Base @ of Page 114, 1 Kbytes */
#define ADDR_FLASH_PAGE_115   ((uint32_t)0x0801CC00) /* Base @ of Page 115, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_116   ((uint32_t)0x0801D000) /* Base @ of Page 116, 1 Kbytes */
#define ADDR_FLASH_PAGE_117   ((uint32_t)0x0801D400) /* Base @ of Page 117, 1 Kbytes  */
#define ADDR_FLASH_PAGE_118   ((uint32_t)0x0801D800) /* Base @ of Page 118, 1 Kbytes  */
#define ADDR_FLASH_PAGE_119   ((uint32_t)0x0801DC00) /* Base @ of Page 119, 1 Kbytes */
                              
#define ADDR_FLASH_PAGE_120   ((uint32_t)0x0801E000) /* Base @ of Page 120, 1 Kbytes */
#define ADDR_FLASH_PAGE_121   ((uint32_t)0x0801E400) /* Base @ of Page 121, 1 Kbytes */
#define ADDR_FLASH_PAGE_122   ((uint32_t)0x0801E800) /* Base @ of Page 122, 1 Kbytes */
#define ADDR_FLASH_PAGE_123   ((uint32_t)0x0801EC00) /* Base @ of Page 123, 1 Kbytes */

#define ADDR_FLASH_PAGE_124   ((uint32_t)0x0801F000) /* Base @ of Page 124, 1 Kbytes */
#define ADDR_FLASH_PAGE_125   ((uint32_t)0x0801F400) /* Base @ of Page 125, 1 Kbytes */
#define ADDR_FLASH_PAGE_126   ((uint32_t)0x0801F800) /* Base @ of Page 126, 1 Kbytes */
#define ADDR_FLASH_PAGE_127   ((uint32_t)0x0801FC00) /* Base @ of Page 127, 1 Kbytes */

/* Base address of the Flash sectors -----------------------------------------*/


#ifdef STORAGE_BLK_SIZ
#undef STORAGE_BLK_SIZ
#endif

#ifdef STORAGE_BLK_NBR
#undef STORAGE_BLK_NBR
#endif

//#ifdef STORAGE_LUN_NBR
//#undef STORAGE_LUN_NBR
//#endif

//#define STORAGE_LUN_NBR                  1u
#define STORAGE_BLOCK_SIZE   	         (2) 
#define STORAGE_BLK_SIZ                  (1024/STORAGE_BLOCK_SIZE)  		
#define STORAGE_BLK_NBR                  ((50*1024)/STORAGE_BLK_SIZ) 	

//分配地址以页对齐

//#define FLASH_PAGE_SIZE	   1024 					         	             	 //1 Kbyte per page
#define FLASH_START_ADDR	   0x08000000					                    	 //Origin
#define FLASH_MAX_SIZE		   0x00020000					                    	 //Max FLASH size = 128 Kbyte
#define FLASH_END_ADDR		   (FLASH_START_ADDR + FLASH_MAX_SIZE)	       		 //FLASH end address
#define FLASH_BOOT_START_ADDR  (FLASH_START_ADDR)				                 //Bootloader start address
#define FLASH_BOOT_SIZE		   0x00006800				   	                     	 //26 Kbyte for bootloader
#define FLASH_APP_START_ADDR   (FLASH_BOOT_START_ADDR + FLASH_BOOT_SIZE)          //User application start address
#define FLASH_APP_SIZE		   0x0000C800					                         //50 Kbyte for user application
#define FLASH_MSD_START_ADDR   (FLASH_APP_START_ADDR + FLASH_APP_SIZE)           //USB MSD start address
#define FLASH_MSD_SIZE	       0x0000c800					                     	 //50 Kbyte for USB MASS Storage
#define FLASH_OTHER_START_ADDR (FLASH_MSD_START_ADDR + FLASH_MSD_SIZE)		     //Other free memory start address
#define FLASH_OTHER_SIZE	   (FLASH_END_ADDR - FLASH_OTHER_START_ADDR) 	 	 //Free memory size		2Kbyte

#define FLASH_MSD_BLK_NBR		 ((FLASH_END_ADDR - FLASH_MSD_START_ADDR - FLASH_OTHER_SIZE) / 1024)	//50块
//#define FLASH_MSD_BLK_NBR		 ((FLASH_END_ADDR - FLASH_MSD_START_ADDR) / 1024)	//100块

//#define FLASH_START_ADDR_1	0x08008000


#pragma pack (1) 
typedef struct
{
	uint32_t FLASH_SIZE;					/* Get flash size */	
	uint32_t SECTOR_COUNT;					/* Get media size */	
	uint32_t SECTOR_SIZE;					/* Get sector size */
	uint32_t BLOCK_SIZE;					/* Block Size in Bytes */
	uint32_t STORAGE_LUN_NBr;				/* 分区   */
	uint32_t STORAGE_BLOCK_NBR;				/* 块数量(U盘总容量) */
	uint32_t STORAGE_BLOCK_SIZ;				/* 块大小(U盘分配单元大小) */
	uint32_t PAGE_SIZE;
}Flash_Parameter;
#pragma pack () 
extern Flash_Parameter Flash_Paramet;


/* Error code */ 
enum 
{
  FLASHIF_OK = 0,
  FLASHIF_ERASEKO,
  FLASHIF_WRITINGCTRL_ERROR,
  FLASHIF_WRITING_ERROR,
  FLASHIF_PROTECTION_ERRROR
};

/* protection type */  
enum{
  FLASHIF_PROTECTION_NONE         = 0,
  FLASHIF_PROTECTION_PCROPENABLED = 0x1,
  FLASHIF_PROTECTION_WRPENABLED   = 0x2,
  FLASHIF_PROTECTION_RDPENABLED   = 0x4,
};

/* protection update */
enum {
	FLASHIF_WRP_ENABLE,
	FLASHIF_WRP_DISABLE
};

/* Define the address from where user application will be loaded.
   Note: this area is reserved for the IAP code                  */
#define FLASH_PAGE_STEP         FLASH_PAGE_SIZE           /* Size of page : 1024 Kbytes */
#define APPLICATION_ADDRESS     FLASH_USER_APP_START_ADDR  			//(uint32_t)0x08008000      

/* Notable Flash addresses */
#define USER_FLASH_END_ADDRESS        FLASH_END_ADDR

///* Define the user application size */
#define USER_FLASH_SIZE               FLASH_BOOT_SIZE     /* Small default template application */

/* Define bitmap representing user flash area that could be write protected (check restricted to pages 3-63). */
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES0TO3 | OB_WRP_PAGES4TO7 | OB_WRP_PAGES8TO11 | OB_WRP_PAGES12TO15 | \
									OB_WRP_PAGES16TO19 | OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 | \
									OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 | \
									OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63  )

extern uint32_t AppAddresssCurren;

/* Exported functions ------------------------------------------------------- */
void FLASH_If_Init(void);
uint32_t FLASH_If_Erase(uint32_t startSectorAddr, uint32_t NbrOfPages);
uint32_t FLASH_If_GetWriteProtectionStatus(void);
uint32_t FLASH_If_Write(uint32_t FlashAddress, uint32_t* pData, uint32_t DataLength);
uint32_t FLASH_If_Write2Byte(uint32_t FlashAddress, uint16_t* pData, uint32_t DataLength);
uint32_t FLASH_If_WriteProtectionConfig(uint32_t protectionstate);
uint32_t FLASH_If_Read(uint32_t FlashAddress, uint32_t* pData, uint32_t DataLength);
uint32_t FLASH_If_Read2Byte(uint32_t FlashAddress, uint16_t* pData, uint32_t DataLength);


uint32_t FLASH_If_Write_Ex(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength, uint8_t is32bit);
uint32_t FLASH_If_Read_Ex(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength, uint8_t is32bit);
#endif  /* __FLASH_IF_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

3、flash_if.c

/*
 * flash_if.c
 *
 *  Created on: September 5th, 2020
 *      Author: Champion
 */


/** @addtogroup STM32F1xx_IAP
  * @{
  */

/* Includes ------------------------------------------------------------------*/
#include "flash_if.h"
#include "stdio.h"

uint32_t AppAddresssCurren = 0;
Flash_Parameter Flash_Paramet;		//内部Flash

uint8_t FLASH_Parameter_Init(Flash_Parameter *Para)
{
	
	Para->FLASH_SIZE   = FLASH_MAX_SIZE;
	Para->SECTOR_COUNT = 45;									/* Get media size */		
	Para->SECTOR_SIZE  = 1024;									/* Get sector size */
	Para->BLOCK_SIZE   = 1024;
	
	Para->STORAGE_LUN_NBr     = 1;							/* 分区   */
	Para->STORAGE_BLOCK_NBR   = 45;	            			/* 块数量 */
	Para->STORAGE_BLOCK_SIZ   = 512;						/* 块大小 */
	Para->PAGE_SIZE    = FLASH_PAGE_SIZE;		    		/* 每一页大小 1024Kbyte */
	
	return 0;
}

/**
  * @brief  Unlocks Flash for write access
  * @param  None
  * @retval None
  */
void FLASH_If_Init(void)
{
  /* Unlock the Program memory */
  HAL_FLASH_Unlock();

  /* Clear all FLASH flags */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
//  /* Unlock the Program memory */
//  HAL_FLASH_Lock();
	
	FLASH_Parameter_Init(&Flash_Paramet);
}

/**
  * @brief  Locks Flash for write access
  * @param  None
  * @retval None
  */
void FLASH_If_DeInit(void)
{
  HAL_FLASH_Lock();
}


/**
  * @brief  This function does an erase of all user flash area
  * @param  startSectorAddr: start of user flash area
  * @retval FLASHIF_OK : user flash area successfully erased
  *         FLASHIF_ERASEKO : error occurred
  */
uint32_t FLASH_If_Erase(uint32_t startSectorAddr, uint32_t NbrOfPages)
{
  uint32_t NbrPages = 0;
  uint32_t PageError = 0;
  FLASH_EraseInitTypeDef pEraseInit;
  HAL_StatusTypeDef status = HAL_OK;

  /* Unlock the Flash to enable the flash control register access *************/ 
  HAL_FLASH_Unlock();

  /* Get the sector where start the user flash area */
  NbrPages = (FLASH_END_ADDR - startSectorAddr)/FLASH_PAGE_SIZE;
  if(NbrOfPages > NbrPages)	
	return FLASHIF_ERASEKO;

  pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  pEraseInit.PageAddress = startSectorAddr;
  pEraseInit.Banks = FLASH_BANK_1;
  pEraseInit.NbPages = NbrOfPages;
  status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();

  if (status != HAL_OK)
  {
    /* Error occurred while page erase */
    return FLASHIF_ERASEKO;
  }

  return FLASHIF_OK;
}

/* Public functions ---------------------------------------------------------*/
/**
  * @brief  This function writes a data buffer in flash (data are 32-bit aligned).
  * @note   After writing data buffer, the flash content is checked.
  * @param  FlashAddress: start address for target location
  * @param  pData: pointer on buffer with data to write
  * @param  DataLength: length of data buffer (unit is 32-bit word)
  * @retval uint32_t 0: Data successfully written to Flash memory
  *         1: Error occurred while writing data in Flash memory
  *         2: Written Data in flash memory is different from expected one
  */
uint32_t FLASH_If_Write(uint32_t FlashAddress, uint32_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;

  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();

  for (i = 0; (i < DataLength) && (FlashAddress <= (FLASH_END_ADDR-4)); i++)
  {
    /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
       be done by word */ 
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(pData+i)) == HAL_OK)      
    {
		printf("> Word FlashAddress:0x%X, pData[%d]:0x%X\r\n", FlashAddress, i, pData[i]);
     /* Check the written value */
      if (*(uint32_t*)FlashAddress != *(uint32_t*)(pData+i))
      {
        /* Flash content doesn't match SRAM content */
		  printf("Word FLASHIF_WRITINGCTRL_ERROR\r\n");
        return(FLASHIF_WRITINGCTRL_ERROR);
      }
      /* Increment FLASH destination address */
      FlashAddress += 4;
    }
    else
    {
      /* Error occurred while writing data in Flash memory */
		printf("Word FLASHIF_WRITING_ERROR\r\n");
      return (FLASHIF_WRITING_ERROR);
    }
  }

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  printf("Word FLASHIF_OK\r\n");
  HAL_FLASH_Lock();

  return (FLASHIF_OK);
}

uint32_t FLASH_If_Write2Byte(uint32_t FlashAddress, uint16_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;

  FLASH_If_Init();
  for (i = 0; (i < DataLength) && (FlashAddress <= USER_FLASH_END_ADDRESS); i++)
  {
    /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
       be done by halfword */
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, pData[i]) == HAL_OK)
    {
		printf("> HalfWord FlashAddress:0x02%X, pData[%d]:0x%X\r\n", FlashAddress, i, pData[i]);
     /* Check the written value */
      if (*(uint16_t*)FlashAddress != pData[i])
      {
    	 FLASH_If_DeInit();
        /* Flash content doesn't match SRAM content */
		  printf("HalfWord FLASHIF_WRITINGCTRL_ERROR\r\n");
        return(FLASHIF_WRITINGCTRL_ERROR);
      }
      /* Increment FLASH destination address */
      FlashAddress += 2;
    }
    else
    {
      FLASH_If_DeInit();
      /* Error occurred while writing data in Flash memory */
		printf("HalfWord FLASHIF_WRITING_ERROR\r\n");
      return (FLASHIF_WRITING_ERROR);
    }
  }

  FLASH_If_DeInit();
  printf("HalfWord FLASHIF_OK\r\n");
  return (FLASHIF_OK);
}

uint32_t FLASH_If_WriteByte(uint32_t FlashAddress, uint8_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;
//  uint16_t pData_t = ((*pData << 8) | (*pData & 0x00));
	
  FLASH_If_Init();
  for (i = 0; (i < DataLength) && (FlashAddress <= USER_FLASH_END_ADDRESS); i++)
  {
    /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
       be done by halfword */
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, pData[i]) == HAL_OK)
    {
		printf("> Byte FlashAddress:0x02%X, pData_t[%d]:0x%X\r\n", FlashAddress, i, pData[i]);
     /* Check the written value */
      if (*(uint16_t*)FlashAddress != pData[i])
      {
    	 FLASH_If_DeInit();
        /* Flash content doesn't match SRAM content */
		  printf("Byte FLASHIF_WRITINGCTRL_ERROR\r\n");
        return(FLASHIF_WRITINGCTRL_ERROR);
      }
      /* Increment FLASH destination address */
      FlashAddress += 2;
    }
    else
    {
      FLASH_If_DeInit();
      /* Error occurred while writing data in Flash memory */
		printf("Byte FLASHIF_WRITING_ERROR\r\n");
      return (FLASHIF_WRITING_ERROR);
    }
  }

  FLASH_If_DeInit();
  printf("Byte FLASHIF_OK\r\n");
  return (FLASHIF_OK);
}

uint32_t FLASH_If_Read(uint32_t FlashAddress, uint32_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;

  for(i = 0; i < DataLength; i++)
  {
	  pData[i] = *(uint32_t*)FlashAddress;
	  FlashAddress += 4;
  }

  return (FLASHIF_OK);
}

uint32_t FLASH_If_Read2Byte(uint32_t FlashAddress, uint16_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;

  for(i = 0; i < DataLength; i++)
  {
	  pData[i] = *(uint16_t*)FlashAddress;
	  FlashAddress += 2;
  }

  return (FLASHIF_OK);
}

uint32_t FLASH_If_ReadByte(uint32_t FlashAddress, uint8_t* pData, uint32_t DataLength)
{
  uint32_t i = 0;

  for(i = 0; i < DataLength; i++)
  {
	  pData[i] = *(uint16_t*)FlashAddress;
	  FlashAddress += 2;
  }

  return (FLASHIF_OK);
}


/**
  * @brief  Returns the write protection status of application flash area.
  * @param  None
  * @retval If a sector in application area is write-protected returned value is a combinaison
            of the possible values : FLASHIF_PROTECTION_WRPENABLED, FLASHIF_PROTECTION_PCROPENABLED, ...
  *         If no sector is write-protected FLASHIF_PROTECTION_NONE is returned.
  */
uint32_t FLASH_If_GetWriteProtectionStatus(void)
{
  uint32_t ProtectedPAGE = FLASHIF_PROTECTION_NONE;
  FLASH_OBProgramInitTypeDef OptionsBytesStruct;

  /* Unlock the Flash to enable the flash control register access *************/
  FLASH_If_Init();

  /* Check if there are write protected sectors inside the user flash area ****/
  HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  FLASH_If_DeInit();

  /* Get pages already write protected ****************************************/
  ProtectedPAGE = ~(OptionsBytesStruct.WRPPage) & FLASH_PAGE_TO_BE_PROTECTED;

  /* Check if desired pages are already write protected ***********************/
  if(ProtectedPAGE != 0)
  {
    /* Some sectors inside the user flash area are write protected */
    return FLASHIF_PROTECTION_WRPENABLED;
  }
  else
  { 
    /* No write protected sectors inside the user flash area */
    return FLASHIF_PROTECTION_NONE;
  }
}

/**
  * @brief  Configure the write protection status of user flash area.
  * @param  protectionstate : FLASHIF_WRP_DISABLE or FLASHIF_WRP_ENABLE the protection
  * @retval uint32_t FLASHIF_OK if change is applied.
  */
uint32_t FLASH_If_WriteProtectionConfig(uint32_t protectionstate)
{
  uint32_t ProtectedPAGE = 0x0;
  FLASH_OBProgramInitTypeDef config_new, config_old;
  HAL_StatusTypeDef result = HAL_OK;
  

  /* Get pages write protection status ****************************************/
  HAL_FLASHEx_OBGetConfig(&config_old);

  /* The parameter says whether we turn the protection on or off */
  config_new.WRPState = (protectionstate == FLASHIF_WRP_ENABLE ? OB_WRPSTATE_ENABLE : OB_WRPSTATE_DISABLE);

  /* We want to modify only the Write protection */
  config_new.OptionType = OPTIONBYTE_WRP;
  
  /* No read protection, keep BOR and reset settings */
  config_new.RDPLevel = OB_RDP_LEVEL_0;
  config_new.USERConfig = config_old.USERConfig;  
  /* Get pages already write protected ****************************************/
  ProtectedPAGE = config_old.WRPPage | FLASH_PAGE_TO_BE_PROTECTED;

  /* Unlock the Flash to enable the flash control register access *************/ 
  FLASH_If_Init();

  /* Unlock the Options Bytes *************************************************/
  HAL_FLASH_OB_Unlock();
  
  /* Erase all the option Bytes ***********************************************/
  result = HAL_FLASHEx_OBErase();
    
  if (result == HAL_OK)
  {
    config_new.WRPPage    = ProtectedPAGE;
    result = HAL_FLASHEx_OBProgram(&config_new);
  }
  
  return (result == HAL_OK ? FLASHIF_OK: FLASHIF_PROTECTION_ERRROR);
}
/**
  * @}
  */


uint32_t FLASH_If_Write_Ex(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength, uint8_t is32bit) 
{
//    uint8_t is32bit = (((uint32_t)Data)%4)? 0 : 1;
	
    FLASH_If_Init();
    
    if (FLASH_If_Erase(FlashAddress, 1) != FLASHIF_OK) {
        printf("Erase_error \n");
    }
    
	if (is32bit == 1) {
		FLASH_If_Write(FlashAddress, (uint32_t*)Data, DataLength);
	} else {
		FLASH_If_Write2Byte(FlashAddress, (uint16_t*)Data, DataLength);
	}
    return (FLASHIF_OK);
}
 
uint32_t FLASH_If_Read_Ex(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength, uint8_t is32bit)
{    
//	uint8_t is32bit = (((uint32_t)Data)%4)? 0 : 1;
	
    FLASH_If_Init();
    
    if (is32bit == 1) {
        FLASH_If_Read(FlashAddress, (uint32_t*)Data, DataLength);
    } else {
		FLASH_If_Read2Byte(FlashAddress, (uint16_t*)Data, DataLength);
	}
    return (FLASHIF_OK);
} 


void Flash_ErasePage(uint32_t pageAddr)
{
	FLASH_EraseInitTypeDef EraseInitTypeDef;
	uint32_t pageError = 0;
	
	HAL_FLASH_Unlock();
	
	EraseInitTypeDef.TypeErase = FLASH_TYPEERASE_PAGES;
	EraseInitTypeDef.PageAddress = pageAddr;
	EraseInitTypeDef.NbPages = 1;
	
	if (HAL_FLASHEx_Erase(&EraseInitTypeDef, &pageError) != HAL_OK) {
		//打印错误码
	}
	
	HAL_FLASH_Lock();
}

HAL_StatusTypeDef Flash_WriteHalfWord(uint32_t FlashAddress, uint16_t Data)
{
	HAL_StatusTypeDef status;
	HAL_FLASH_Unlock();
	
	status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, Data);
	
	if (status != HAL_OK) {
		return HAL_ERROR;
	}
	
	HAL_FLASH_Lock();
	
	return (HAL_OK);
}

uint16_t Flash_ReadHalfWord(uint32_t FlashAddress)
{
	return *(__IO uint16_t*) FlashAddress;
}

void Flash_WriteBuffer(uint32_t FlashAddress, uint16_t* pData, uint32_t Len)
{
	HAL_FLASH_Unlock();
	
	for(uint32_t i = 0; i < Len; i++)
	{
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress + i*2, pData[i]);
	}
	
	HAL_FLASH_Lock();
}

void Flash_ReadBuffer(uint32_t FlashAddress, uint16_t* pData, uint32_t Len)
{
	for(uint32_t i = 0; i < Len; i++)
	{
		pData[i] = *(__IO uint16_t*) (FlashAddress + i*2);
	}
}


void test_flash_demo(void)
{
	#define DATA_LEN	5

	uint8_t write_data_8[DATA_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55};
	uint8_t read_data_8[DATA_LEN] = {0};

	uint16_t write_data_16[DATA_LEN] = {0x1111, 0x2222, 0x3333, 0x4444, 0x5555};
	uint16_t read_data_16[DATA_LEN] = {0};

	uint32_t write_data_32[DATA_LEN] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555};
	uint32_t read_data_32[DATA_LEN] = {0};
	
//	Flash_ErasePage(FLASH_APP_START_ADDR);
	
//	FLASH_If_Erase(FLASH_APP_START_ADDR, 1);
	
//	Flash_WriteBuffer(FLASH_APP_START_ADDR, write_data_16, DATA_LEN);
	
//	Flash_ReadBuffer(FLASH_APP_START_ADDR, read_data_16, DATA_LEN);
//	for (uint16_t i = 0; i < DATA_LEN; i++)
//	{
//		printf("FLASH_OTHER_START_ADDR:0x%X, read_data_16[%d]:0x%X\r\n", FLASH_APP_START_ADDR + i*2, i, read_data_16[i]);
//	}
	
//	FLASH_If_Erase(FLASH_OTHER_START_ADDR, 1);
//	FLASH_If_Write(FLASH_OTHER_START_ADDR, write_data_32, DATA_LEN);
//	FLASH_If_Read(FLASH_OTHER_START_ADDR, read_data_32, DATA_LEN);
//	for (uint8_t i = 0; i < DATA_LEN; i++)
//	{
//		printf("FLASH_APP_START_ADDR:0x%X, read_data_32[%d]:0x%X\r\n", FLASH_OTHER_START_ADDR + i*4, i, read_data_32[i]);
//	}
	
	FLASH_If_Write_Ex(FLASH_OTHER_START_ADDR, (uint32_t*)write_data_32, DATA_LEN, 1);
	FLASH_If_Read_Ex(FLASH_OTHER_START_ADDR, (uint32_t*)read_data_32, DATA_LEN, 1);
	for (uint16_t i = 0; i < DATA_LEN; i++)
	{
		printf("FLASH_OTHER_START_ADDR:0x%X, read_data_16[%d]:0x%X\r\n", FLASH_OTHER_START_ADDR + i*4, i, read_data_32[i]);
	}
	
	FLASH_If_Erase(FLASH_APP_START_ADDR, 1);
	FLASH_If_Write2Byte(FLASH_APP_START_ADDR, (uint16_t*)write_data_16, DATA_LEN);
	FLASH_If_Read2Byte(FLASH_APP_START_ADDR, (uint16_t*)read_data_16, DATA_LEN);
	
	for (uint16_t i = 0; i < DATA_LEN; i++)
	{
		printf("FLASH_OTHER_START_ADDR:0x%X, read_data_16[%d]:0x%X\r\n", FLASH_APP_START_ADDR + i*2, i, read_data_16[i]);
	}	
	
	FLASH_If_Erase(FLASH_MSD_START_ADDR, 1);
	FLASH_If_WriteByte(FLASH_MSD_START_ADDR, write_data_8, DATA_LEN);
	FLASH_If_ReadByte(FLASH_MSD_START_ADDR, read_data_8, DATA_LEN);
	
	for (uint16_t i = 0; i < DATA_LEN; i++)
	{
		printf("FLASH_OTHER_START_ADDR:0x%X, read_data_16[%d]:0x%X\r\n", FLASH_MSD_START_ADDR + i*2, i, read_data_8[i]);
	}
}


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

4、main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "flash_if.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* 创建产品信息文件 */
void create_product_info_file(void)
{
  FIL file;
  UINT bw;
  char info[] = "产品名称: STM32F103设备\n版本号: 1.0.0\n制造商: Your Company";
  
  if (f_open(&file, "产品信息.txt", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) {
    f_write(&file, info, strlen(info), &bw);
    f_close(&file);
  }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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();
  MX_FATFS_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */

	create_product_info_file();
	
	printf ("-----START LOG----- \n\r\n\r");
	printf ("FLASH_START_ADDR     : %#x \n\r", FLASH_START_ADDR);
	printf ("FLASH_MAX_SIZE       : %dKByte \n\r", FLASH_MAX_SIZE/1024);
	printf ("BOOT_START_ADDR      : %#x \n\r", FLASH_BOOT_START_ADDR);
	printf ("BOOT_MEM_SIZE        : %dKByte \n\r", FLASH_BOOT_SIZE/1024);
	printf ("APP_START_ADDR       : %#x \n\r", FLASH_APP_START_ADDR);
	printf ("APP_MEM_SIZE         : %dKByte \n\r", FLASH_APP_SIZE/1024);
	printf ("FLASH_MSD_START_ADDR : %#x \n\r", FLASH_MSD_START_ADDR);
	printf ("MSD_MEM_SIZE         : %dKByte \n\r", FLASH_MSD_SIZE/1024);
	printf ("OTHER_START_ADDR     : %#x \n\r", FLASH_OTHER_START_ADDR);
	printf ("OTHER_MEM_SIZE       : %dKByte \n\r\n\r", FLASH_OTHER_SIZE/1024);
	printf ("FLASH_MSD_BLK_NBR    : %dKByte \n\r\n\r", FLASH_MSD_BLK_NBR);

	extern void test_flash_demo(void);
	test_flash_demo();


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  	  printf("Runing, I'm an MSD USB Bootloader... \r\n");
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

二、运行结果

三、总结

      好了,就介绍到此,感谢参阅,小小心得分享,希望能帮助到需要的攻城狮们^_^。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐