小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

第12章 SD卡和SDIO接口(二)

 望穿墻 2020-05-06

轉(zhuǎn): https://www./blog/132890554114507778

12.5 SDIO初始化結(jié)構(gòu)體

了解STM32的SDIO接口的相關(guān)信息之后,接下來就開始配置SDIO接口。STM32 固件庫定義了一個SDIO初始化結(jié)構(gòu)體用于SDIO接口指定參數(shù)的初始化,具體如下:

48.jpg

1、SDIO_ClockDiv——時鐘分頻

該參數(shù)設(shè)置時鐘控制寄存器(SDIO_CLKCR)的時鐘分頻系數(shù)位(CLKDIV),它定義了輸入時鐘(SDIOCLK)與輸出時鐘(SDIO_CK)間的分頻系數(shù),范圍0~0xFF。SDIO_CK頻率=  SDIOCLK/[CLKDIV + 2]。注意:只有使能旁路時鐘分頻器,時鐘分頻才會有效。

2、SDIO_ClockEdge——時鐘相位選擇

該參數(shù)設(shè)定時鐘控制寄存器(SDIO_CLKCR)NEGEDGE位,它的指定了輸出時鐘SDIO_CK在主時鐘SDIOCLK的上升沿還是下降沿生成,具體參數(shù)如表12-23所示。

49.jpg

3、SDIO_ClockBypass——旁路時鐘分頻器

該參數(shù)設(shè)定時鐘控制寄存器(SDIO_CLKCR)的BYPASS位,它指定是否啟用或禁用了SDIO時鐘分流器旁路,如果使能BYPASS位,SDIOCLK直接驅(qū)動SDIO_CK輸出信號,否則,依據(jù)CLKDIV數(shù)值對SDIOCLK分頻,然后輸出SDIO_CK信號。

4、SDIO_ClockPowerSave——省電配置

當總線為空閑時,設(shè)置時鐘控制寄存器(SDIO_CLKCR)的PWRSAV位可以關(guān)閉SDIO_CK時鐘輸出,降低功耗,具體設(shè)置參數(shù)如表12-24所示。

50.jpg

5、SDIO_BusWide——總線寬度

SDIO接口定義了3種總線寬度,1bit、4bit、8bit,默認為1bit模式,操作SD卡傳輸數(shù)據(jù)時需要配置為4bit模式。該參數(shù)主要設(shè)置時鐘控制寄存器(SDIO_CLKCR)的 WIDBUS 位位,具體設(shè)置參數(shù)如表12-25所示。

51.jpg

6、SDIO_HardwareFlowControl——硬件流設(shè)置

硬件流控制功能可以避免FIFO下溢(發(fā)送模式)和上溢(接收模式)錯誤。該功能主要通過停止SDIO_CK并凍結(jié)SDIO狀態(tài)機,在FIFO不能進行發(fā)送和接收數(shù)據(jù)時,使得總線上數(shù)據(jù)傳輸暫停。但是 AHB接口還在工作,仍然可以讀出或?qū)懭隖IFO。通常選擇不使用硬件流功能,具體設(shè)置參數(shù)如表12-26所示。

52.jpg

12.6 SD卡初始化流程

SD卡初始化也稱為SD卡識別,主要分為三部分:卡復(fù)位、操作電壓確認(卡上電)、卡識別,初始化流程如圖12-27所示。在卡識別模式下,主機會復(fù)位所有處于“卡識別模式”的卡,以確認工作電壓范圍,識別卡,并且要求他們發(fā)布相對卡地址(Relative Card Address)。這個操作僅通過卡的 CMD線完成的。卡識別模式下,所有數(shù)據(jù)通信都只通過數(shù)據(jù)線完成。注意:識別模式時鐘頻率最大不超過400Khz。

 53.jpg

54.jpg

圖12-19初始化流程圖

12.6.1 卡復(fù)位

主機發(fā)送“軟復(fù)位命令”設(shè)置每張卡進入“Idle”狀態(tài)。只有“Inactive”無效狀態(tài)的卡不受該命令的影響。其中多媒體卡和SD卡的復(fù)位命令為CMD0(GO_IDLE_STATE),而SD I/O卡的復(fù)位命令為 CMD51(IO_RW_DIRECT)。

SD卡上電后或執(zhí)行CMD0后,所有卡的輸出端都處于高阻狀態(tài),同時所有卡都被初始化至一個默認的相對卡地址(RCA=0x0001)和默認的驅(qū)動器寄存器設(shè)置(最低的速度,最大的電流驅(qū)動能力)。

12.6.2 操作電壓范圍確認(卡上電)

所有的卡都可以使用規(guī)定范圍內(nèi)的電壓與主機通信,可支持的最小和最大電壓VDD數(shù)值由卡上的操作條件寄存器(OCR)定義,SD 2.0協(xié)議卡支持2.7V~3.6V供電范圍,上電流程如圖12-20所示。

(1)在主機和卡交互之初,主機和卡都不清楚相互支持的電壓范圍,此時就需要雙方確認電壓范圍。主機給供電卡,電壓要在250ms之內(nèi)達到VDD最小值,并且開始提供最少74個時鐘信號給SD卡,并保持SDIO_CMD線為高。

(2)上電之后,卡會進入空閑狀態(tài)(idle ),如果主機使用SD模式,CMD0非必需;如果是SPI模式,第一條命令必須發(fā)送CMD0,并且CS保持低電平讓卡進入SPI模式。

(3)發(fā)送CMD8 命令;該命令是 V2.0 規(guī)范新添加的,為的是支持多電壓范圍,用于檢查卡是否支持某個電壓。主機在初始化V2.0卡之前,應(yīng)該發(fā)送CMD8并表明主機支持的電壓。

(4)發(fā)送ACMD41命令;該命令是一個同步命令,用于來識別和拒絕那些不匹配它期望電壓范圍的卡,循環(huán)發(fā)送,直到上電時序完成。不能支持指定電壓范圍的卡在收到ACMD41 后會進入“inactive”狀態(tài)。如果主機系統(tǒng)連接了多個卡,那么主機應(yīng)該檢查所有卡滿足的電壓。

 55.jpg

圖12-20 上電流程

SD卡上電代碼如下:

56.jpg57.jpg58.jpg

12.6.3 卡識別

對于SD卡而言,卡識別過程以時鐘頻率Fod≤400Khz開始,所有SDIO_CMD輸出為推挽模式,識別過程如下:

1. 總線被激活

2. SDIO卡主機廣播發(fā)送SEND_APP_OP_COND(ACMD41)命令

3. 得到的響應(yīng)是所有卡的操作條件寄存器的內(nèi)容

4. 不兼容的卡會被置于非激活狀態(tài)

5. SDIO卡主機廣播發(fā)送ALL_SEND_CID(CMD2)至所有激活的卡

6. 所有激活的卡發(fā)送回他們唯一卡識別號(CID)并進入識別狀態(tài)。

7. SDIO卡主機發(fā)送SET_RELATIVE_ADDR(CMD3)命令和一個地址到一個激活的卡,這個新的地址被稱為相對卡地址(RCA),它比CID短,用于對卡尋址。至此,這個卡轉(zhuǎn)入待機狀態(tài)。 SDIO卡主機可以再次發(fā)送該命令更改RCA,卡的RCA將是最后一次的賦值。

8. SDIO卡主機對所有激活的卡重復(fù)上述步驟5至7。

SD卡識別代碼如下:

59.jpg60.jpg

12.6.4 SD卡初始化代碼

61.jpg

12.7  數(shù)據(jù)傳輸模式

當相對卡地址(RCA)第一次發(fā)布后,卡會處于“數(shù)據(jù)傳輸模式”,主機會在總線上所有的卡都被識別后進入這個模式。數(shù)據(jù)傳輸模式下可以讀寫SD卡的相關(guān)數(shù)據(jù)。

讀寫SD卡的操作都是在初始化后基于SD卡命令和響應(yīng)。當沒有數(shù)據(jù)傳輸時,DAT線被拉高。當有數(shù)據(jù)傳輸時,主機通過SELECT/DESELECT_CARD(CMD7)先選中卡,然后發(fā)送SET_BUS_WIDTH(ACMD6)命令選擇或取消寬總線(4位總線寬度)操作模式,ACMD6命令僅在傳輸狀態(tài)時有效,即只有選中卡后才能改變總線寬度,此時可以對SD卡進行讀寫操作。

數(shù)據(jù)傳輸時,發(fā)送方先拉低所有數(shù)據(jù)線,發(fā)送起始位;然后發(fā)送連續(xù)的數(shù)據(jù)流,數(shù)據(jù)流包含了有效數(shù)據(jù);最后拉高所有數(shù)據(jù)線發(fā)送結(jié)束位。數(shù)據(jù)傳輸是和時鐘信號同時進行的,數(shù)據(jù)傳輸?shù)挠行酝ㄟ^CRC校驗值驗證。

12.7.1 讀數(shù)據(jù)模式

已知數(shù)據(jù)傳輸?shù)幕締挝皇菈K(Black), 由CSD寄存器中的READ_BL_LEN位定義,通過CMD16可以設(shè)置數(shù)據(jù)塊的長度。但是對于SDXC和SDHC卡,數(shù)據(jù)塊長度始終為512字節(jié),CMD16不會影響數(shù)據(jù)塊的長度。另外塊讀是以塊為單位的數(shù)據(jù)傳輸,通常SD卡上都不允許“讀部分塊”。為保證數(shù)據(jù)傳輸?shù)恼_,每個數(shù)據(jù)塊后都有一個CRC校驗碼。讀數(shù)據(jù)分為單塊讀和多塊讀,具體如下:

1、 單塊讀

  單塊讀,顧名思義就是讀取單個數(shù)據(jù)塊的數(shù)據(jù)。單塊讀流程為:

(1)主機發(fā)送CMD7命令選中卡(總線只有一個SD卡時,可以省略);

(2)發(fā)送CMD16命令設(shè)置數(shù)據(jù)塊的有效長度(默認為512Byte) ;

(3)通過SDIO_DataInitTypeDef結(jié)構(gòu)體和SDIO_DataConfig函數(shù)設(shè)置數(shù)據(jù)傳輸?shù)南嚓P(guān)

參數(shù);

(4)發(fā)送CMD17命令啟動單塊讀并等待SD卡返回響應(yīng)無錯誤;

(5)初始化SDIO中斷并啟動DMA傳輸,必須保證DMA數(shù)據(jù)緩沖區(qū)按照4字節(jié)對齊(緩沖區(qū)大小為4的整數(shù)倍);

CMD17(READ_SINGLE_BLOCK)命令用于啟動一次讀數(shù)據(jù)塊操作,其命令參數(shù)中指出了被讀數(shù)據(jù)塊的地址,數(shù)據(jù)塊內(nèi)的任意地址都將指向該數(shù)據(jù)塊。數(shù)據(jù)從主機命令結(jié)束的Nac個周期后開始傳輸,數(shù)據(jù)的最后為CRC校驗。Nac為標準SD卡訪問時間,最小為2個SDIOCLK周期,最大讀超時固定為100ms,單塊讀時序如圖12-21 所示。

 62.jpg

圖12-21單塊讀命令時序

具體代碼如下:

63.jpg

   2、多塊讀

多塊讀就是讀完一個數(shù)據(jù)塊,繼續(xù)讀下一個數(shù)據(jù)塊,直至發(fā)送停止命令,多塊讀流程:

(1)主機發(fā)送CMD7命令選中卡(總線只有一個SD卡時,可以省略);

(2)發(fā)送CMD16命令設(shè)置數(shù)據(jù)塊的有效長度(一般默認為512Byte) ;

(3)通過SDIO_DataInitTypeDef結(jié)構(gòu)體和SDIO_DataConfig函數(shù)設(shè)置數(shù)據(jù)傳輸?shù)南嚓P(guān)參數(shù);

(4)主機發(fā)送CMD18命令啟動多個數(shù)據(jù)塊的讀操作,并等待SD卡返回響應(yīng)無錯誤

(5)初始化SDIO中斷并啟動DMA傳輸,必須保證DMA數(shù)據(jù)緩沖區(qū)按照4字節(jié)對齊;

(6)開始傳輸數(shù)據(jù),直到數(shù)據(jù)傳輸完畢或者收到CMD12(STOP_TRANSMISSON)命令;

CMD18(READ_MULTIPLE_BLOCK)為讀取多個連續(xù)的數(shù)據(jù)塊命令,其參數(shù)包含被讀數(shù)據(jù)塊的地址(該地址同樣可以為數(shù)據(jù)塊內(nèi)任意地址),SDIO_DataInitTypeDef結(jié)構(gòu)體中定義了待傳輸?shù)臄?shù)據(jù)量。一旦發(fā)送CMD18啟動傳輸,主機間隔Nac個周期讀取一次數(shù)據(jù),直至讀完設(shè)定的數(shù)據(jù)量。一旦收到CMD12停止傳輸命令,數(shù)據(jù)傳輸會在收到停止命令后的兩個時鐘周期停止,多塊讀命令時序如圖12-22 所示。

 64.jpg

圖 12-22 多塊讀命令時序

SD卡多塊讀代碼:

65.jpg66.jpg67.jpg

12.7.2 寫數(shù)據(jù)模式

寫數(shù)據(jù)的數(shù)據(jù)傳輸格式和讀數(shù)據(jù)類似,寫數(shù)據(jù)前SD卡會自動擦除待寫的數(shù)據(jù)塊,并檢測每一個數(shù)據(jù)塊的CRC值,只有數(shù)據(jù)準確無誤時才會寫入到數(shù)據(jù)塊中。如果發(fā)生BLOCK_LEN_ERROR和ADDRESS_ERROR的錯誤,寫命令將不被執(zhí)行,寫數(shù)據(jù)分為單塊寫和多塊寫。

1、單塊寫

單塊寫其實就是擦除一個數(shù)據(jù)塊(不需要手動擦除),寫入一個數(shù)據(jù)塊。通過執(zhí)行寫數(shù)據(jù)塊命令(CMD24~27),主機將一個或多個數(shù)據(jù)塊的數(shù)據(jù)傳送到卡,每個數(shù)據(jù)塊之后都有CRC,單塊寫數(shù)據(jù)流程如下:

(1)主機發(fā)送 CMD7 命令選擇一個卡進行寫操作(總線只有一個卡時可以忽略);

(2)主機通過 CMD16命令設(shè)置需要進行塊傳輸?shù)挠行K長度(默認為512Byte);

(3)通過SDIO_DataInitTypeDef結(jié)構(gòu)體和SDIO_DataConfig函數(shù)設(shè)置數(shù)據(jù)傳輸?shù)南嚓P(guān)參數(shù);

(4)發(fā)送 CMD24 作為開始,標明起始地址,等待卡響應(yīng)無錯誤 ;

(5)初始化SDIO中斷并啟動DMA傳輸;

CMD24(WRITE_BLOCK)為寫數(shù)據(jù)塊命令,其參數(shù)為待寫入數(shù)據(jù)塊地址。主機的數(shù)據(jù)傳輸在收到響應(yīng)后的 Nwr 時鐘周期后開始,數(shù)據(jù)后跟著CRC校驗位,允許卡來檢查是否有傳輸錯誤。卡通過DAT0傳回CRC檢測結(jié)果。如果有錯誤,那么發(fā)送否定CRC狀態(tài)‘101’。如果沒有錯誤,發(fā)送正確 CRC 狀態(tài)‘010’,以及數(shù)據(jù)編程處理狀態(tài)。當發(fā)生編程錯誤的時候,卡會忽略所有后續(xù)塊。這種情況下,不會有 CRC 響應(yīng)發(fā)給主機,因此,總線上也不會有 CRC 起始位,但是可以讀到 3bit 的 CRC 狀態(tài)‘111’,單塊寫命令時序如圖12-23 所示。

 68.jpg

圖12-23 單塊寫命令時序

SD卡單塊寫代碼:

69.jpg

2、多塊寫

多塊寫模式,卡會在主機發(fā)送寫命令之后收到連續(xù)的數(shù)據(jù)塊。并且多塊寫通過預(yù)擦除指令(ACMD23)一次性將要寫入的所有數(shù)據(jù)塊全部擦除。同單塊寫類似,數(shù)據(jù)后跟著 CRC 校驗位,允許卡檢查數(shù)據(jù)正確性。多塊寫數(shù)據(jù)流程:

(1)主機發(fā)送 CMD7 命令選擇一個卡進行寫操作(總線只有一個卡時可以忽略);

(2)主機通過 CMD16命令設(shè)置需要進行塊傳輸?shù)挠行K長度(一般默認為512Byte);

(3)通過SDIO_DataInitTypeDef結(jié)構(gòu)體和SDIO_DataConfig函數(shù)設(shè)置數(shù)據(jù)傳輸?shù)南嚓P(guān)參數(shù);

(4)發(fā)送ACMD55告訴卡下一條命令為特定應(yīng)用命令,而非標準命令;

(5)發(fā)送ACMD23設(shè)置需要擦除的塊的數(shù)目,一次性擦除,提高效率  

(6)發(fā)送CMD25,啟動連續(xù)寫數(shù)據(jù)塊模式

(7)初始化SDIO中斷并啟動DMA傳輸;

主機如果想使用“預(yù)擦除”功能,應(yīng)該僅僅在WTITE 命令之前發(fā)送 ACMD23。如若不然的話,“預(yù)擦除數(shù)目”可能會在其他命令執(zhí)行的時候被自動清除。如果發(fā)送CMD12命令,數(shù)據(jù)傳輸將被停止,多塊寫命令時序如圖12-24 所示。

 70.jpg

圖12-24 多塊寫命令時序

71.jpg72.jpg

同理,將SD卡單塊寫和多塊寫整合為SDWrite函數(shù),使用時直接調(diào)用即可,需要注意每次寫入的數(shù)據(jù)需要占用一個單獨的塊,即使未寫滿,再次寫入時需要從下個數(shù)據(jù)塊開始。

73.jpg

12.7.3 擦除模式

擦除的基本單位是擦除組,擦除組包含若干個數(shù)據(jù)塊(大于等于1),由擦除命令的地址域設(shè)定,卡會舍棄未與擦除組大小對齊的部分,把地址邊界對齊到擦除組的邊界,換句話說,擦除命令會擦除設(shè)定地址區(qū)域所涉及的所有數(shù)據(jù)塊,而非部分數(shù)據(jù)塊。已知W25Q128擦除后擦除后數(shù)據(jù)默認全為1,而對于SD卡而言,擦除后的數(shù)據(jù)是‘0’還是‘1’由SD卡的SCR寄存器的DATA_STAT_AFTER_ERASE(bit55)定義。

擦除流程如下:

(1)主機發(fā)送CMD32(ERASE_WR_BLK_START)和CMD33(ERASE_WR_BLK_END)命令定義連續(xù)范圍的開始和結(jié)束地址;

(2)發(fā)送CMD38(ERASE)開始擦除。如果順序不對,卡會設(shè)置 ERASE_SEQ_ERROR位到狀態(tài)寄存器,并且重啟整個序列。

注意:SD I/O卡使用ERASE_GROUP_START(CMD35)和ERASE_GROUP_END(CMD36) 命令定義連續(xù)范圍的開始和結(jié)束地址。

如果收到了除CMD13(SEND_STATUS)和擦除命令之外的其它命令,卡在狀態(tài)寄存器中設(shè)置ERASE_RESET位,解除擦除序列并執(zhí)行新的命令。如果擦除范圍包含了寫保護數(shù)據(jù)塊,這些塊將不被擦除,只有未保護的塊被擦除,同時卡在狀態(tài)寄存器中設(shè)置WP_ERASE_SKIP狀態(tài)位,在擦除過程中,卡拉低SDIO_D信號。

SD卡擦除代碼如下:

74.jpg75.jpg

12.8 串口讀寫SD卡實驗

實際開發(fā)中,SD卡多與文件系統(tǒng)搭配使用,為了測試SD卡的相關(guān)功能,將第6章的串口讀寫Flash例程略作修改,改寫為串口讀寫SD卡。

讀指令格式:sd-read  + Block編號 + 待讀取字節(jié)數(shù)

寫指令格式:sd-write + Block編號 + 待寫入數(shù)據(jù)

擦除指令格式:sd-erase + 起始Block編號 + 終止Block編號,如果擦除單個數(shù)據(jù)塊,起始和終止Block塊編號相同。

具體代碼如下:

76.jpg77.jpg78.jpg79.jpg80.jpg

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多