sdio接口是什么_如何理解api接口

2022-11-09 17:40:41 浏览数 (1)

运用SD卡第一步,认识SDIO接口

做毕业设计需要用到大量的音频文件,一般的存储器满足不了存储要求,故选择SD卡作为存储器件。在这里记录一下自己的学习经历,学习一个新的IC,无非是要么根据时序图写出Read和Write函数,要么是根据通信总线和IC相关操作指令去完成Read和Write函数。只有能与对应IC“说话”,我们才能去开发它更多地可能性。这里以原子探索者为例,为大家介绍一下SD卡相关知识。

简要的介绍一下什么是SDIO接口

SDIO——>安全数字输入输出接口。它是在SD卡接口基础上发展而来。 SDIO 和 SD卡规范间的一个重要的区别是增加了低速标准,低速卡的目标应用是以最小硬件开支支持低速I/O能力,低速卡支持类似调制解调器,条码扫描仪和GPS接收器等应用。STM32的SDIO控制器支持多媒体卡(MMC卡)、SD存储卡、SD I/O卡和CE-ATA设备。

其特点我们直接上图:

我们可以看到SDIO接口具有向前兼容的特点,支持多种多个版本的存储卡。在高位总线模式下,也同样具有优秀的读取速度。

stm32内核自带了SDIO适配器,下面上框图(手册自带):

根据框图我们可以看到SDIO适配器的时钟与PCLK2和SDIOCLK有关,SDIO适配器的控制与SDIO_CK和SDIO_CMD有关,其数据的传输又与SDIO_D[7:0]有关(最高可以配置8位数据总线宽度)。复位情况下,SDIO_D0用于数据传输,初始化后主机可以改变数据总线的宽度通过(ACMD6命令设置)。

SDIO与外围设备的命令与响应均是通过SDIO_CMD来完成的。这里我们可以调用SDIO_SendCommand()这个库函数,用来通过SDIO总线的SDIO_CMD以SDIO_CK这样的频率,对外围设备如SD卡发送CMD命令,并且可以获取响应数据。

那么问题来了,这个SDIO_CK到底是怎么计算的呢?话不多说,我们接着上图:

通过上图我们可以得出,SDIO时钟计算公式:SDIO_CK时钟=SDIOCLK/[clkdiv 2];其中,SDIOCLK固定为48Mhz。那么我们只要配置clkdiv这个位,就能够完成对SDIO_CK的配置。clkdiv这个位在SDIO初始化函数里即可进行配置,下面上代码:

代码语言:javascript复制
  SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;	/* HCLK = 72MHz, SDIOCLK = 72MHz, SDIO_CK = HCLK/(178   2) = 400 KHz */
  SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
  SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;  //不使用bypass模式,直接用HCLK进行分频得到SDIO_CK
  SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;	// 空闲时不关闭时钟电源
  SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;	 				//1位数据线
  SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;//硬件流
  SDIO_Init(&SDIO_InitStructure);

这里SDIO_INIT_CLK_DIV = 0x76,计算一下就可以知道SDIO_CK的时钟为400KHz,数据宽度为1位。看到这里大家能可会问,这么慢的频率,这么短的数据传输位数,传输的效率能高吗?其实这里对SD卡的初始化只是为了激活SD卡,开启SDIO总线与SD卡之间的通信。真正的初始化需要一大串命令。

初始化完以后我们需要使能SDIO_CK这个时钟,SDIO->CLKCR|=1<<8; 这个寄存器我们后面再说。

SD卡与SDIO的接口

说完了SDIO接口,我们再说说这个接口需要操作的外围设备,SD卡。随便在网上买了个4GB的SD卡,大概长这个样子:

这种SD卡有9个接口,每个接口的定义如下:

一般的对于SD卡,我们的开发板上都有对应的卡槽,自己画板子的话也很好画,网上买个卡槽也很便宜,所以不要怕SD卡不好放置。

SDIO的命令与响应

SDIO的命令分为:应用相关命令(ACMD)和通用命令(CMD)两部分。发送ACMD时,需先发送CMD55。

需要注意的是,发送CMD命令只需要填充命令索引和参数即可,这两个数据相关的寄存器 SDICARG[31:0] —–>CMD[39:8] 命令的参数(根据命令所需的参数位格式设置) SDICCON[7:0] —–> CMD[47:40] 包含Start Bit,Transmission Bit,Command Index. 关于寄存器的操作都被封装成了库函数,所以我们只需要调用SDIO_SendCommand()这个库函数,即可完成发送CMD命令的要求,这个库函数还带一个参数是响应类型参数,根据长响应还是短响应到对应的寄存器去寻找返回的参数。

SDIO的所有命令和响应都是在SDIO_CMD引脚上面传输的,命令长度固定位48位,SDIO命令格式如下表所示:

其中除了命令索引和参数需要我们设置,其他都是由SDIO硬件自动控制。命令索引(如CMD0,CMD1之类)由SDIO_CMD寄存器设置,命令参数则由SDIO_ARG寄存器设置。 一般SD卡在接收到命令行以后都会有一个应答(CMD0例外),这个应答我们也称之为响应。

对于stm32的SDIO接口,支持2种响应类型:短响应(48位)和长响应(136位)。

SDIO块数据传输不论是短响应还是长响应,硬件都会自动滤除了起始位,传输位,CRC7以及结束位等信息,对于短响应,命令索引存放在SDIO_RESPCMD寄存器。参数则存放在SDIO_RESP1寄存器里面。对于长响应,则仅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4个寄存器里面。每个响应都有自己的响应格式(6种)。

到这里我们其实可以给SD卡的初始化和工作流程简要的总结一下了: ①、首先我们通过配置SDIO的初始化函数初始化SD卡,就是可以想象成把SD卡给唤醒。 ②、唤醒完了以后,我们就可以通过SDIO总线,给SD卡发送命令。 ③、SD卡收到命令后会反馈一个响应,我们可以通过响应的信息去获取SD卡的各项信息,以方便我们根据信息对于SD卡做出相应的初始化操作,比如设置数据总线宽度,设置SD卡工作频率等等。 ④、无论发送命令或者接收响应,均是通过SDIO_CMD这一个位来完成的,在没有涉及发送或者接收数据的时候,SDIO_D数据线是不参与的。

这样一看SD卡的初始化其实就是一个端口的发送和接收,是不是感觉简单了很多呢?

SD卡读写多块数据过程

读取多块数据过程

怎么说呢,就是我们发送命令,然后接收到响应的响应后通过SDIO_D数据线接收来自SD卡的数据,直到发送了STOP命令。

写入多块数据过程

至此,SD卡基本的初始化和读写信息已经介绍完毕了,SDIO总线的通信方式相信大家也很了解了,但是SD卡本身是一个非常复杂的存储IC,下一篇文章我将介绍SD卡初始化和读写数据的详细步骤。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186203.html原文链接:https://javaforall.cn

0 人点赞