基于STM32F407的SDCard读写操作

2023-11-09

基于STM32F407的SDCard读写操作

目录

基于STM32F407的SDCard读写操作

硬件电路

SD卡结构示意图

 管脚连接(SDIO方式) 

SDCard初始化

SDCacr寄存器介绍

SDCacr初始化代码


       在之前没有做过SD卡相关,做这个之前参考了正点原子、野火等等资料,花了1天时间,其实在有参考的情况下,难倒是不难,就是资料挺乱的,然后代码上面有的还有不兼容(可能因为我有的资料是F103的),对于做好的东西做一个备份和总结——后续篇幅是关于SD通过USB端口挂载U盘以及通过HAL库的SD卡操作。

  • 硬件电路

  • SD卡结构示意图

 管脚连接(SDIO方式) 

STM32-GPIO

STM32-GPIO 复用功能

SDCard管脚

其他

PC8

SDIO-D0

DATA0

PC9

SDIO-D1

DATA1

PC10

SDIO-D2

DATA2

PC11

SDIO-D3

CD/DATA3

PC12

SDIO-CLK

CLK

PD2

SDIO-CMD

CMD

 

  • SDCard初始化

  • SDCacr寄存器介绍

        SD卡共有8个寄存器,用于设定或表示SD卡信息,参考下表,这些寄存器只能通过对应的命令访问,对SD卡进行读写控制操作并不是像操作控制寄存器GPIO相关寄存器那样一次读写一个寄存器的,它是通过命令来控制的,SDIO定义了64个命令,每个命令都有意义,可以实实现某一特定功能,SD卡接收到命令之后,根据命令的要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。

名称

Bit宽度

描述

CID

128

卡识别号:用来识别SD卡的个体号码

RCA

16

相对地址:卡的本地系统地址

DSR

16

驱动级寄存器:配置卡的输出驱动

CSD

128

卡的特定数据:卡的操作条件信息

SCR

64

SD配置寄存器:SD卡特性信息

OCR

32

操作条件寄存器

SSR

512

SD状态:SD卡专有特征的信息

CSR

32

卡的状态:卡的当前状态信息

SDCacr初始化代码

首先对SDIO及中断进行设置;

使能GPIOC、GPIOD、DMA2及SDIO时钟

复位SDIO时钟

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_DMA2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE);

初始化PC8~PC12及PD2(SDIO接口)

PC8~PC12设置复用功能、推挽输出、上拉

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

PC8~PC12复用功能映射

    GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_SDIO);    
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource2,GPIO_AF_SDIO); 

解除SDIO时钟复位

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE);

设置SD卡的外设寄存器

    SDIO->POWER=0x00000000;
    SDIO->CLKCR=0x00000000;
    SDIO->ARG=0x00000000;
    SDIO->CMD=0x00000000;
    SDIO->DTIMER=0x00000000;
    SDIO->DLEN=0x00000000;
    SDIO->DCTRL=0x00000000;
    SDIO->ICR=0x00C007FF;
    SDIO->MASK=0x00000000;   

设置SDIO中断并打开中断

    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

GPIO相关设置就结束了

接着根据流程图对SD卡进行配置

 1.配置SDIO传输模式

    SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;
    SDIOCLK = 72MHz, SDIO_CK = HCLK/(178 + 2) = 400 KHz */
    SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
    SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; 
    SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;     
    SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;                     
    SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;

2.进行SD卡上电、初始化及设备参数读取

        首先进行SD卡上电:

        发送CMD0,等待回应后

        发送CMD8,等待R7响应,判断是2.0还是高容量卡。

        然后发送CMD41,等待R3响应,判断上电是否完成。

        接着进行SD卡初始化:

        发送CMD2,等待R2响应,取得CID,

        发送CMD3,等待R6响应,

        再次发送CMD3,等待R2响应。

        最后读取SD卡信息,选中SD卡,

        设置数据宽度,设置SD时钟,设置传输模式(查询或DMA)。

3.SDCard初始化

(1)SDCacr基本读写

偷懒的话可以直接去下载已经写好的sdcard读写函数,这种网上有好多

(附sdcard.c及sdcard.h(正点原子STM32F407的)容我研究下怎么上传文件)

        对一个块(Block)的读写操作

        所用函数:

        SD_WriteBlock(*buf,addr,blksize)

        SD_ReadBlock(*buf,addr,blksize)

        其中,buf是读、写数据缓存区,addr是起始地址,blksize是块大小。

        对多个块(MultiBlock)的读写操作

        所用函数:

        SD_WriteMultiBlocks(*buf,addr,blksize,nblks)

        SD_ReadMultiBlocks(*buf,addr,blksize,nblks)

        其中,buf是读、写数据缓存区,addr是起始地址,blksize是块大小,nblks是读、写块的数量。

        对扇区(Disk)的读写操作

        所用函数:

        SD_ WriteDisk(*buf,sector,cnt)

        SD_ReadDisk(*buf,sector,cnt)

        其中,buf是读、写数据缓存区,sector是扇区地址,cnt是扇区个数。

(2)SDCacr文件系统(FATFS)读写

        只有在SD卡基本读写块操作成功之后,才能进行FATFS文件的操作。

        移植FATFS文件系统之前,先下载FAT文件源码,解压后里面文件挺多的,我们需要的文件主要是diskio.c、diskio.h、ff.c、ff.h、ffconf.h、integer.h。

PS:Fatfs版本还挺多的,好像还有点差别,所以以下仅供参考

(附上述文件,容我研究下怎么上传文件)

        Integer.h:是一些数值类型的定义

        diskio.c:底层磁盘的操作函数

        ff.c:独立于底层介质操作文件的函数

        将文件移植到项目文件中,进行编译,如果出现报错一般都是重复定义啊之类的小毛病,KO掉它们。等到编译无错之后,文件系统移植成功。

        FATFS是独立于底层介质的应用函数库,对底层介质的操作都需要自己实现,文件仅仅提供一个函数接口,自己添加代码。偷懒的话可以直接去下载已经写好的sdcard读写函数,这种网上有好多,我上传的也是已经加完的。        

        完成代码的添加后,我们开始进行文件系统操作。

        首先我们对SD卡硬件进行初始化

    disk_initialize( 0 );

        初始化成功才能进行接下来的步骤。

        在文件系统中挂载一个工作区,工作区的设备号为0(相当于盘符),fs为指向工作区的指针。

    f_mount(&fs,"0",0);

        剩下的操作就比较简单了,和一般的读写文件差不多,通过,f_open、f_write、f_read等函数进行操作,详细函数操作可以查询FatFs - Generic FAT Filesystem Module

        不过fatfs版本不同,函数形参会略有不通,我用过几个版本,一开始用的也忘了哪个版本了,总出错,也不知道是我下的有问题,还是一开始代码有问题,后来换了个版本重写倒是好了,

最后,举个栗子:

写入

    res = f_open( &fsrc , "0:/Demo.csv" , FA_OPEN_APPEND | FA_WRITE);   		
	res = f_write(&fsrc, &WD, sizeof(WD), &br);  	
	res = f_write(&fsrc, "\n", sizeof("\n"), &br);   	
    f_close(&fsrc); 

读取

    res = f_open(&fsrc, "0:/Demo.csv", FA_OPEN_EXISTING | FA_READ);
    res = f_read( &fsrc, *&textFileBuffer, sizeof(textFileBuffer), &br ); 
    f_close(&fsrc);	

删除

    res = f_unlink ("0:/Demo.csv");

操作完记得卸载

    f_mount(0, "0",0);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于STM32F407的SDCard读写操作 的相关文章

  • 如何在 Cortex-M3 (STM32) 上从 RAM 执行函数?

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • 毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计

    基于STM32的智能温室控制蓝牙声光报警APP系统设计 1 项目简介 1 1 系统构成 1 2 系统功能 2 部分电路设计 2 1 stm32f103c8t6单片机最小系统电路设计 2 2 LCD1602液晶显示电路设计 2 2 风
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • HAL 锁定和解锁函数如何使用以及为什么?

    我试图理解另一位程序员编写的代码 它使用了I C http en wikipedia org wiki I C2 B2C通信以将数据写入 STM32 微控制器的 EEPROM 一般来说 我理解他的代码是如何工作的 但我不明白他为什么使用HA
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • 使用 STM32 USB 设备库将闪存作为大容量存储设备

    我的板上有这个闪存IC 它连接到我的STM32F04 ARM处理器 处理器的USB端口可供用户使用 我希望我的闪存在通过 USB 连接到 PC 时被检测为存储设备 作为第一步 我在程序中将 USB 类定义为 MSC 效果很好 因为当我将主板
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • ValueError: shapes (1,3) and (100,1) not aligned: 3 (dim 1) != 100 (dim 0)

    ValueError shapes 1 3 and 100 1 not aligned 3 dim 1 100 dim 0 出现这个错误 是你数据的维度不对 这个问题是出现在写logistic Regression 代码时出现的 用scip
  • C++拷贝构造函数

    注意 1 当函数的参数为类的对象时 那么在函数的形参与调用这个函数时的实参并不一定内容一模一样 因为是调用的拷贝构造函数 因此也有可能自定义的拷贝构造函数会导致两个对象的内容不一样 2 拷贝构造函数 只对非静态属性进行拷贝 拷贝构造函数调用
  • OpenCV中读取摄像头

    人脸识别首先要做的就是摄像头数据的读取 这里OpenCV很好的实现了摄像头数据的读取 在OpenCV1 x中用到的函数是 1 打开摄像头或视频文件 CvCapture cvCreateCameraCapture int index inde
  • ubuntu18.04安装dconf-editor以及设置root远程终端

    今天我们将学习一下dconf editor和root远程 方便我们在工作的时候 客户需要安装软件 我们就不用那么麻烦的跑道现场去给客户安装 这也是给咱们运维人员图个方便 dconf editor介绍 这个只是简单配置存储系统 图形编辑器 可
  • linux进程间通信---本地socket套接字(一)---一个server对应一个client

    先给自己打个广告 本人的微信公众号正式上线了 搜索 张笑生的地盘 主要关注嵌入式软件开发 股票基金定投 足球等等 希望大家多多关注 有问题可以直接留言给我 一定尽心尽力回答大家的问题 想要获取完整源码的 关注公众号后回复 socket1 即
  • ipa文件怎么安装到iphone_无需电脑,无需越狱,手机端一键签名安装ipa文件

    很多玩苹果的小伙伴都知道 由于ios系统的封闭性 使得很多第三方软件无法直接安装到手机 因为破解之后都需要打包 签名才可以安装到手机使用 因此好多优秀的第三方软件都无法安装到手机使用 今天 苹果用户的福音来了 一个软件 无需电脑 无需越狱
  • CentOS7环境Grafana监控系统的备份、恢复与迁移

    目的 实现Grafana系统的数据备份 迁移与恢复 最近一直在给客户的环境搭建服务资源 业务与数据库监控 这里记录下实际搭建过程中的一些问题 如下是安装grafana的服务器要迁移 需要备份迁移并做数据恢复 1 备份Grafana相关数据
  • WebService 的一些基本概念

    一 1 Endpoint http www ttdev com SimpleService 这个webservice全名就是所谓的 endpoint 2 RPC type RPC 型的Web Service 方法定义 3 Document
  • 区块链之java(一) 番外篇(数据类型)

    预先善其事 必先利其器 今天俺们讲讲智能合约和java中的一个数据类型 在智能合约中 大概有这些基本类型 能满足开发 是否有漏的呢 我也不太清楚 因为我也没有很深入的了解这块 好了 话不多说 看看具体的东西 智能合约类型如下 uint256
  • 【Python零基础入门篇 · 12】:函数的定义和作用、函数参数、函数嵌套、枚举函数enumerate

    文章目录 函数的定义和作用 函数的结构 函数调用 返回值 函数参数 区分形参和实参 必备参数 默认参数 可变参数 关键字参数 函数嵌套 枚举函数 enumerate 函数的定义和作用 函数 function 是将具有独立功能的代码块组织成为
  • 【BEVformer部署】tensorrt部署整体流程

    1 安装依赖包 CUDA cuDNN TensorRT 下载安装 CUDA 11 6 cuDNN 8 6 0 TensorRT 8 5 1 7 地址 NVIDIA PyTorch安装指令 pip install torch 1 12 1 c
  • Python爬虫 实例 网络爬虫

    一 这里是一个简单的网页爬虫例子 python import requests from bs4 import BeautifulSoup url https example com response requests get url so
  • [小技巧] git 清理 repository

    使用如下命令可以快速清除 repository 里没有被 git 管理的文件 git clean xdf 如果要保留某些后缀的文件 如 txt 文件 使用如下命令 git clean xdfe txt 参考 http stackoverfl
  • 在 NetBeans 中自动生成 get、set 和构造函数

    如果您使用的是 NetBeans 以下内容将为您节省大量时间 您可以在几秒钟内为您的变量以及构造函数自动生成函数get set以下适用于 Java 和 PHP 但我认为它也适用于其他语言 只需将光标指向您希望生成的代码出现的位置 然后按 A
  • elasticsearch 一对多普通文档子对象边界值问题

    一般为保证大数据量 低延时业务数据查询都会用到基于lucene的搜索引擎elasticsearch ES的出现解决了大数据搜索的一大问题 但是由于某些特殊业务数据就可能出现一些问题 比如 一对多业务普通索引的子对象边界值问题 什么是子对象边
  • [游戏开发][Unity]点击Play按钮后卡死很久

    一般小工程不会遇到这个问题 我在公司接手了几个老项目 都遇到了这个问题 每次Play卡顿几分钟甚至十几分钟 很是头疼 原因大概率就是下图 Packing Sprite Atlases 打包纹理图集 Windows上的Unity项目经常不显示
  • 【分治法】中位数问题和Gray码问题——武汉理工大学算法设计与分析课程实验

    1 中位数问题 问题描述 设X 0 n 1 和Y 0 n 1 为两个数组 每个数组中含有n个已排好序的数 找出X和Y的2n个数的中位数 编程任务 利用分治策略试设计一个O log n 时间的算法求出这2n个数的中位数 数据输入 由文件inp
  • UML建模详解

    摘要 本教程简要介绍了统一建模语言 面向对象问题解决的核心是构建一个模型 该模型从其通常复杂的现实世界中抽象出基本问题的基本细节 几个建模工具被包裹在UML 的标题下 代表统一建模语言 本课程的目的是介绍UML的重要亮点 UML的中心是我们
  • 二十二. Kubernetes ResourceQuota配额限制与LimitRanger限制范围

    目录 一 ResourceQuota 资源限制基础解释 二 LimitRanger 一 ResourceQuota 资源限制基础解释 官方文档 ResourceQuota 是k8s中对每个命名空间资源消耗总量提供的一种限制 可以限制指定命名
  • 基于STM32F407的SDCard读写操作

    基于STM32F407的SDCard读写操作 目录 基于STM32F407的SDCard读写操作 硬件电路 SD卡结构示意图 管脚连接 SDIO方式 SDCard初始化 SDCacr寄存器介绍 SDCacr初始化代码 在之前没有做过SD卡相