对STM32的SDIO——SD卡输入/输出模块探索了一下,今日只看了POWER UP这个函数的完成。对SDIO编写驱动,需求参阅SD卡的协议,我手上的SD卡协议是ver2.00的物理层简化协议。协议首要规则了主机(这儿便是STM32)向SD卡写入的各种操控指令,以及SD卡的初始化进程状况搬运图。了解SD卡从初始化状况搬运图开端。
这个图看起来有点杂乱,感觉无从下手,其实细心瞧瞧就跟咱们数电学的状况搬运图差不多,框框里边是各种操作,箭头指向下一步操作,直线引出去的部分便是状况产生跳转的条件。首先上电(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后检测到收到指令,紧接着发送ACMD41指令。ACMD41呼应类型是R3,该呼应回来OCR寄存器的值,稍后咱们需求这个寄存器来判别卡容量以及power up状况。留意此处参数格局规则的是HCS和Voltage Window一起确认的。填写完结构体后查看是否正确接纳指令,然后检测power up位是不是1,不是的话再次循环,是则依据条件跳出循环。假如到达最大循环次数power up依然没置位,则回来卡不可用的信息。
(7)检测卡的终究类型
正常上电好后,检测OCR的CCS为,一次来判别卡是SDHC仍是SDSC。至此,power on函数功用到此完毕。