当前位置: 首页 > news >正文

STM32HAL库-F1内部Flash读写操作(官网驱动)

目录

一、代码

二、运行结果

三、总结



概述

        本文章内部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 ConfigurationPA9     ------> USART1_TXPA10     ------> 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 ConfigurationPA9     ------> USART1_TXPA10     ------> 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 printfset 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 --------------------------------------------------------*/#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;		//内部Flashuint8_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 (recommendedto 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 willbe 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 (recommendedto 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 willbe 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 willbe 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 combinaisonof 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 (recommendedto 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	5uint8_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 */

二、运行结果

三、总结

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

http://www.dtcms.com/a/585452.html

相关文章:

  • 辛集建设网站网络营销推广渠道
  • 外国排版网站企业名录2019企业黄页
  • 微信小程序开发实战:图片转 Base64 全解析
  • 秒杀-订单创建消费者CreateOrderConsumer
  • 单层前馈神经网络的万能逼近定理
  • C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown/KeyUp事件之间的区别
  • Windows系统不关闭防火墙,允许某个端口的访问怎么设置?
  • UniApp 多个异步开关控制教程
  • 邯郸哪家公司做企业网站比较专业中国制造网是干什么的
  • 做视频网站把视频放在哪里wordpress建站用什么意思
  • ASP.NET Core Web 应用SQLite数据连接显示(1)
  • 网易门户网站建设网站建设及发布的流程
  • 基于python的jlink单片机自动化批量烧录工具
  • 从三路快排到内省排序:探索工业级排序算法的演进
  • CPP 学习笔记 语法总结
  • Qt 跨平台 2048 游戏开发完整教程 (含源码)
  • SortScope 排序算法可视化
  • 组件库引入
  • 手写Spring第25弹:Spring JdbcTemplate深度解析:数据操作如此简单
  • 《Python 小程序编写系列》(第一部):从零开始写一个猜数字游戏
  • 【完整源码+数据集】草莓数据集,yolov8草莓成熟度检测数据集 3207 张,草莓成熟度数据集,目标检测草莓识别算法系统实战教程
  • 英特尔网站开发框架视频教学互动网站建设
  • DeepSeek-OCR实战(01):基础运行环境搭建-RockyLinux
  • 测开学习DAY26
  • VBA经典应用69例应用9:读取工作表中个数不定的数据
  • 网站建设策划书5000字蚂蚁网站建设
  • 【Janet】比较运算符
  • 05 kafka 如何存储较大数据记录
  • 使用Unity ASE插件设置数值不会生效的问题
  • 【ZeroRange WebRTC】WebRTC 信令安全:实现原理与应用(深入指南)