本篇文章使用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