first commit
This commit is contained in:
124
Users/File_Handle.c
Normal file
124
Users/File_Handle.c
Normal 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)
|
||||
* 对于STM32F103V,Flash地址范围: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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user