本篇文章使用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
5、SD卡容量问题小解释




















