first commit

This commit is contained in:
2026-01-24 20:03:14 +08:00
commit a2224908e3
318 changed files with 278538 additions and 0 deletions

124
Users/File_Handle.c Normal file
View File

@@ -0,0 +1,124 @@
/******************************************************************************
* @file File_Handle.c
* @brief BMP图片文件处理和Flash存储管理文件
* @details 本文件实现了BMP图片文件的处理功能包括BMP文件头结构定义、
* Flash存储读写操作、LOGO图片的保存和显示等功能。
* 支持将BMP格式的LOGO图片数据保存到Flash中并在需要时读取显示。
* @author 阜阳师范大学物电学院
* @version V0.1
* @date 2026.1.23
* @note Flash存储地址0x0803F000扇区126
* Flash扇区大小2KB
* BMP数据长度3208字节
******************************************************************************/
/* ============================================================================
* 头文件包含
* ============================================================================ */
#include "filehandle.h"
#include <string.h>
#include <stdio.h>
/* ============================================================================
* 私有宏定义
* ============================================================================ */
#define Flash_EndAddr (0x08040000) /**< Flash存储结束地址 */
#define SECTOR_SIZE (2048) /**< Flash扇区大小单位字节2KB */
/* ============================================================================
* Flash存储操作函数
* ============================================================================ */
/**
* @brief 向Flash写入多个16位数据
* @param startAddress 起始写入地址必须是Flash地址范围内的有效地址
* @param writeData 要写入的数据指针16位数据数组
* @param countToWrite 要写入的数据个数16位数据个数
* @note 本函数实现了Flash的批量写入功能支持跨扇区写入
* 1. 自动计算需要擦除的扇区数量和位置
* 2. 在写入前自动擦除相关扇区
* 3. 按半字16位方式写入数据
* 4. 自动处理Flash的解锁和上锁
* 5. 进行地址合法性检查
* 注意Flash写入前必须先擦除擦除以扇区为单位2KB
* 对于STM32F103VFlash地址范围0x08000000~0x0803FFFF
* @retval HAL_StatusTypeDef 操作状态HAL_OK=成功HAL_ERROR=失败
*/
HAL_StatusTypeDef FLASH_WriteMoreData(uint32_t startAddress, uint16_t *writeData, uint16_t countToWrite)
{
/* 计算去掉Flash基地址0x08000000后的实际偏移地址 */
uint32_t offsetAddress = startAddress - FLASH_BASE;
/* 计算扇区位置,对于 STM32F103V 为0~127 */
uint32_t sectorPosition = offsetAddress / SECTOR_SIZE;
/* 计算对应扇区的首地址 */
uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE;
uint16_t Index;
/* 计算起始地址在扇区内的偏移量 */
uint32_t startAddressOffset = startAddress - sectorStartAddress;
/* 计算总写入长度(字节数) */
uint32_t Total_len = countToWrite * 2;
uint32_t writeAddr = startAddress;
/* 计算待擦除的扇区个数(考虑起始地址偏移) */
uint32_t EraseSectorNum = (Total_len + startAddressOffset) / SECTOR_SIZE;
HAL_StatusTypeDef status = HAL_OK;
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t SectorError = 0;
/* 如果有余数,需要多擦除一个扇区 */
if((Total_len + startAddressOffset) % SECTOR_SIZE)
EraseSectorNum += 1;
/* 地址合法性检查起始地址必须在Flash范围内 */
if(startAddress < FLASH_BASE || ((startAddress + Total_len) >= Flash_EndAddr))
{
return HAL_ERROR; /* 非法地址 */
}
/* 扇区地址合法性检查 */
if(sectorStartAddress < FLASH_BASE || (sectorStartAddress >= Flash_EndAddr))
{
return HAL_ERROR; /* 非法地址 */
}
/* 解锁Flash写保护 */
HAL_FLASH_Unlock();
/* 检查是否需要跨扇区写入 */
if((writeAddr + Total_len) >= (sectorStartAddress + SECTOR_SIZE))
{
/* 循环擦除需要写入的所有扇区 */
for(Index = 0; Index < EraseSectorNum; Index++)
{
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; /* 设置擦除类型为页擦除 */
EraseInitStruct.PageAddress = sectorStartAddress; /* 设置要擦除的扇区地址 */
EraseInitStruct.NbPages = 1; /* 每次擦除1个扇区 */
/* 执行扇区擦除操作 */
status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
if(status != HAL_OK)
{
HAL_FLASH_Lock(); /* 擦除失败上锁Flash */
return status;
}
/* 移动到下一个扇区 */
sectorStartAddress += SECTOR_SIZE;
}
/* 循环写入所有数据(按半字方式写入) */
for(Index = 0; Index < countToWrite; Index++)
{
/* 按半字16位方式编程Flash */
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, startAddress + Index * 2, writeData[Index]);
if(status != HAL_OK)
{
break; /* 写入失败,退出循环 */
}
}
}
/* 上锁Flash写保护 */
HAL_FLASH_Lock();
return status;
}