/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
*
© Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#if USE_FATFS_RECORD
#include "dev_spi_sdcard.h"
#include "func_spi_w25qxx.h"
#include "func_fatfs.h"
#include "func_fatfs_record.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* 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 -----------------------------------------------*/
/* USER CODE BEGIN PFP */
FATFS fileSystem;
FIL testFile;
uint8_t testBuffer[16] = "SD write success";
char fatfs_buf[4*1024];
#if USE_SPI_SD
const char FATFS_Path[4] = "0:/"; //挂载SD卡
#else
const char FATFS_Path[4] ;//= "1:/"; //挂载FLASH.
#endif
char readnrf,reafsd;
/* USER CODE END PFP */
void func_fatfs_Get_Capacity(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int func_fatfs_init(void)
{
FRESULT res;
uint8_t format_disk = 0;
/* Initialize all configured peripherals */
FATFS_Init();
//res = f_mkfs ( FATFS_Path, FM_ANY, 0, fatfs_buf, sizeof(fatfs_buf));
/* USER CODE BEGIN 2 */
res = f_mount(&fileSystem, (const TCHAR*)FATFS_Path, 1);
if(res != FR_OK)
{
func_record_fatfs_set_OK(false);
}
if(res == FR_NO_FILESYSTEM)//FLASH磁盘,FAT文件系统错误,重新格式化FLASH
{
//
while(res != FR_OK)
{
if(format_disk)
{
func_w25q_erase_ship();
format_disk = 0;
}
if(format_disk)
{
res = f_mkfs (FATFS_Path, FM_ANY, 0, fatfs_buf, sizeof(fatfs_buf));
format_disk = 0;
}
res = f_mount(&fileSystem, (const TCHAR*)FATFS_Path, 1);
};
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
/* USER CODE END 3 */
return res;
}
/**
* @brief The application entry point.
* @retval int
*/
int func_fatfs_main(void)
{
/* USER CODE BEGIN 1 */
//func_fatfs_Get_Capacity();
/* USER CODE END 1 */
return 0;
}
typedef struct fatfs_st
{
DWORD TotalSpace;
DWORD AvailableSize;
DWORD UsedSize;
}fatfs_st;
fatfs_st fatfs_run_st;
void func_fatfs_Capacity(void)
{
FATFS *hFatfs = &fileSystem;
fatfs_run_st.TotalSpace=((hFatfs->n_fatent - 2) * hFatfs->ssize *hFatfs->csize)/1024;
fatfs_run_st.AvailableSize=(hFatfs->free_clst*hFatfs->ssize*hFatfs->csize)/1024;
fatfs_run_st.UsedSize=fatfs_run_st.TotalSpace-fatfs_run_st.AvailableSize;
}
uint32_t func_fatfs_get_free(void)
{
return (fileSystem.free_clst*fileSystem.ssize*fileSystem.csize)/1024;
}
void func_fatfs_Get_Capacity(void)
{
// FRESULT result;
// FATFS FS;
FATFS *fs;
DWORD fre_clust;
FRESULT res;
res = f_getfree(FATFS_Path, &fre_clust, &fs); /* 根目录 */
if ( res == FR_OK )
{
fatfs_run_st.TotalSpace=(fs->n_fatent - 2);
fatfs_run_st.AvailableSize=fre_clust;
fatfs_run_st.UsedSize=fatfs_run_st.TotalSpace-fatfs_run_st.AvailableSize;
/* Print free space in unit of MB (assuming 512 bytes/sector) */
// printf("\r\n%d MB total drive space.\r\n""%d MB available.\r\n""%d MB used.\r\n",TotalSpace, AvailableSize,UsedSize);
}
else
{
// printf("Get SDCard Capacity Failed (%d)\r\n", result);
}
return;
}
void func_fatfs_Get_Capacity_Sample(void)
{
// FRESULT result;
// FATFS FS;
FATFS *fs;
DWORD fre_clust;
FRESULT res;
res = f_getfree(FATFS_Path, &fre_clust, &fs); /* 根目录 */
if ( res == FR_OK )
{
fatfs_run_st.TotalSpace=(uint16_t)(((fs->n_fatent - 2) * fs->csize ) / 2 /1024);
fatfs_run_st.AvailableSize=(uint16_t)((fre_clust * fs->csize) / 2 /1024);
fatfs_run_st.UsedSize=fatfs_run_st.TotalSpace-fatfs_run_st.AvailableSize;
/* Print free space in unit of MB (assuming 512 bytes/sector) */
// printf("\r\n%d MB total drive space.\r\n""%d MB available.\r\n""%d MB used.\r\n",TotalSpace, AvailableSize,UsedSize);
}
else
{
// printf("Get SDCard Capacity Failed (%d)\r\n", result);
}
return;
}
FIL file; /* 文件对象 */
/* FatFs多项功能测试 */
FRESULT func_fatfs_miscellaneous(void)
{
FRESULT f_res; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
DIR dir;
FATFS *pfs;
DWORD fre_clust, fre_sect, tot_sect;
printf("\n*************** 设备信息获取 ***************\r\n");
/* 获取设备信息和空簇大小 */
f_res = f_getfree((TCHAR const*)FATFS_Path, &fre_clust, &pfs);
/* 计算得到总的扇区个数和空扇区个数 */
tot_sect = (pfs->n_fatent - 2) * pfs->csize;
fre_sect = fre_clust * pfs->csize;
/* 打印信息(4096 字节/扇区) */
printf("》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\n", tot_sect *4, fre_sect *4);
printf("\n******** 文件定位和格式化写入功能测试 ********\r\n");
f_res = f_open(&file, "FatFs读写测试文件.txt",
FA_OPEN_EXISTING|FA_WRITE|FA_READ );
if ( f_res == FR_OK )
{
/* 文件定位 */
f_res = f_lseek(&file,f_size(&file)-1);
if (f_res == FR_OK)
{
/* 格式化写入,参数格式类似printf函数 */
f_printf(&file,"\n在原来文件新添加一行内容\n");
f_printf(&file,"》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\n", tot_sect *4, fre_sect *4);
/* 文件定位到文件起始位置 */
f_res = f_lseek(&file,0);
/* 读取文件所有内容到缓存区 */
f_res = f_read(&file,fatfs_buf,f_size(&file),&fnum);
if(f_res == FR_OK)
{
printf("》文件内容:\n%s\n",fatfs_buf);
}
}
f_close(&file);
printf("\n********** 目录创建和重命名功能测试 **********\r\n");
/* 尝试打开目录 */
f_res=f_opendir(&dir,"TestDir");
if(f_res!=FR_OK)
{
/* 打开目录失败,就创建目录 */
f_res=f_mkdir("TestDir");
}
else
{
/* 如果目录已经存在,关闭它 */
f_res=f_closedir(&dir);
/* 删除文件 */
f_unlink("TestDir/testdir.txt");
}
if(f_res==FR_OK)
{
/* 重命名并移动文件 */
f_res=f_rename("FatFs读写测试文件.txt","TestDir/testdir.txt");
}
}
else
{
printf("!! 打开文件失败:%d\n",f_res);
printf("!! 或许需要再次运行“FatFs移植与读写测试”工程\n");
}
return f_res;
}
/**
* 文件信息获取
*/
FRESULT func_fatfs_file_check(void)
{
FRESULT f_res; /* 文件操作结果 */
static FILINFO finfo;
/* 获取文件信息 */
f_res=f_stat("TestDir/testdir.txt",&finfo);
if(f_res==FR_OK)
{
printf("“testdir.txt”文件信息:\n");
printf("》文件大小: %ld(字节)\n", finfo.fsize);
printf("》时间戳: %u/%02u/%02u, %02u:%02u\n",
(finfo.fdate >> 9) + 1980, finfo.fdate >> 5 & 15, finfo.fdate & 31,finfo.ftime >> 11, finfo.ftime >> 5 & 63);
printf("》属性: %c%c%c%c%c\n\n",
(finfo.fattrib & AM_DIR) ? 'D' : '-', // 是一个目录
(finfo.fattrib & AM_RDO) ? 'R' : '-', // 只读文件
(finfo.fattrib & AM_HID) ? 'H' : '-', // 隐藏文件
(finfo.fattrib & AM_SYS) ? 'S' : '-', // 系统文件
(finfo.fattrib & AM_ARC) ? 'A' : '-'); // 档案文件
}
return f_res;
}
/**
* @brief scan_files 递归扫描FatFs内的文件
* @param path:初始扫描路径
* @retval result:文件系统的返回值
*/
FRESULT func_fatfs_scan_files (char* path)
{
FRESULT res; //部分在递归过程被修改的变量,不用全局变量
FILINFO fno;
DIR dir;
int i;
char *fn; // 文件名
#if _USE_LFN
/* 长文件名支持 */
/* 简体中文需要2个字节保存一个“字”*/
static char lfn[_MAX_LFN*2 + 1];
fno.fname = lfn;
fno.fsize = sizeof(lfn);
#endif
//打开目录
res = f_opendir(&dir, path);
if (res == FR_OK)
{
i = strlen(path);
for (;;)
{
//读取目录下的内容,再读会自动读下一个文件
res = f_readdir(&dir, &fno);
//为空时表示所有项目读取完毕,跳出
if (res != FR_OK || fno.fname[0] == 0) break;
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
//点表示当前目录,跳过
if (*fn == '.') continue;
//目录,递归读取
if (fno.fattrib & AM_DIR)
{
//合成完整目录名
sprintf(&path[i], "/%s", fn);
//递归遍历
res = func_fatfs_scan_files(path);
path[i] = 0;
//打开失败,跳出循环
if (res != FR_OK)
break;
}
else
{
printf("%s/%s\n", path, fn); //输出文件名
/* 可以在这里提取特定格式的文件路径 */
}//else
} //for
}
return res;
}
/*------------------------------------------------------
读取指定目录下所有的文件
说明:
f_readdir 按顺序读取目录内文件,
重复调用此函数可读取目录内所有文件;
---------------------------------------------------------*/
void func_fatfs_ReadDirTest(char*path)
{
// FRESULT res; /* FatFs 函数通用结果代码 */
DIR dir;
FILINFO fno;
#if _USE_LFN//如果使能支持长文件名 先对下面两项初始化
fileinfo.lfsize=_MAX_LFN * 2 + 1;//
fileinfo.lfname=(TCHAR*)FileName;//
#endif
if(f_opendir(&dir,(const char*)path) == FR_OK)/* 打开文件夹目录成功,目录信息已经在dir结构体中保存 */
{
while(f_readdir(&dir, &fno) == FR_OK) /* 读文件信息到文件状态结构体中 */
{
if(!fno.fname[0]) break; /* 如果文件名为‘\0',说明读取完成结束 */
printf("%s/",path);//打印路径
#if _USE_LFN
printf("文件名:%s\r\n",fileinfo.lfname );//打印信息到串口
#else
printf("文件名:%s\r\n", fno.fname);//
#endif
}
}
}
char* pstr = 0;
char* pidx = 0;
void func_record_fatfs_str(void)
{
char str_name[] ="20221112.TXT" ;
while(1)
{
pstr = strstr(str_name,FILE_START);
pidx = strstr(str_name,FILE_END);
UNUSED(pstr);
UNUSED(pidx);
}
}
#if 0
static int qsort_cmp(const void *a,const void *b)
{
return strcmp(( char * ) a, (const char* )b);
}
#define MAX_FILE_COUNT 20
char fileList[MAX_FILE_COUNT][30];//保存文件名
void func_fatfs_dir_qsort(uint32_t fcount)
{
qsort(fileList, fcount, sizeof(fileList[0]), qsort_cmp);
}
#endif
#endif //--------------------------USE_FATFS_RECORD------------------------------
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/