/\* USER CODE BEGIN Header \*/ /\*\* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* @file : main.c \* @brief : Main program body \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* @attention \* \* Copyright (c) 2022 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 "dma.h" #include "fatfs.h" #include "sdio.h" #include "usart.h" #include "gpio.h"
/\* Private includes ----------------------------------------------------------\*/ /\* USER CODE BEGIN Includes \*/ #include <stdio.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 \*/
/\* 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\_SDIO\_SD\_Init(); MX\_DMA\_Init(); MX\_USART1\_UART\_Init(); MX\_FATFS\_Init(); /\* USER CODE BEGIN 2 \*/ printf("\r\n\*\*\*\*\*\* FatFs Example \*\*\*\*\*\*\r\n\r\n");
//挂载文件系统 f_res = f\_mount(&fs, "/", 1);
printf("\r\n\*\*\*\*\*\* Mount FatFs File System \*\*\*\*\*\*\r\n"); // 检查是否SD卡是否已经格式化 if (f_res == FR_NO_FILESYSTEM) { printf( "The SD card does not yet have a file system and is about to be formatted...\r\n"); /\* 格式化SD卡 \*/ f_res = f\_mkfs("/", 0, 0); if (f_res == FR_OK) { printf("The SD card successfully formatted the file system\r\n"); /\* 格式化后,先取消挂载 \*/ f_res = f\_mount(NULL, "/", 1); /\* 重新挂载 \*/ f_res = f\_mount(&fs, "/", 1); } else { printf("The format failed\r\n"); while (1) ; } } else if (f_res != FR_OK) { printf(" mount error : %d \r\n", f_res); while (1) ; } else { printf(" mount sucess!!! \r\n"); }
printf("\r\n\*\*\*\*\*\* FatFs File Operation \*\*\*\*\*\*\r\n"); //打开并创建文件(不存在时) f_res = f\_open(&file, "/test.txt", FA_CREATE_ALWAYS | FA_WRITE); if (f_res == FR_OK) { printf(" open file sucess!!! \r\n"); // 将数据写入文件 printf("\r\n\*\*\*\*\*\* Write data to the text files \*\*\*\*\*\*\r\n"); f_res = f\_write(&file, WriteBuffer, sizeof(WriteBuffer), &fnum); if (f_res == FR_OK) { printf(" write file sucess!!! (%d)\n", fnum); printf(" write Data : %s\r\n", WriteBuffer); } else { printf(" write file error : %d\r\n", f_res); } /\*关闭文件\*/ f\_close(&file); } else { printf(" open file error : %d\r\n", f_res); }
printf("\r\n\*\*\*\*\*\* Read data from the text files \*\*\*\*\*\*\r\n"); // 打开文件 f_res = f\_open(&file, "/test.txt", FA_OPEN_EXISTING | FA_READ); if (f_res == FR_OK) { printf(" open file sucess!!! \r\n"); f_res = f\_read(&file, ReadBuffer, sizeof(ReadBuffer), &fnum); if (f_res == FR_OK) { printf("read sucess!!! (%d)\n", fnum); printf("read Data : %s\r\n", ReadBuffer); } else { printf(" read error!!! %d\r\n", f_res); } } else { printf(" open file error : %d\r\n", f_res); } /\* 关闭文件 \*/ f\_close(&file); /\*卸载文件系统 \*/ f\_mount(NULL, "/", 1);
/\* USER CODE END 2 \*/
/\* Infinite loop \*/ /\* USER CODE BEGIN WHILE \*/ while (1) { /\* USER CODE END WHILE \*/
/\* USER CODE BEGIN 3 \*/ } /\* USER CODE END 3 \*/ }
if (HAL\_RCC\_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != 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 \*/
if (f_res == FR_NO_FILESYSTEM) { printf( "The SD card does not yet have a file system and is about to be formatted...\r\n"); /\* 格式化SD卡 \*/ f_res = f\_mkfs("/", 0, 0); if (f_res == FR_OK) { printf("The SD card successfully formatted the file system\r\n"); /\* 格式化后,先取消挂载 \*/ f_res = f\_mount(NULL, "/", 1); /\* 重新挂载 \*/ f_res = f\_mount(&fs, "/", 1); } else { printf("The format failed\r\n"); while (1) ; } }
如果挂载文件系统失败,则停止所有操作
1 2 3 4 5 6
else if (f_res != FR_OK) { printf(" mount error : %d \r\n", f_res); while (1) ; }
文件系统挂载成功后,就可以对文件进行读写操作了。打开文件,并写入操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
f_res = f\_open(&file, "/test.txt", FA_CREATE_ALWAYS | FA_WRITE); if (f_res == FR_OK) { printf(" open file sucess!!! \r\n"); // 将数据写入文件 printf("\r\n\*\*\*\*\*\* Write data to the text files \*\*\*\*\*\*\r\n"); f_res = f\_write(&file, WriteBuffer, sizeof(WriteBuffer), &fnum); if (f_res == FR_OK) { printf(" write file sucess!!! (%d)\n", fnum); printf(" write Data : %s\r\n", WriteBuffer); } else { printf(" write file error : %d\r\n", f_res); } /\*关闭文件\*/ f\_close(&file); } else { printf(" open file error : %d\r\n", f_res); }
函数f_open用于打开文件,如果打开成功,则返回FR_OK,否则,返回错误代码。
函数f_write用于向文件写数据。如果写文件成功,则返回FR_OK,否则,返回错误代码。
当文件写数据完成后,需要通过调用f_close函数,对文件进行操作。如果打开文件过多,会导致后期文件读写失败。支持打开最多文件数量,在FatFs配置中的FS_LOCK(Numbers of files openned simultaneously)中设置,默认值 为2。