STM32与SD卡通信问题详解

发布者:真诚友爱最新更新时间:2021-06-28 来源: eefocus关键字:STM32  SD卡  通信问题 手机看文章 扫描二维码
随时随地手机看文章

SD的驱动和应用困扰了我很久,寒假的时候看到SD简化版物理层协议的时候就傻掉了,看到SD的驱动快3000行的代码也动摇了。这几天几种地看了一下SD卡的相关内容,总结了一些体会,感觉也没有那么恐怖了。我决定从分层上来讨论SD的驱动和应用,因为这样可以构建一个清晰的逻辑,且不知哪位计算机大师曾说过:一切计算机问题都可以用分层的方法来解决。


我自己把SD卡从驱动到应用共分为4层,从下至上依次为:驱动层、物理层、文件系统层、应用层。下面一一来介绍各层的一些重要的操作。


1)驱动层


驱动层,对应到ST的库,就是stm32f10x_sdio.c/.h这个两文件。其实使用任何一个STM32的外设,只要用库函数都离不开这一对互相对应的.c/.h文件。对于SDIO外设来说,它就是用来操作寄存器的,由于涉及ST库函数的编写,没能力参透,在此不赘述它的实现过程。


2)物理层


这一层可以说是承上启下的一层,下接驱动层,用于操作寄存器,上接文件系统层,用于统一管理文件,可谓整个SD驱动的核心代码。其实,如果对于SD的要求不高,可以直接在这一层上面进行文件操作,只是没有文件系统操作起来实在不便。之所以叫物理层是因为这一部分的代码主要参考了“SD卡物理层简化协议”这样一个东西。这个协议规定了控制器对SD卡操作的各种指令的格式和操作时序。这一层对应了源代码中的sdio_sdcard.c/.h这两个文件,那么它主要实现了什么功能呢?这一层最重要的一个函数就是SD_Init()——SD卡的初始化函数。这函数包括了SD卡的上电、识别、卡初始这三个重要步骤,分别对应两个子函数——SD_PowerOn、SD_InitializeCards(),而SD_InitializeCards()的返回值包含了卡的类型信息。这两个子函数的实现则是通过STM32内置的SDIO控制器发送CMD命令完成,这个命令的发送要严格遵守SD协议的流程图,而且要及时进行标志位判断,否则很容易程序跑飞了。发送CMD命令是通过填写SDIO_CmdInitStructure这个结构体完成的。举个例子:


SDIO_CmdInitStructure.SDIO_Argument = 0x00;


SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;


SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;


SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;


SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;


这个结构体包含了五个参数,从上至下分别控制的是:参数、命令索引、响应格式、是否等待、硬件流控制。填写了五个结构体也就也就配置好了一个CMD命令格式,使用SDIO_SendCommand()函数发送命令即可。当然,这一层还包含了一些其他外设的初始化——NVIC(配置中断向量优先级)、GPIO(配置了SD插槽的IO口)、DMA(使用DMA模式传输)。总结一下这部分就是主机(STM32)用CMD命令控制了SD卡,所以说在这一层上就已经可以直接调用函数来进行初始化、读写操作了。那么为什么又会有文件系统层呢?


3)文件系统层


它的存在就是用来管理文件的。一个SD卡,现在普通的8个G,要是直接使用物理层来操作,就要操作人来记住好多文件的地址、长度等等,这些事情本来就是计算机可以完成的,所以人们就发明了文件系统这么个东西,用来管理大容量储存设备,在文件系统之上来进行操作,整个格局就显得很大了,也更高端大气上档次,否则调用个文件就要写个地址,什么0x20000f54之类的,用的人不得疯了。说了这么多,文件系统的作用就是一个管理层,下接SD的物理层,用来发送各种CMD操作SDIO控制器的寄存器,上承应用函数,封装好了由开发人员自由调用,可以说也是承上启下的关键代码。而且很幸运的是已经有人替你写好了这个代码的绝大部分,你只需要进行适量的修改就能为你所用,搭建起一个文件系统来。FATFS就是在一个很遥远的地方的好心人已经替你写好的东西,这东西通用性很强,与驱动层完全脱离,留下了一些接口函数,往哪个平台上移植,就填写相应的接口函数即可。这个接口连接了SD卡的物理层和文件系统的操作函数。这一层对应的ff.c/.h文件由于也是很遥远的大神编写的,参透不能。故在此不讲怎么实现。


4)应用层


这一层应该是硬件开发人员发挥的一层,因为对应的平台不同,这一层的接口函数填写就完全不同。应用层就是由上一层(文件系统层)留下的各种接口构成,我们填写了接口函数,就可以直接跑文件系统了。怎么写接口函数呢?FATFS在留接口时除了留下了函数名,还留下了参数以及参数对应的功能和格式。帮助文件中有对应接口函数要实现的功能,其实不用查帮助文件通过接口函数的名字也能猜到,比如disk_read就是读盘。这个接口函数要实现读盘功能,就得调用在物理层写下的各种函数,如SD_ReadBlock(),只要注意子函数与母函数调用参数要一致就行,这个一致性就需要开发人员充分理解函数参数功能了。这部分代码很少,编写起来也不是很难,就是要注意记得判断标志位。


至此,SD的操作函数就已经被封装好了,只需要查询FATFS中各种操作函数的功能既可以调用它。


SD驱动还有很多问题没有搞清楚,之前只是对着源码单步调试,看了看功能实现过程,接下来就准备动手移植文件系统试试了,希望能成功。SD驱动做起来还是很有意思的,通过它与其他外设,比如MP3模块或液晶屏模块连接可以实现歌曲播放和图片显示,还是颇有成就感。以前在用电子产品的时候没想到想听首歌看张图这么复杂,从0101的最原始编码到我们看到听到的模拟信号经过了这么多道的工序,想起来也只得感叹人类智慧的无穷尽也。


关键字:STM32  SD卡  通信问题 引用地址:STM32与SD卡通信问题详解

上一篇:基于STM32的带触摸屏的无线解说器
下一篇:STM32的IO口如何配置

推荐阅读最新更新时间:2024-11-09 19:42

关于STM32的入门问题
前言 前两天在群里看到群友们在讨论学习STM32的话题,并且今天也有一位机械专业的准研究生读者也问了STM32的入门问题。 正好我也有一点点经验,所以试着分享一下这个话题。我也不是什么大神,只是一名普通的工程师,以下分享仅仅是自己的一点经验及看法,仅供参考,希望能对一些初学的朋友有所帮助。老鸟略过~~ 找资料 在知乎,我也有看到类似问题:学STM32要买什么书籍、看什么书籍? STM32编程作为一项实操性很强的技能,所以要多实操。初学的话,我觉得书籍就暂时先不买吧,先考虑入手一块STM32开发板,然后跟着开发板的教程走。 几年前,做STM32的教程有很多家: 现在市面上还比较火的基本就只剩前4家了,从这4家中选择一家买
[单片机]
关于<font color='red'>STM32</font>的入门<font color='red'>问题</font>
STM32】HAL库-系统滴答定时器SysTick
SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3、CM4内核芯片,都有Systick定时器。Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。 Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。 系统滴答定时器有4个寄存器 时钟源 该定时器的时钟源可以是 内部时钟(FCLK,CM3上的自由运行时钟) 外部时钟( CM3处理器上的STCLK信号) 通过SysTick控制及状态寄存器的第2位来确定 STM32的时钟树 RCC通过AHB时钟(HCLK)8分频或者不分
[单片机]
【<font color='red'>STM32</font>】HAL库-系统滴答定时器SysTick
STM32中重要的C语言知识点整理
说在前面的话 一位初学 单片机 的小伙伴让我 推荐 C语言 书籍,因为C语言基础比较差,想把C语言重新学一遍,再去学单片机,我以前刚学单片机的时候也有这样子的想法。 其实C语言是可以边学单片机边学的,学单片机的一些例程中,遇到不懂的C语言知识,再去查相关的知识点,这样印象才会深刻些。 下面就列出了一些 STM32 中重要的C语言知识点,初学的小伙伴可以多读几遍,其中大多知识点之前都有写过,这里重新整理一下,更详细地分析解释可以阅读附带的链接。 assert_pa ram 断言(assert)就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。 断言表示为一些布尔表达式, 程序员 相信在程序中的某个特定点该表
[单片机]
<font color='red'>STM32</font>中重要的C语言知识点整理
linux下STM32开发环境搭建
前言: 本文最终目的是在 ubuntu 16.04 系统下开发STM32。 用到了 STM32CUBEMX 去生成带有 Makefile 的代码,然后使用 gcc-arm-none-eabi 工具对程序进行编译。再通过 openocd 加 CMSIS-DAP的方式连接到目标板(这里是一块STM32F103C8T6)加下载程序。最终使用 GDB 工具进行调试程序。 安装 JAVA 环境 安装 STM32CUBEMX 是需要JAVA的环境的,下载的地址详见文首“参考”项。下载 linux 版本的压缩包。将其放到 linux 系统下进行解压,注意你文件放的路径。 1:使用下面命令打开 profile sudo vi /e
[单片机]
linux下<font color='red'>STM32</font>开发环境搭建
STM32 USB SD读卡器(SDIO)
这次是做一个SD卡的USB读卡器的功能,我们就在上次NAND Flash模拟出的U盘的工程上修改了,这样的话只要修改一小部分了。 工程的绝大部分不需要修改,只要将fsmc_nand.c文件移除工程,添加上官方的关于SDIO的SD卡的驱动代码文件stm32_eval_sdio_sd.c,我讨厌出现eval,所以将该文件直接改为sdio_sdcard.c。同时,既然我们使用SDIO来驱动SD卡,所以在外设库文件组里要添加stm32_sdio.c文件,否则会出现很多未定错误。 我们接下去修改的就只有mass_mal.c这个文件了。更NAND Flash工程一样,我们改成简洁点: uint32_t Mass_Memory_Si
[单片机]
<font color='red'>STM32</font> USB SD读卡器(SDIO)
我的STM32艰苦入门经验体会与总结
  1.1为什么要把时间花在 犹豫 上?   每当我们在入门之前(ARM是这样,DSP也一样),总会会有很多疑问,会有很多顾虑。我们渴望知道学习STM32前景如何?需要啥基础?难不难?适不适合我?但是什么时候能心潮澎湃地、相当着急地开始学STM32?日子在一天一天过去!你开始行动了吗?没有行动的思索,永远都不可能入门!把这些时间用来看书吧,效果能好一万倍。   大家一般都是从51单片机过来的,回想一下,我们之前学单片机时如何入门呢?实际上都是先看书(理论),再玩板子(实践)。严格地说,应该是模仿实验。熟悉之后才会自己写程序代码实现某个功能。因此,如果你正在咨询STM32;如果你正对STM32心潮澎湃;如果你想入门STM32;那么,
[单片机]
STM32中FLASH_Status的5个状态各表示的含义详解
获取状态:FLASH_Status FLASH_GetStatus(void); 返回值是通过枚举类型定义的。 typedef enum { FLASH_BUSY = 1, //忙 FLASH_ERROR_PG, //编程错误 FLASH_ERROR_WRP, //写保护错误 FLASH_COMPLETE, //操作完成 FLASH_TIMEOUT //操作超时 }FLASH_Status;
[单片机]
STM32启动过程相关代码分析
STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\TrueSTUDIO路径下的文件进行分析。对了,我用的库是3.5的。 system_stm32f10x.c SystemInit(): 在 startup_stm32f10x_xx.s 文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有 flash的设定),这个函数 会在系统复位之后首先被执行。文件中默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周 期),PLL系数为9,开启PLL并选择
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved