9、STM32 SDIO FATFS(SD卡)

本篇文章使用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
9、STM32 SDIO FATFS(SD卡)_第1张图片

一、CubeMx配置Fatfs方式读写SD卡文件(SDIO)

此章只是会使用CubeMx快速配置使用实现所需目的,不会详细讲解
9、STM32 SDIO FATFS(SD卡)_第2张图片

1、CubeMx配置

9、STM32 SDIO FATFS(SD卡)_第3张图片
9、STM32 SDIO FATFS(SD卡)_第4张图片
9、STM32 SDIO FATFS(SD卡)_第5张图片
9、STM32 SDIO FATFS(SD卡)_第6张图片
9、STM32 SDIO FATFS(SD卡)_第7张图片
9、STM32 SDIO FATFS(SD卡)_第8张图片
9、STM32 SDIO FATFS(SD卡)_第9张图片
9、STM32 SDIO FATFS(SD卡)_第10张图片
9、STM32 SDIO FATFS(SD卡)_第11张图片
所以SDIO_CK = 48 / (0 + 2) = 24MHz
9、STM32 SDIO FATFS(SD卡)_第12张图片
9、STM32 SDIO FATFS(SD卡)_第13张图片
9、STM32 SDIO FATFS(SD卡)_第14张图片
9、STM32 SDIO FATFS(SD卡)_第15张图片
注:允许同时打开的文件数
在这里插入图片描述
9、STM32 SDIO FATFS(SD卡)_第16张图片
9、STM32 SDIO FATFS(SD卡)_第17张图片
生成代码工程时会由于这个引脚弹警告,忽略即可
9、STM32 SDIO FATFS(SD卡)_第18张图片
生成代码工程

2、编写目标代码

9、STM32 SDIO FATFS(SD卡)_第19张图片
在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 */
}

9、STM32 SDIO FATFS(SD卡)_第20张图片
9、STM32 SDIO FATFS(SD卡)_第21张图片
这个文件格式UTF-8是和FATFS配置一致
9、STM32 SDIO FATFS(SD卡)_第22张图片
测试结束

3、完整工程下载

链接:https://pan.baidu.com/s/1rrofmllJri1O2Bzszrc83g
提取码:dgb1

5、SD卡容量问题小解释

在这里插入图片描述

你可能感兴趣的:(STM32,stm32,单片机,嵌入式硬件)