本篇文章使用STM32对SD卡通过SDIO配置,读写文件
在使用FATFS时值得注意得是若通信SDIO不启动DMA方式读写,容易导致其他任务中断打断读写时序,导致FATFS的执行出现异常,常见返回为FR_DISK_ERR, / (1) A hard error occurred in the low level disk I/O layer /
例如:循环FATFS读写文件,开启定时器200KHz中断
注意:SDIO时开启中断
文件系统常用函数参考网站:http://elm-chan.org/fsw/ff/00index_e.html
一、CubeMx配置Fatfs方式读写SD卡文件(SDIO)
此章只是会使用CubeMx快速配置使用实现所需目的,不会详细讲解
1、CubeMx配置
所以SDIO_CK = 48 / (0 + 2) = 24MHz
注:允许同时打开的文件数
生成代码工程时会由于这个引脚弹警告,忽略即可
生成代码工程
2、编写目标代码
在main.h中添加所需头文件
#include "stdio.h"
#include "string.h"
在main.c中添加所需测试代码
A、添加ff.h头文件
#include "ff.h"
B、添加串口重定义函数、文件写读测试函数
int fputc(int ch,FILE *f)
void SD_ReadWrite(void)
C、挂载文件系统、测试容量、文件读写
main.c文件
#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 "ff.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 *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/****************************************************
@function:串口重定义
@param:void
@return:void
@date:2023.2.14
@note:使用printf时需要此函数,并在Keil魔术棒中勾选User MicroLIB库
****************************************************/
int fputc(int ch,FILE *f)
{uint8_t data = ch;HAL_UART_Transmit(&huart1,&data,1,1);return(ch);
}/****************************************************
@function:文件写读测试
@param:void
@return:void
@date:2023.3.1
@note:
****************************************************/
void SD_ReadWrite(void)
{FRESULT res_sd;char string[10240];int32_t ByteNum = 0,line = 0;UINT fnum;/* 文件成功读写数量 */res_sd = f_open (&SDFile,"残梦SDPath.txt",FA_CREATE_ALWAYS | FA_WRITE);if(res_sd != FR_OK){printf("res_sd=%d\r\n",res_sd);Error_Handler();}//sprintf(string,"Vreal\tA1\tA2\n");for(int i = 0,j = '0';i < 10200;i++){string[i] = j++;if(j == '9'){j = '0';i++;string[i] = '\n';}}ByteNum = strlen(string);res_sd=f_write(&SDFile,string,ByteNum,&fnum);res_sd = f_close(&SDFile);if(res_sd != FR_OK){printf("Error:File closure Exception!\r\n");}res_sd = f_open(&SDFile, "残梦SDPath.txt", FA_OPEN_EXISTING | FA_READ);if(res_sd != FR_OK){printf("res_sd=%d\r\n",res_sd);Error_Handler();}line = 0;while(!(f_eof(&SDFile))){memset(string,0,sizeof(string));f_gets(string,sizeof(string),&SDFile);if(strlen(string) == 0){break;}line++;printf("line=%d %s",line,string);}res_sd = f_close(&SDFile);if(res_sd != FR_OK){printf("res_sd=%d\r\n",res_sd);Error_Handler();}
}
/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* 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 */HAL_Delay(5000);//此处是为了串口看打印信息用的/* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_SDIO_SD_Init();MX_USART1_UART_Init();MX_FATFS_Init();/* USER CODE BEGIN 2 */FRESULT res_sd;HAL_SD_CardInfoTypeDef SdCard;res_sd = f_mount(&SDFatFS,SDPath,1);if(res_sd != FR_OK){printf("res_sd=%d\r\n",res_sd);Error_Handler();}if(HAL_SD_GetCardInfo(&hsd,&SdCard) != HAL_OK){printf("HAL_SD_GetCardInfo()\r\n");Error_Handler();}printf("SD卡容量:%.2fGB\r\n",(float)((uint64_t)SdCard.BlockNbr * (uint64_t)SdCard.BlockSize / 1024.0f / 1024.0f / 1024.0f));SD_ReadWrite();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
这个文件格式UTF-8是和FATFS配置一致
测试结束
3、完整工程下载
链接:https://pan.baidu.com/s/1rrofmllJri1O2Bzszrc83g
提取码:dgb1