MCU微課堂
CKS32F4xx系列SDIO
第二十四期 2023.10.5
很多單片機(jī)系統(tǒng)都需要大容量存儲(chǔ)設(shè)備,以存儲(chǔ)數(shù)據(jù)。目前常用的有U盤,F(xiàn)LASH芯片,SD卡等。他們各有優(yōu)點(diǎn),綜合比較,最適合單片機(jī)系統(tǒng)的莫過于SD卡了,它不僅容量可以做到很大(32GB以上),支持SPI/SDIO驅(qū)動(dòng),而且有多種體積的尺寸可供選擇(標(biāo)準(zhǔn)的SD卡尺寸,以及TF卡尺寸等),能滿足不同應(yīng)用的要求。
CKS32F4xx系列的SDIO控制器支持多媒體卡(MMC卡)、SD存儲(chǔ)卡、SD I/O卡和CE-ATA設(shè)備等。SDIO的主要功能如下: 1. 與多媒體卡系統(tǒng)規(guī)格書版本4.2全兼容。支持三種不同的數(shù)據(jù)總線模式:1位(默認(rèn))、4位和8位。 2. 與較早的多媒體卡系統(tǒng)規(guī)格版本全兼容(向前兼容)。 3. 與SD存儲(chǔ)卡規(guī)格版本2.0全兼容。 4. 與SD I/O卡規(guī)格版本2.0全兼容:支持良種不同的數(shù)據(jù)總線模式:1位(默認(rèn))和4位。 5. 完全支持CE-ATA功能(與CE-ATA數(shù)字協(xié)議版本1.1全兼容)。8位總線模式下數(shù)據(jù)傳輸速率可達(dá)48MHz(分頻器旁路時(shí))。 數(shù)據(jù)和命令輸出使能信號(hào),用于控制外部雙向驅(qū)動(dòng)器。
SDIO主要功能及框圖
CKS32F4xx系列的SDIO控制器包含2個(gè)部分:SDIO適配器模塊和APB2總線接口,其功能框圖如下:

圖1?CKS32F4xx系列SDIO控制器功能框圖
復(fù)位后默認(rèn)情況下SDIO_D0用于數(shù)據(jù)傳輸。初始化后主機(jī)可以改變數(shù)據(jù)總線的寬度(通過ACMD6命令設(shè)置)。 如果一個(gè)多媒體卡接到了總線上,則SDIO_D0、SDIO_D[3:0]或SDIO_D[7:0]可以用于數(shù)據(jù)傳輸。MMC版本V3.31和之前版本的協(xié)議只支持1位數(shù)據(jù)線,所以只能用SDIO_D0(為了通用性考慮,在程序里面我們只要檢測(cè)到是MMC卡就設(shè)置為1位總線數(shù)據(jù))。 如果一個(gè)SD或SD I/O卡接到了總線上,可以通過主機(jī)配置數(shù)據(jù)傳輸使用SDIO_D0或SDIO_D[3:0]。所有的數(shù)據(jù)線都工作在推挽模式。 SDIO_CMD有兩種操作模式: ①用于初始化時(shí)的開路模式(僅用于MMC版本V3.31或之前版本) ②用于命令傳輸?shù)耐仆炷J?SD/SD I/O卡和MMC V4.2在初始化時(shí)也使用推挽驅(qū)動(dòng))
SDIO時(shí)鐘
SDIO總共有3個(gè)時(shí)鐘:
1. 卡時(shí)鐘(SDIO_CK):每個(gè)時(shí)鐘周期在命令和數(shù)據(jù)線上傳輸1位命令或數(shù)據(jù)。對(duì)于多媒體卡V3.31協(xié)議,時(shí)鐘頻率可以在0MHz至20MHz間變化;對(duì)于多媒體卡V4.0/4.2協(xié)議,時(shí)鐘頻率可以在0MHz至48MHz間變化;對(duì)于SD或SD I/O卡,時(shí)鐘頻率可以在0MHz至25MHz間變化。
2. SDIO適配器時(shí)鐘(SDIOCLK):該時(shí)鐘用于驅(qū)動(dòng)SDIO適配器,來自PLL48CK,一般為48Mhz,并用于產(chǎn)生SDIO_CK時(shí)鐘。
3. APB2總線接口時(shí)鐘(PCLK2):該時(shí)鐘用于驅(qū)動(dòng)SDIO的APB2總線接口,其頻率為HCLK/2,一般為84Mhz。
我們的SD卡時(shí)鐘(SDIO_CK),根據(jù)卡的不同,可能有好幾個(gè)區(qū)間,這就涉及到時(shí)鐘頻率的設(shè)置,SDIO_CK與SDIOCLK的關(guān)系(時(shí)鐘分頻器不旁路時(shí))為:
SDIO_CK=SDIOCLK/(2+CLKDIV)
其中,SDIOCLK為PLL48CK,一般是48Mhz,而CLKDIV則是分配系數(shù),可以通過SDIO的SDIO_CLKCR寄存器進(jìn)行設(shè)置(確保SDIO_CK不超過卡的最大操作頻率)。注意,以上公式,是時(shí)鐘分頻器不旁路時(shí)的計(jì)算公式,當(dāng)時(shí)鐘分頻器旁路時(shí),SDIO_CK直接等于 SDIOCLK。
這里要提醒大家,在SD卡剛剛初始化的時(shí)候,其時(shí)鐘頻率(SDIO_CK)是不能超過400Khz的,否則可能無法完成初始化。在初始化以后,就可以設(shè)置時(shí)鐘頻率到最大了(但不可超過SD卡的最大操作時(shí)鐘頻率)。
SDIO命令與響應(yīng)
SDIO的命令分為應(yīng)用相關(guān)命令(ACMD)和通用命令(CMD)兩部分,應(yīng)用相關(guān)命令(ACMD)的發(fā)送,必須先發(fā)送通用命令(CMD55),然后才能發(fā)送應(yīng)用相關(guān)命令(ACMD)。SDIO的所有命令和響應(yīng)都是通過SDIO_CMD引腳傳輸?shù)模魏蚊畹拈L度都是固定為48位,SDIO的命令格式如表1所示:

表1?SDIO命令格式
所有的命令都是由MCU發(fā)出,其中開始位、傳輸位、CRC7和結(jié)束位由SDIO硬件控制,我們需要設(shè)置的就只有命令索引和參數(shù)部分。其中命令索引(如CMD0,CMD1)在SDIO_CMD寄存器里面設(shè)置,命令參數(shù)則由寄存器SDIO_ARG設(shè)置。 一般情況下,選中的SD卡在接收到命令之后,都會(huì)回復(fù)一個(gè)應(yīng)答(CMD0是無應(yīng)答),這個(gè)應(yīng)答我們稱之為響應(yīng),響應(yīng)也是在CMD線上串行傳輸?shù)摹KS32F4xx系列的SDIO控制器支持2種響應(yīng)類型,即:短響應(yīng)(48位)和長響應(yīng)(136位),這兩種響應(yīng)類型都帶CRC錯(cuò)誤檢測(cè)(不帶CRC的響應(yīng)應(yīng)忽略CRC錯(cuò)誤標(biāo)志,如CMD1響應(yīng))。

表2 短響應(yīng)格式

表3?長響應(yīng)的格式
同樣,硬件為我們?yōu)V除了開始位、傳輸位、CRC7以及結(jié)束位等信息,對(duì)于短響應(yīng),命令索引存放在SDIO_RESPCMD寄存器,參數(shù)則存放在SDIO_RESP1寄存器里面。對(duì)于長響應(yīng),則僅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4個(gè)寄存器。SD存儲(chǔ)卡總共有5類響應(yīng)(R1、R2、R3、R6、R7),我們這里以R1為例簡單介紹一下。R1(普通響應(yīng)命令)響應(yīng)輸入短響應(yīng),其長度為48位,R1響應(yīng)的格式如表4所示:

表4 R1響應(yīng)格式
在收到R1響應(yīng)后,我們可以從SDIO_RESPCMD寄存器和SDIO_RESP1寄存器分別讀出命令索引和卡狀態(tài)信息。關(guān)于其他響應(yīng)的介紹,請(qǐng)大家參考SD卡2.0協(xié)議。 最后,我們看看數(shù)據(jù)在SDIO控制器與SD卡之間的傳輸。對(duì)于SDI/SDIO存儲(chǔ)器,數(shù)據(jù)是以數(shù)據(jù)塊的形式傳輸?shù)模鴮?duì)于MMC卡,數(shù)據(jù)是以數(shù)據(jù)塊或者數(shù)據(jù)流的形式傳輸。本節(jié)我們只考慮數(shù)據(jù)塊形式的數(shù)據(jù)傳輸。

圖2 SDIO(多個(gè))塊讀取操作
從上圖,我們可以看出,從機(jī)在收到主機(jī)相關(guān)命令后,開始發(fā)送數(shù)據(jù)塊給主機(jī),所有數(shù)據(jù)塊都帶有CRC校驗(yàn)值(CRC由SDIO硬件自動(dòng)處理),單個(gè)數(shù)據(jù)塊讀的時(shí)候,在收到1個(gè)數(shù)據(jù)塊以后即可以停止了,不需要發(fā)送停止命令(CMD12)。但是多塊數(shù)據(jù)讀的時(shí)候,SD卡將一直發(fā)送數(shù)據(jù)給主機(jī),直到接到主機(jī)發(fā)送的STOP命令(CMD12)。

圖3?SDIO(多個(gè))塊寫入操作
數(shù)據(jù)塊寫操作同數(shù)據(jù)塊讀操作基本類似,只是數(shù)據(jù)塊寫的時(shí)候,多了一個(gè)繁忙判斷,新的數(shù)據(jù)塊必須在SD卡非繁忙的時(shí)候發(fā)送。這里的繁忙信號(hào)由SD卡拉低SDIO_D0,以表示繁忙,SDIO硬件自動(dòng)控制,不需要我們軟件處理。
SD卡初始化流程
要實(shí)現(xiàn)SDIO驅(qū)動(dòng)SD卡,最重要的步驟就是SD卡的初始化,只要SD卡初始化完成,那么剩下的讀寫操作就簡單了,所以我們這里重點(diǎn)介紹SD卡的初始化。從SD卡2.0協(xié)議中,我們得到SD卡初始化流程圖如圖4所示:

圖4?SD卡初始化流程
從圖中,我們看到,不管什么卡(這里我們將卡分為4類:SD2.0高容量卡(SDHC,最大32G),SD2.0標(biāo)準(zhǔn)容量卡(SDSC,最大2G),SD1.x卡和MMC卡),首先我們要執(zhí)行的是卡上電(需要設(shè)置SDIO_POWER[1:0]=11),上電后發(fā)送CMD0,對(duì)卡進(jìn)行軟復(fù)位,之后發(fā)送CMD8命令,用于區(qū)分SD卡2.0,只有2.0及以后的卡才支持CMD8命令,MMC卡和V1.x的卡,是不支持該命令的。
在發(fā)送CMD8后,發(fā)送ACMD41(注意發(fā)送ACMD41之前要先發(fā)送CMD55),來進(jìn)一步確認(rèn)卡的操作電壓范圍,并通過HCS位來告訴SD卡,主機(jī)是不是支持高容量卡(SDHC)。 對(duì)于支持CMD8指令的卡,主機(jī)通過ACMD41的參數(shù)設(shè)置HCS位為1,來告訴SD卡主機(jī)支SDHC卡,如果設(shè)置為0,則表示主機(jī)不支持SDHC卡,SDHC卡如果接收到HCS為0,則永遠(yuǎn)不會(huì)反回卡就緒狀態(tài)。對(duì)于不支持CMD8的卡,HCS位設(shè)置為0即可。
SD卡在接收到ACMD41后,返回OCR寄存器內(nèi)容,如果是2.0的卡,主機(jī)可以通過判斷OCR的CCS位來判斷是SDHC還是SDSC;如果是1.x的卡,則忽略該位。OCR寄存器的最后一個(gè)位用于告訴主機(jī)SD卡是否上電完成,如果上電完成,該位將會(huì)被置 1。 對(duì)于MMC卡,則不支持ACMD41,不響應(yīng)CMD55,對(duì)MMC卡,我們只需要在發(fā)送CMD0后,再發(fā)送CMD1(作用同ACMD41),檢查MMC卡的OCR寄存器,實(shí)現(xiàn)MMC卡的初始化。
至此,我們便實(shí)現(xiàn)了對(duì)SD卡的類型區(qū)分,最后發(fā)送CMD2和CMD3命令,用于獲得卡CID寄存器數(shù)據(jù)和卡相對(duì)地址(RCA)。 SD卡在收到CMD2后,將返回R2長響應(yīng)(136位),其中包含128位有效數(shù)據(jù)(CID寄存器內(nèi)容),存放在SDIO_RESP1~4等4個(gè)寄存器里面。通過讀取這四個(gè)寄存器,就可以獲得SD卡的CID信息。
CMD3用于設(shè)置卡相對(duì)地址(RCA,必須為非0),對(duì)于SD卡(非MMC卡),在收到CMD3后,將返回一個(gè)新的RCA給主機(jī),方便主機(jī)尋址。RCA的存在允許一個(gè)SDIO接口掛多個(gè)SD卡,通過RCA來區(qū)分主機(jī)要操作的是哪個(gè)卡。而對(duì)于MMC卡,則不是由SD卡自動(dòng)返回RCA,而是主機(jī)主動(dòng)設(shè)置MMC卡的RCA,即通過CMD3帶參數(shù)(高16位用于RCA設(shè)置),實(shí)現(xiàn)RCA設(shè)置。同樣MMC卡也支持一個(gè)SDIO接口掛多個(gè)MMC卡,不同于SD卡的是所有的RCA都是由主機(jī)主動(dòng)設(shè)置的,而SD卡的RCA則是SD卡發(fā)給主機(jī)的。
在獲得卡RCA之后,我們便可以發(fā)送CMD9(帶RCA參數(shù)),獲得SD卡的CSD寄存器內(nèi)容,從CSD寄存器,我們可以得到SD卡的容量和扇區(qū)大小等十分重要的信息。CSD寄存器我們?cè)谶@里就不詳細(xì)介紹了,關(guān)于CSD寄存器的詳細(xì)介紹,請(qǐng)大家參考SD卡2.0協(xié)議。 至此,我們的SD卡初始化基本就結(jié)束了,最后通過CMD7命令,選中我們要操作的SD卡,即可開始對(duì)SD卡的讀寫操作了。
編輯:黃飛
?
電子發(fā)燒友App






































評(píng)論