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
在这里插入图片描述

一、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卡容量问题小解释

在这里插入图片描述

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值