Cubemx+Fatfs(解决挂载Fatfs失败的问题)
一、基本思路
为了接入SD卡,需要启用SDMMC接口;为了通过串口进行数据显示,必须启用UART;为了进行文件系统管理,需要启用FATFS。
二、Cubemx操作步骤
1.选择好芯片
2.设置RCC为外部时钟
3.使能串口1(usart1)
模式设为异步(Asynchronous)其他默认,波特率可以自己改,USART1为115200Bits/s,如图
4.使能SDMMC
笔者此处使用的芯片没有SDMMC,借用的SDIO的接口
模式设为SD 4 Bits Wide bus ,设置DMA,如图
使能SDMMC1中断,并在中断设置中设置中断优先级
设备 | 优先级 |
---|---|
SDMMC | 5 |
DMA | 6 |
此处必须使得SDMMC的中断优先级高于DMA,才可正常工作。
5、使能FATFS
此处参考链接选的 SD Card ,但此处笔者只有 User-Defined 这一个可以选。
6、时钟树设置
没有找到 给sdmmc的时钟
7、项目设置
有文件系统,堆栈改大一点0x1000
生成代码 右上角GENERATE CODE
8、代码修改
1. 为方便的使用串口打印信息,所以找到uart.c,并在/* USER CODE BEGIN 0 */后添加如下代码用于重定义printf函数的输出口:
#include <stdio.h>
struct __FILE
{
int handle;
};FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->ISR&0X40)==0);
USART1->TDR=(uint8_t)ch;
return ch;
}
2.在main.c函数中的/* USER CODE BEGIN PV */ 后添加如下定义
FATFS fs; //工作空间
FIL fil; // 文件项目
uint32_t byteswritten; // 写文件计数
uint32_t bytesread; // 读文件计数
uint8_t wtext[] = "我就是那张SD卡,8G那张!!"; // 写的内容
uint8_t rtext[1024]; // 读取的buff
char filename[] = "GPSSave.txt"; // 文件名
3. main.c函数中的/* USER CODE BEGIN 2 */后添加如下代码:
printf("\r\n ****** 文件系统 ******\r\n\r\n");
/*-1- 挂载文件系统*/
retSD = f_mount(&fs, "", 0);
if(retSD)
{
printf(" mount error : %d \r\n",retSD);
Error_Handler();
}
else
printf(" mount sucess!!! \r\n");
/*-2-创建新的文件并写入数据*/
retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); //打开文件,权限包括创建、写(如果没有该文件,会创建该文件)
if(retSD) //返回值不为0(出现问题)
printf(" open file error : %d\r\n",retSD); //打印问题代码
else
printf(" open file sucess!!! \r\n");
/*-3- 在txt文件中写入数据*/
retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten); //在文件内写入wtext内的内容
if(retSD) //返回值不为0(出现问题)
printf(" write file error : %d\r\n",retSD); //打印问题代码
else
{
printf(" write file sucess!!! \r\n");
printf(" write Data : %s\r\n",wtext); //打印写入的内容
}
/*-4- 关闭txt文件*/
retSD = f_close(&fil); //关闭该文件
if(retSD) //返回值不为0(出现问题)
printf(" close error : %d\r\n",retSD); //打印问题代码
else
printf(" close sucess!!! \r\n");
/*-5- 打开文件读取数据*/
retSD = f_open(&fil, filename, FA_READ); //打开文件,权限为只读
if(retSD) //返回值不为0(出现问题)
printf(" open file error : %d\r\n",retSD); //打印问题代码
else
printf(" open file sucess!!! \r\n");
/*-6- 读取txt文件数据*/
retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread); //读取文件内容放到rtext中
if(retSD) //返回值不为0(出现问题)
printf(" read error!!! %d\r\n",retSD); //打印问题代码
else
{
printf(" read sucess!!! \r\n");
printf(" read Data : %s\r\n",rtext); //打印读取到的数据
}
/*-7- 关闭文件*/
retSD = f_close(&fil); //关闭该文件
if(retSD) //返回值不为0(出现问题)
printf(" close error!!! %d\r\n",retSD); //打印问题代码
else
printf(" close sucess!!! \r\n");
/*##-8- 读写一致性检测 ############*/
if(bytesread == byteswritten) //如果读写位数一致
{
printf(" FatFs is working well!!!\r\n"); //打印文件系统工作正常
}
Debug
FatFs[vol] = fs; /* Register new fs object */
if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */
res = find_volume(&path, &fs, 0); /* Force mounted the volume */
LEAVE_FF(fs, res);
}
FatFs[vol] = fs; /* 注册新的文件系统对象 */
if (!fs || opt != 1) return FR_OK; /* 不进行挂载,稍后挂载 */
res = find_volume(&path, &fs, 0); /* 强制挂载该卷 */
LEAVE_FF(fs, res);
这段代码的功能:
- 注册文件系统对象:将给定的
fs
对象(文件系统)与特定的卷关联,存储在FatFs
数组中。 - 条件挂载卷:如果没有有效的文件系统对象(
fs
为NULL
)或操作标志opt
不为1
,则跳过挂载操作。 - 查找并挂载卷:如果条件符合,调用
find_volume()
查找与路径对应的卷并挂载它。 - 返回结果:操作结果保存在
res
中,LEAVE_FF()
用于处理和返回结果。
挂载前先格式化
printf("\r\n ****** 文件系统 ******\r\n\r\n");
/*格式化内存区*/
// 格式化逻辑驱动器 0
retSD = f_mkfs("0:", FM_FAT32, 0, work, sizeof(work));
if (retSD != FR_OK) {
处理格式化错误
printf(" mkfs_err");
}
/*-1- 挂载文件系统*/
user_diskio.c
令Stat=0 磁盘状态设置为正常
MX_SDIO_MMC_Init()里初始化时手动改成1B
参考
STM32Cube的FATFS+SD卡_stm32l cube sd卡-CSDN博客
【CubeMX+STM32】SD卡 U盘文件系统 USB+FATFS_stm32 u盘 sd-CSDN博客