STM32学习笔记——SDIO(1)
这个图看起来有点复杂,感觉无从下手,其实仔细瞧瞧就跟我们数电学的状态转移图差不多,框框里面是各种操作,箭头指向下一步操作,直线引出去的部分就是状态发生跳转的条件。首先上电(power-on),然后发出CMD0,再接着发送CMD8,有应答(response)判断为Ver2.00或更新的SDMC,无应答(no response)判断为ver2.00或者更新版SDMC(电压不匹配(voltage mismatch) )或ver1.X SDMC或不是SDMC。若判断为前一种情况,则问询是否为有效应答(valid response),如果不是,判断为无效卡,否则判断为有效卡且开始循环发送ACMD41指令直至SD卡发出power up应答。然后判断CCS(card capacity status——卡容量状态)位,为1则判断为ver2.00或者更新的大容量卡(high capacity SD memory card),否则判断为ver2.00或者更新的标准卡(sandard capacity SD memory card)。至此,power on工作结束。
上文只是对状态图进行了一个解读,真正要控制还是需要知道各个CMD如何发送。SD卡协议提供了几个CMD的格式以及其响应值的格式(如果有相应的话)。下面就对函数的具体编写进行下总结。
(1)初始化SDIO
利用SDIO_Init中的结构体初始化SDIO接口。该结构体有以下几个成员函数:SDIO_ClockDiv、SDIO_ClockEdge、SDIO_ClockBypass、SDIO_ClockPowerSave、SDIO_BusWide、SDIO_HardwareFlowControl。其中比较重要的是SDIO_ClockDiv成员,它确定了SDIO的分频系数,在不使用旁路时钟(ByPass)的时候SDIO_CLK=HCLK/(SDIO_ClockDiv+2),我们在这里将SDIO_CLK设置为400kHZ,就是通过设置分频系数实现的。初始化完成后,就进行第一步,也就是power on,调用SDIO_SetPowerState函数即可。最后别忘记使能SDIO的时钟。
(2)发送CMD0
由STM32向SD卡发送指令可以直接调用SDIO_SendCommand函数,该函数包含一个结构体,该结构体有以下几个成员:SDIO_Argument、SDIO_CmdIndex、SDIO_Response、SDIO_Wait、SDIO_CPSM。跟我们编程密切相关的一个是SDIO_Argument——参数,许多带有响应的命令都需要通过设置参数来实现,由于CMD0没有响应,所以此处设为0x00即可。SDIO_CmdIndex成员是该结构体核心——指令指数。也就是说,如果我要发送CMD0,SDIO_CmdIndex=0,如果发送ACMD41,SDIO_CmdIndex=41,但是注意此处SDIO_CmdIndex的值是等于指令,而且是指令的十进制形式,但是我们在给SDIO_CmdIndex赋值时必须转换成十六进制。SDIO_Wait设置等待中断。填写好结构体后检测是否正确受到CMD0,然后才能进行下一步。为了保证程序正确,这样的检测在每一个指令发送周期都是必须的。
(3)发送CMD8
用同样类似的方式发送CMD8。注意此时CMD8是带有响应的指令,接收到指令后sd返回该SDIO_Argument的值,所以对SDIO_Argument要进行特殊设置,设置后SDIO->ARG寄存器便有了该值。SDIO_Response——把应答模式设置成短应答,这是根据参考指南设置的。同样地,在填写完结构体后检查是否接收到命令。根据SD协议初始化流程图,此时如果有响应则SD遵循2.00协议,否则说明是1.x 或者mmc。无论是哪一种情况,都发送CMD55来检测。
(4)发送CMD55
CMD55是一个特殊的指令,该指令告诉主机下一个command将会是一个应用指令(application command),比如要发送ACMD41之前必须先发送CMD55。此处发送CMD55是为了检测卡的类型。不过暂时没没看懂为什么是发送CMD55,因为关于CMD55的解释中并没有提到它能够检测卡类型,只说了它的应答类型是R1。判断是SD卡或者是不支持的卡。
(5)进入循环,再次发送CMD55
这次发送CMD55就是为发送ACMD41做准备了。为什么要在循环里发送呢?因为SD协议初始化状态图中发送ACMD的过程是一个反复地,指导检测出power up为1为止,所以该处的循环条件设置成!validvoltage,validvoltage为OCR的power up位。需要注意的是例程中的循环条件是(!validvoltage) && (count < SD_MAX_VOLT_TRIAL),也就是说它设置了一个最大检测次数,当超过该检测次数仍然没有power up时就可以跳出,反馈检测失败的信息,这样程序不会死在此处。
(6)发送ACMD41
发送了CMD55后检测到
STM32学习笔记SDI 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)