1、准备材料

正点原子stm32f407探索者开发板V2.4

STM32CubeMX软件(Version 6.10.0

keil µVision5 IDE(MDK-Arm

ST-LINK/V2驱动

野火DAP仿真器

XCOM V2.6串口助手

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

向工程中添加.c/.h文件的步骤请阅读“STM32CubeMX教程19 I2C - MPU6050驱动”实验3.2.3小节

在main.c文件中添加 ”file_operate.h“ 头文件,然后在主函数 main() 中添加文件系统挂载函数及按键控制逻辑函数,具体源代码与STM32CubeMX教程26 FatFs 文件系统 - W25Q128读写实验中实现的一模一样,无需任何修改

4、烧录验证

烧录程序,开发板上电后会尝试在SD卡上挂载文件系统,挂载成功后会输出读取到的SD卡的信息,接下来按照下面几个步骤使用FatFs文件系统对SD卡进行读写等测试

  1. 按下开发板上的WK_UP按键,扫描SD卡根目录下所有文件,并通过串口将文件列表输出
  2. 按下开发板上的KEY2按键,在SD卡根目录创建一个”test.txt“文件,将一个字符串”Line1: Hello, FatFs***“写入该文件中,该字符串大小为24个字节(该字符串中有2个空格,末尾包括一个’\n‘和一个‘\0')
  3. 按下开发板上的KEY1按键,读取SD卡根目录下名为”test.txt“的文件,将其中的内容通过串口输出,然后读取该文件的信息(大小,属性,名称),并通过串口输出
  4. 按下开发板上的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读写实验 ”常用函数“ 小节

参考资料

STM32Cube高效开发教程(高级篇)

STM32CubeMX教程28 SDIO - 使用FatFs文件系统读写SD卡的更多相关文章

  1. Android 读写SD卡的文件

    今天介绍一下Android 读写SD卡的文件,要读写SD卡上的文件,首先需要判断是否存在SD卡,方法: Environment.getExternalStorageState().equals(Env ...

  2. android学习笔记47——读写SD卡上的文件

    读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...

  3. android 读写sd卡的权限设置

    原文:android 读写sd卡的权限设置 在Android中,要模拟SD卡,要首先使用adb的mksdcard命令来建立SD卡的镜像,如何建立,大家上网查一下吧,应该很容易找到,这里不说这个问题. ...

  4. Android读写SD卡

    SD卡的读写是我们在开发Android 应用程序过程中最常见的操作.下面介绍SD卡的读写操作方式: 1. 获取SD卡的根目录 String sdCardRoot = Environment.getEx ...

  5. android 读写SD卡文件

    参考: http://www.oschina.net/code/snippet_176897_7336#11699 写文件: private void SavedToText(Context cont ...

  6. C#使用CH341 SPI模块读写SD卡

    SD卡相关CMD命令 ;//卡复位 ; ;//命令9 ,读CSD数据 ;//命令10,读CID数据 ;//命令12,停止数据传输 ;//命令16,设置SectorSize 应返回0x00 ;//命令1 ...

  7. android读写SD卡封装的类

    参考了网上的一些资源代码,FileUtils.java: package com.example.test; import java.io.BufferedInputStream; import ja ...

  8. 今天发现郭的华为手机无法读写sd卡,找到了这个方法

    https://bbs.csdn.net/topics/391985867?page=1 华为P9是android 6.0 的==在API23+以上也就是安卓6.0以上的,进行了权限管理不止要在And ...

  9. 第37章 基于SD卡的FatFs文件系统—零死角玩转STM32-F429系列

    第37章     基于SD卡的FatFs文件系统 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  10. 第36章 SDIO—SD卡读写测试

    第36章     SDIO—SD卡读写测试 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...

随机推荐

  1. JS 闭包 BUG

    C.js代码: /** * 有BUG */ (function (global) { var _id; var _map; var _length; global.C = function () { ...

  2. vue mutations与actions的区别

    关于 mutations与actions的区别,网上有很多文章,大多是照着vue.js的教程再来一波!!因为最近接手vue项目,自己之前vue的知识点掌握也不深,就此机会把这个知识点再深挖一下. 使用 ...

  3. 如何设置IDEA代码风格为Google风格,使用Google风格format

    1.在Github仓库寻找:google style 为了节省大家时间直接放链接了:Here 2.进到项目 找到名为intellij-java-google-style.xml 文件 Ctrl + F ...

  4. 推荐收藏!年度Top20开源许可证风险等级

    开源许可现状 开发人员经常在软件中引入开源的代码片段.函数.方法和操作代码.因此,软件代码中经常会包含各种声明不同许可证的子组件.这些子组件的许可证条款和条件与项目整体主许可证的条款和条件冲突时,就会 ...

  5. Springboot+ELK实现日志系统简单搭建

    前面简单介绍了ELK三剑客中的其中两个Elasticsearch和Kibana的简单使用,如果对这两个不了解,可以看下下面的 Centos7安装Elasticsearch和Kibana 搜索引擎基础- ...

  6. vue-cli3title标签中的htmlWebpackPlugin.options.title

    https://blog.csdn.net/weixin_56650035/article/details/119355625

  7. vue配置proxy实现跨域

  8. Laravel - except() 函数

         /**      *  用户添加      * @param 接收的表单数据  (name,password,id)      * @return 返回添加是否成功      */      ...

  9. Go-获取密码的sha值

    // 对用户密码进行加密 func EncodePwd(pwd string) string { s := sha256.New() s.Write([]byte(pwd)) data := s.Su ...

  10. [转帖]高并发下nginx配置模板

    user web;       # One worker process per CPU core.   worker_processes 8;       # Also set   # /etc/s ...