目录
读者可访问 GitHub - lc-guo/STM32CubeMX-Series-Tutorial 获取原始工程代码
1、准备材料
STM32CubeMX软件(Version 6.10.0)
keil µVision5 IDE(MDK-Arm)
2、实验目标
使用STM32CubeMX软件配置STM32F407开发板SDIO使用FatFs中间件读写4线SD卡,并实现以轮询方式读写SD卡或以DMA方式读取SD卡
3、FatFs轮询读取SD卡流程
3.0、前提知识
FatFs文件系统相关知识请读者阅读STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验”3.0、前提知识“、"3.2.1、外设初始化调用流程"和"3.2.3、添加其他必要代码"三个小节内容
SD卡及SDIO接口相关知识请读者阅读STM32CubeMX教程27 SDIO - 读写SD卡实验”3.0、前提知识“小节内容
3.1、CubeMX相关配置
3.1.0、工程基本配置
打开STM32CubeMX软件,单击ACCESS TO MCU SELECTOR选择开发板MCU(选择你使用开发板的主控MCU型号),选中MCU型号后单击页面右上角Start Project开始工程,具体如下图所示
开始工程之后在配置主页面System Core/RCC中配置HSE/LSE晶振,在System Core/SYS中配置Debug模式,具体如下图所示
详细工程建立内容读者可以阅读“STM32CubeMX教程1 工程建立”
3.1.1、时钟树配置
按照STM32CubeMX教程27 SDIO - 读写SD卡实验配置,主锁相环参数Q配置为7,48MHz时钟频率配置为48MHz,其余时钟频率均设置为其能达到的最高频率,具体如下图所示
3.1.2、外设参数配置
本实验需要初始化开发板上WK_UP、KEY2、KEY1和KEY0用户按键,具体配置步骤请阅读“STM32CubeMX教程3 GPIO输入 - 按键响应”,注意两个实验使用的开发板不同,但配置步骤原理相同
本实验需要初始化USART1作为输出信息渠道,具体配置步骤请阅读“STM32CubeMX教程9 USART/UART 异步通信”
本实验对SDIO的初始化配置与上一实验STM32CubeMX教程27 SDIO - 读写SD卡3.1小节一致,无需做任何修改,只需要增加本实验需要的中间件FatFs即可
单击Pinout & Configuration页面左边功能分类栏目最下面的Middleware and SoftwarePacks,单击其中FatFs,在右侧模式设置中选择SD卡,下方的Configuration中参数大多保持默认即可,需要使用到的时候可以再修改
对Set Defines页面的参数不理解的读者,请阅读STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验"3.1.2、外设参数配置"小节,这里只需将 CODE_PAGE 参数配置为简体中文即可,具体配置如下图所示
在Advanced Settings配置页面中,参数 SDIO instance 只可选SDIO,无SPI选项,因为STM32F407的SDIO接口不支持SPI;当SDIO配置了DMA时,如果希望FatFs使用SDIO的DMA,那么可以将参数 Use dma template 配置为Enable;参数 BSP code for SD 不可选,只能为通用模式
在Platform Settings配置页面中,需要配置SD卡的插入检测引脚 Detect SDIO ,如果不配置该参数,则默认认为SD卡插在SD卡槽中,并且在生成工程代码时也会出现警告,这里由于硬件上并不支持插入检测因此并未配置该选项,警告内容如下图所示
3.1.3、外设中断配置
FatFs轮询读取SD卡无需配置任何中断
3.2、生成代码
3.2.0、配置Project Manager页面
单击进入Project Manager页面,在左边Project分栏中修改工程名称、工程目录和工具链,然后在Code Generator中勾选“Gnerate peripheral initialization as a pair of 'c/h' files per peripheral”,最后单击页面右上角GENERATE CODE生成工程,具体如下图所示
详细Project Manager配置内容读者可以阅读“STM32CubeMX教程1 工程建立”实验3.4.3小节
3.2.1、外设初始化调用流程
SDIO外设初始化调用流程请读者阅读STM32CubeMX教程27 SDIO - 读写SD卡实验对应小节
FatFs文件系统初始化调用流程请阅读STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验对应小节
在之前STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中笔者提到过,对于Extemal SRAM、SD Card和USB Disk这三种固定类型的存储,则无需用户在App文件夹和Target文件夹中重新实现FatFs的底层IO读写等操作函数,CubeMX生成的工程代码中会自动实现
将本实验生成的工程代码与STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验做对比,可以发现,FatFs在Target目录下多生成了一个名为bsp_driver_xxx.c的文件,如下图所示
该bsp_driver_xxx.c文件就是将对应内存设备底层读写等操作函数进行了封装,同时在sd_diskio.c文件中,本该在移植FatFs时由用户自己手动实现的初始化、状态、读/写和IO控制等函数也被直接调用了bsp_driver_xxx.c里的函数进行了自动实现,无需用户的任何操作,极为方便
这部分实现的原始代码读者可以自行生成工程查看,也可以和STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中笔者手动实现的几个函数做对比,更加容易发现其中共性
3.2.2、外设中断调用流程
FatFs轮询读取SD卡无配置任何中断
3.2.3、添加其他必要代码
STM32CubeMX工程生成工程代码后,读者应注意手动修改MX_SDIO_SD_Init()函数中SD卡数据总线宽度从默认的4位手动修改为1位,否则SD卡将初始化失败
在生成的工程代码中增加使用FatFs库中API进行文件操作的函数,包括挂载文件系统、显示SD卡信息、读/写TXT文件、获取文件信息、扫描文件列表和删除文件等函数,笔者将其封装在了file_operate.c / file_operate.h文件中,具体的源代码如下所示
file_operate.c文件
与STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中实现的file_operate.c文件一致,除了测试写的函数FatFs_WriteTXTFile()中写入SD卡的内容修改为了“Line1: Hello, FatFs***\n”
file_operate.h文件
与STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中实现的file_operate.h文件一致,除了下面三个宏定义需要修改为本实验的SD卡相关内容,修改内容如下所示
/*定义自己的存储设备*/
/*用户存储设备扇区字节数*/
#define User_Sector 512
/*用户存储设备FatFs对象*/
#define User_FatFs SDFatFS
/*用户存储设备卷路径*/
#define User_SDPath SDPath
/*用户存储设备初始化类型*/
#define User_FatType FM_FAT32
向工程中添加.c/.h文件的步骤请阅读“STM32CubeMX教程19 I2C - MPU6050驱动”实验3.2.3小节
在main.c文件中添加 ”file_operate.h“ 头文件,然后在主函数 main() 中添加文件系统挂载函数及按键控制逻辑函数,具体源代码与STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中实现的一模一样,无需任何修改
4、烧录验证
烧录程序,开发板上电后会尝试在SD卡上挂载文件系统,挂载成功后会输出读取到的SD卡的信息,接下来按照下面几个步骤使用FatFs文件系统对SD卡进行读写等测试
- 按下开发板上的WK_UP按键,扫描SD卡根目录下所有文件,并通过串口将文件列表输出
- 按下开发板上的KEY2按键,在SD卡根目录创建一个”test.txt“文件,将一个字符串”Line1: Hello, FatFs***“写入该文件中,该字符串大小为24个字节(该字符串中有2个空格,末尾包括一个’\n‘和一个‘\0')
- 按下开发板上的KEY1按键,读取SD卡根目录下名为”test.txt“的文件,将其中的内容通过串口输出,然后读取该文件的信息(大小,属性,名称),并通过串口输出
- 按下开发板上的KEY0按键,删除SD卡根目录下名为”test.txt“的文件
整个实验过程串口具体的输出情况如下图所示
5、FatFs DMA读写SD卡流程简述
5.1、CubeMX相关配置
参考上一实验STM32CubeMX教程27 SDIO - 读写SD卡的”6.1、CubeMX相关配置“小节对SDIO的DMA进行配置,具体如下图所示
在System Core/NVIC中勾选SDIO全局中断、DMA2 stream3 全局中断和 DMA2 stream6 全局中断,然后选择合适的中断优先级即可,如下图所示
最后只需在FatFs的Configuration页面Advanced Settings选项卡中将参数 Use dma template 修改为Enable即可,具体如下图所示
5.2、生成代码
修改STM32CubeMX工程重新生成工程代码后,读者应注意再次手动修改MX_SDIO_SD_Init()函数中SD卡数据总线宽度从默认的4位手动修改为1位
除了上述修改外,在轮询读取SD卡基础上生成的代码无需做任何改动,可以直接编译后烧录到开发板上,程序应该直接可以运行,不需要额外添加任何代码
启用SDIO的DMA之后,对应生成的bsp_driver_xxx.c文件中所有的以轮询方式读写等操作SD卡的底层驱动函数都将被相应的替换为以DMA的方式对SD卡进行读写等操作的底层驱动函数,如下图所示以sd_diskio.c文件中的读函数为例简单展示区别
5.3、烧录验证
FatFs DMA读写SD卡的实验现象与FatFs 轮询读取SD卡的实验现象一致,只不过底层SDIO读写SD卡的方式由轮询读写修改为了以DMA方式的读写,对上层FatFs应用无任何影响
6、常用函数
请读者阅读STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验 ”常用函数“ 小节