/* 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_fatfs.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ #define MAX_FILE_COUNT 20 /* 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 readbuffer[512]; char SDPath[4]; 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; /* Initialize all configured peripherals */ SDCARD_GPIO_Init(); SDCARD_SPI_Init(); SDCARD_FATFS_Init(); /* USER CODE BEGIN 2 */ res = f_mount(&fileSystem, (const TCHAR*)&SDPath, 1); if(res != FR_OK) { func_record_fatfs_set_OK(false); } /* 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 { uint16_t TotalSpace; DWORD AvailableSize; DWORD UsedSize; }fatfs_st; fatfs_st sd_fatfs_st; void func_fatfs_Get_Capacity(void) { // FRESULT result; // FATFS FS; FATFS *fs; DWORD fre_clust; FRESULT res; res = f_getfree(SDPath, &fre_clust, &fs); /* 根目录 */ if ( res == FR_OK ) { sd_fatfs_st.TotalSpace=(uint16_t)(((fs->n_fatent - 2) * fs->csize ) / 2 /1024); sd_fatfs_st.AvailableSize=(uint16_t)((fre_clust * fs->csize) / 2 /1024); sd_fatfs_st.UsedSize=sd_fatfs_st.TotalSpace-sd_fatfs_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*)SDPath, &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,readbuffer,f_size(&file),&fnum); if(f_res == FR_OK) { printf("》文件内容:\n%s\n",readbuffer); } } 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 } } } static int qsort_cmp(const void *a,const void *b) { return strcmp(( char * ) a, (const char* )b); } char fileList[MAX_FILE_COUNT][30];//保存文件名 void func_fatfs_dir_qsort(uint32_t fcount) { qsort(fileList, fcount, sizeof(fileList[0]), qsort_cmp); } #endif //--------------------------USE_FATFS_RECORD------------------------------ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/