国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

第二十一章 SDIO接口(SDIO)

W55MH32 ? 來源:W55MH32 ? 作者:W55MH32 ? 2025-05-29 14:36 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機

W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。

在封裝規格上,W55MH32 提供了兩種選擇:QFN68和QFN100。

W55MH32Q采用QFN68封裝版本,尺寸為8x8mm,它擁有36個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、3個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN以及1個USB2.0。在保持與同系列其他版本一致的核心性能基礎上,僅減少了部分GPIO以及SDIO接口,其他參數保持一致,性價比優勢顯著,尤其適合網關模組等對空間布局要求較高的場景。緊湊的尺寸和精簡化外設配置,使其能夠在有限空間內實現高效的網絡連接與數據交互,成為物聯網網關、邊緣計算節點等緊湊型設備的理想選擇。 同系列還有QFN100封裝的W55MH32L版本,該版本擁有更豐富的外設資源,適用于需要多接口擴展的復雜工控場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。

此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及MQTT SSL等,為網絡通信安全再添保障。

為助力開發者快速上手與深入開發,基于W55MH32Q這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。

若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

wKgZO2gbOfaAVPzkACJSygzv-rI600.png

第二十一章 SDIO接口(SDIO)

1 SDIO 主要功能

SD/SDIOMMC 卡主機模塊(SDIO)在 AHB 外設總線和多媒體卡(MMC)、SD 存儲卡、SDIO 卡和 CE-ATA設備間提供了操作接口。多媒體卡系統規格書由 MMC技術委員會發布,可以在多媒體卡協會的網站上(www.mmca.org)獲得。CE-ATA 系統規格書可以在 CE-ATA 工作組的網站上(www.ce-ata.org)獲得。SDIO 的主要功能如下:

?與多媒體卡系統規格書版本 4.2 全兼容。支持三種不同的數據總線模式:1 位(默認)、4 位和8 位。

?與較早的多媒體卡系統規格版本全兼容(向前兼容)。

?與 SD 存儲卡規格版本 2.0 全兼容。

?與 SDI/O 卡規格版本 2.0 全兼容:支持良種不同的數據總線模式:1 位(默認)和 4 位。

?完全支持 CE-ATA 功能(與 CE-ATA 數字協議版本 1.1 全兼容)。

?8 位總線模式下數據傳輸速率可達 48MHz。

?數據和命令輸出使能信號,用于控制外部雙向驅動器

注: 1.SDIO 沒有 SPI 兼容的通信模式

2.在多媒體卡系統規格書版本 2.11 中,定義 SD 存儲卡協議是多媒體卡協議的超集。只支持 I/O模式的 SD 卡或復合卡中的 I/O 部分不能支持 SD 存儲備中很多需要的命令,這里有些命令在SDI/O 設備中不起作用,如擦除命令,因此 SDIO 不支持這些命令。另外,SD 存儲卡和 SDI/O 卡中有些命令是不同的SDIO 也不支持這些命令。細節可以參考 SDI/O 卡規格書版本 1.0。使用現有的 MMC 命令機制,在 MMC 接口上可以實現 CE-ATA 的支持。SDIO 接口的電氣和信號定義詳見MMC 參考資料。多媒體卡/SD 總線將所有卡與控制器相連。當前版本的 SDIO 在同一時間里只能支持一個 SD/SDIO/MMC4.2 卡,但可以支持多個 MMC 版本4.1 或以前版本的卡。

2 SDIO 總線拓撲

總線上的通信是通過傳送命令和數據實現。在多媒體卡/SD/SDI/O 總線上的基本操作是命令/響應結構,這樣的總線操作在命令或總線機制下實現信息交換;另外,某些操作還具有數據令牌。在 SD/SDIO 存儲器卡上傳送的數據是以數據塊的形式傳輸;在 MMC 上傳送的數據是以數據塊或數據流的形式傳輸;在 CE-ATA 設備上傳送的數據也是以數據塊的形式傳輸。

wKgZPGg3_D2AP1uzAAD0FoKNbs4888.png

SDIO“無響應”和“無數據”操作

wKgZPGg3_D2AKTKaAAGQseHRVow537.png

SDIO(多)數據塊讀操作

wKgZO2g3_D2Aa5vZAAHjMa52ZzY548.png

SDIO(多)數據塊寫操作

SDIO 連續讀操作

wKgZPGg3_D6AUwraAAFH_NZmLD8715.png

SDIO 連續寫操作

3 SDIO 功能描述

SDIO 包含 2 個部分:

?--SDIO 適配器模塊:實現所有 MMC/SD/SDI/O 卡的相關功能,如時鐘的產生、命令和數據的傳送。

?--AHB 總線接口:操作 SDIO 適配器模塊中的寄存器,并產生中斷和 DMA 請求信號。

wKgZO2g3_D6AP1ETAAEEhoaR4VM318.png

SDIO 框圖

復位后默認情況下 SDIO_D0 用于數據傳輸。初始化后主機可以改變數據總線的寬度。如果一個多媒體卡接到了總線上,則 SDIO_D0、SDIO_D[3:0]或 SDIO_D[7:0]可以用于數據傳輸。MMC 版本 V3.31 和之前版本的協議只支持 1 位數據線,所以只能用 SDIO_D0。如果一個 SD 或 SDI/O 卡接到了總線上,可以通過主機配置數據傳輸使用 SDIO_D0 或 SDIO_D[3:0]。所有的數據線都工作在推挽模式。

SDIO_CMD 有兩種操作模式:

?用于初始化時的開路模式(僅用于 MMC 版本 V3.31 或之前版本)

?用于命令傳輸的推挽模式(SD/SDI/O 卡和 MMCV4.2 在初始化時也使用推挽驅動)

SDIO_CK 是卡的時鐘:每個時鐘周期在命令和數據線上傳輸 1 位命令或數據。對于多媒體卡 V3.31協議,時鐘頻率可以在 0MHz 至 20MHz 間變化;對于多媒體卡 V4.0/4.2 協議,時鐘頻率可以在0MHz 至 48MHz 間變化;對于 SD 或 SDI/O 卡,時鐘頻率可以在 0MHz 至 25MHz 間變化。SDIO 使用兩個時鐘信號:

?SDIO 適配器時鐘(SDIOCLK=HCLK)

?AHB 總線時鐘(HCLK/2)

下表適用于多媒體卡/SD/SDI/O 卡總線:

表 SDIO 引腳定義

引腳 方向 說明
SDIO_CK 輸出 多媒體卡 / SD/SDIO 卡時鐘。這是從主機至卡的時鐘線。
SDIO_CMD 雙向 多媒體卡 / SD/SDIO 卡命令。這是雙向的命令 / 響應信號線。
SDIO_D[7:0] 雙向 多媒體卡 / SD/SDIO 卡數據。這些是雙向的數據總線。

3.1 SDIO 適配器

下圖是簡化的 SDIO 適配器框圖:

wKgZO2g3_D6ASWClAAGZb7hgoSI870.png

SDIO 適配器

SDIO 適配器是多媒體/加密數字存儲卡總線的主設備(主機),用于連接一組多媒體卡或加密數字存儲卡,它包含以下 5 個部分:

?適配器寄存器模塊

?控制單元

?命令通道

?數據通道

?數據 FIFO

注: 適配器寄存器和 FIFO 使用 AHB 總線一側的時鐘(HCLK/2),控制單元、命令通道和數據通道使SDIO 適配器一側的時鐘(SDIOCLK)。

適配器寄存器模塊

適配器寄存器模塊包含所有系統寄存器。該模塊還產生清除多媒體卡中靜態標記的信號,當在SDIO 清除寄存器中的相應位寫'1'時會產生清除信號。

控制單元

控制單元包含電源管理功能和為存儲器卡提供的時鐘分頻。共有三種電源階段:

?電源關閉

?電源啟動

?電源開

wKgZPGg3_D2AXfKJAADnA4ip9Us059.png

控制單元

上圖為控制單元的框圖,有電源管理和時鐘管理子單元。在電源關閉和電源啟動階段,電源管理子單元會關閉卡總線上的輸出信號。時鐘管理子單元產生和控制 SDIO_CK 信號。SDIO_CK 輸出可以使用時鐘分頻或時鐘旁路模式。下述情況下沒有時鐘輸出:

?復位后

?在電源關閉和電源啟動階段

?當啟動了省電模式并且卡總線處于空閑狀態(命令通道和數據通道子單元進入空閑階段后的 8個時鐘周期)

命令通道

命令通道單元向卡發送命令并從卡接收響應。

wKgZPGg3_D6Ads47AAGl0NAjGOE088.png

SDIO適配器命令通道

命令通道狀態機(CPSM)

當寫入命令寄存器并設置了使能位,開始發送命令。命令發送完成時,命令通道狀態機(CPSM)設置狀態標志并在不需要響應時進入空閑狀態(見下圖)。當收到響應后,接收到的CRC 碼將會與內部產生的 CRC 碼比較,然后設置相應的狀態標志。

wKgZPGg3_D-AYyfVAAS84VSCcMA798.png

命令通道狀態機(CPSM)

當進入等待(Wait)狀態時,命令定時器開始運行;當 CPSM 進入接收(Receive)狀態之前,產生了超時,則設置超時標志并進入空閑(Idle)狀態。

注: 命令超時固定為 64 個 SDIO_CK 時鐘周期。

如果在命令寄存器設置了中斷位,則關閉定時器,CPSM 等待某一個卡發出的中斷請求。如果命令寄存器中設置掛起位,CPSM 進入掛起(Pend)狀態并等待數據通道子單元發出的 CmdPend 信號,在檢測到 CmdPend 信號時,CPSM 進入發送(Send)狀態,這將觸發數據計數器發送停止命令的功能。

注: CPSM 保持在空閑狀態至少 8 個 SDIO_CK 周期,以滿足 NCC 和 NRC 時序限制。NCC 是兩個主機命令間的最小間隔;NRC 是主機命令與卡響應之間的最小間隔。

wKgZO2g3_D6AfCtCAAE-KufEsRs784.png

SDIO命令傳輸

命令格式

命令:命令是用于開始一項操作。主機向一個指定的卡或所有的卡發出帶地址的命令或廣播命令(廣播命令只適合于 MMCV3.31 或之前的版本)。命令在 CMD 線上串行傳送。所有命令的長度固定為 48 位,下表給出了多媒體卡、SD 存儲卡和 SDIO 卡上一般的命令格式。CE-ATA 命令是 MMCV4.2 命令的擴充,所以具有相同的格式。命令通道操作于半雙工模式,這樣命令和響應可以分別發送和接收。如果 CPSM 不處在發送狀態,SDIO_CMD 輸出處于高阻狀態,如圖 所示。SDIO_CMD 上的數據與 SDIO_CK 的上升沿同步。

寬度 數值 說明
47 1 0 開始位
46 1 1 傳輸位
[45:40] 6 - 命令索引
[39:8] 32 - 參數
[7:1] 7 - CRC7
0 1 1 結束位

響應:響應是由一個被指定地址的卡發送到主機,對于 MMCV3.31 或以前版本所有的卡同時發送響應;響應是對先前接收到命令的一個應答。響應在 CMD 線上串行傳送。

SDIO 支持 2 種響應類型,2 種類型都有 CRC 錯誤檢測:

?48 位短響應

?136 位長響應

注: 如果響應不包含 CRC(如 CMD1 的響應),設備驅動應該忽略 CRC 失敗狀態

短響應格式

寬度 數值 說明
47 1 0 開始位
46 1 1 傳輸位
[45:40] 6 - 命令索引
[39:8] 32 - 參數
[7:1] 7 - CRC7 (或 1111111)
0 1 1 結束位

長響應格式

寬度 數值 說明
135 1 0 開始位
134 1 0 傳輸位
[133:128] 6 111111 保留
[127:1] 127 - CID 或 CSD (包含內部 CRC7)
0 1 1 結束位

命令寄存器包含命令索引(發至卡的 6 位)和命令類型;命令本身決定了是否需要響應和響應的類型、48 位還是 136 位(見 20.9.4 節)。命令通道中的狀態標志示于下表:

命令通道狀態標志

標志 說明
CMDRCEND 響應的 CRC 正確
CCRCFAIL 響應的 CRC 錯誤
CMDSENT 命令 (不需要響應的命令) 已經送出
CTIMEOUT 響應超時
CMDACT 正在發送命令

CRC發生器計算 CRC碼之前所有位的 CRC校驗和,包括開始位、發送位、命令索引和命令參數(或卡狀態)。對于長響應格式,CRC 校驗和計算的是 CID 或 CSD 的前 120 位;注意,長響應格式中的開始位、傳輸位和 6 個保留位不參與 CRC 計算。

CRC 校驗和是一個 7 位的數值:

CRC[6:0]=余數[(M(x)*x7)/G(x)]

G(x)=x7+x3+1

M(x)=(開始位)*x39+…+(CRC 前的最后一位)*x0,或

M(x)=(開始位)*x119+…+(CRC 前的最后一位)*x0,或

數據通道

數據通道子單元在主機與卡之間傳輸數據。下圖是數據通道的框圖。

wKgZPGg3_D6Ac9aaAAFxMp8UsG4390.png

數據通道

在時鐘控制寄存器中可以配置卡的數據總線寬度。如果選擇了 4 位總線模式,則每個時鐘周期四條數據信號線(SDIO_D[3:0])上將傳輸 4 位數據;如果選擇了 8 位總線模式,則每個時鐘周期八條數據信號線(SDIO_D[7:0])上將傳輸 8 位數據;如果沒有選擇寬總線模式,則每個時鐘周期只在SDIO_D0 上傳輸 1 位數據。根據傳輸的方向(發送或接收),使能時數據通道狀態機(DPSM)將進入 Wait_S 或 Wait_R 狀態:

?發送:DPSM 進入 Wait_S 狀態。如果發送 FIFO 中有數據,則 DPSM 進入發送狀態,同時數據通道子單元開始向卡發送數據。

?接收:DPSM 進入 Wait_R 狀態并等待開始位;當收到開始位時,DPSM 進入接收狀態,同時數據通子單元開始從卡接收數據。

數據通道狀態機(DPSM)

DPSM 工作在 SDIO_CK 頻率,卡總線信號與 SDIO_CK 的上升沿同步。DPSM 有 6 個狀態,如下圖所示:

wKgZO2g3_D-AHzerAAT0RllLg5g709.png

數據通道狀態機(DPSM)

?空閑(Idle):數據通道不工作,SDIO_D[7:0]輸出處于高阻狀態。當寫入數據控制寄存器并設置使能位時,DPSM 為數據計數器加載新的數值,并依據數據方向位進入 Wait_S 或 Wait_R狀態。

?Wait_R:如果數據計數器等于 0,當接收 FIFO 為空時 DPSM 進入到空閑(Idle)狀態。如果數據計數器不等于 0,DPSM 等待 SDIO_D上的開始位。如果 DPSM 在超時之前接收到一個開始位,它會進入接收(Receive)狀態并加載數據塊計數器。如果 DPSM 在檢測到一個開始位前出現超時,或發生開始位錯誤,DPSM 將進入空閑狀態并設置超時狀態標志。

?接收(Receive):接收到的串行數據被組合為字節并寫入數據 FIFO。根據數據控制寄存器中傳輸模式位的設置,數據傳輸模式可以是塊傳輸或流傳輸:

······在塊模式下,當數據塊計數器達到 0 時,DPSM 等待接收 CRC 碼,如果接收到的代碼與內部產生的 CRC 碼匹配,則 DPSM 進入 Wait_R 狀態,否則設置 CRC 失敗狀態標志同時 DPSM進入到空閑狀態。

······在流模式下,當數據計數器不為 0 時,DPSM 接收數據;當計數器為 0 時,將移位寄存器中的剩余數據寫入數據 FIFO,同時 DPSM 進入 Wait_R 狀態。如果產生了 FIFO 上溢錯誤,DPSM 設置 FIFO 的錯誤標志并進入空閑狀態。

?Wait_S:如果數據計數器為 0,DPSM 進入空閑狀態;否則 DPSM 等待數據 FIFO 空標志消失后,進入發送狀態。

注: DPSM 會在 Wait_S 狀態保持至少 2 個時鐘周期,以滿足 NWR 的時序要求,NWR 是接收到卡的響應至主機開始數據傳輸的間隔。

?發送(Send):DPSM 開始發送數據到卡設備。根據數據控制寄存器中傳輸模式位的設置,數據傳輸模式可以是塊傳輸或流傳輸:

······在塊模式下,當數據塊計數器達到 0 時,DPSM 發送內部產生的 CRC 碼,然后是結束位,并進入繁忙狀態。

······在流模式下,當使能位為高同時數據計數器不為 0 時,DPSM 向卡設備發送數據,然后進入空閑狀態。如果產生了 FIFO 下溢錯誤,DPSM 設置 FIFO 的錯誤標志并進入空閑狀態。

?繁忙(Busy):DPSM 等待 CRC 狀態標志:

······如果沒有接收到正確的 CRC 狀態,則 DPSM 進入空閑狀態并設置 CRC 失敗狀態標志。

······如果接收到正確的 CRC 狀態,則當 SDIO_D0 不為低時(卡不繁忙)DPSM 進入 Wait_S 狀態。

當 DPSM 處于繁忙狀態時發生了超時,DPSM 則設置數據超時標志并進入空閑狀態。

當 DPSM 處于 Wait_R 或繁忙狀態時,數據定時器被使能,并能夠產生數據超時錯誤:

······發送數據時,如果 DPSM 處于繁忙狀態超過程序設置的超時間隔,則產生超時。

······接收數據時,如果未收完所有數據,并且 DPSM 處于 Wait_R 狀態超過程序設置的超時間隔,則產生超時。

?數據:數據可以從主機傳送到卡,也可以反向傳輸。數據在數據線上傳輸。數據存儲在一個32 字的 FIFO 中,每個字為 32 位寬。

數據令牌格式

說明 開始位 數據 CRC16 結束位
塊數據 0 - 1
流數據 0 - 1

數據 FIFO

數據 FIFO(先進先出)子單元是一個具有發送和接收單元的數據緩沖區。FIFO 包含一個每字 32 位寬、共 32 個字的數據緩沖區,和發送與接收電路。因為數據 FIFO 工作在AHB 時鐘區域(HCLK/2),所有與 SDIO 時鐘區域(SDIOCLK)連接的信號都進行了重新同步。依據 TXACT 和 RXACT 標志,可以關閉 FIFO、使能發送或使能接收。TXACT 和 RXACT 由數據通道子單元設置而且是互斥的:

······當 TXACT 有效時,發送 FIFO 代表發送電路和數據緩沖區

······當 RXACT 有效時,接收 FIFO 代表接收電路和數據緩沖區

?發送 FIFO:當使能了 SDIO 的發送功能,數據可以通過 AHB 接口寫入發送 FIFO。

發送 FIFO 有 32 個連續的地址。發送 FIFO 中有一個數據輸出寄存器,包含讀指針指向的數據字。當數據通道子單元裝填了移位寄存器后,它移動讀指針至下個數據并傳輸出數據。如果未使能發送 FIFO,所有的狀態標志均處于無效狀態。當發送數據時,數據通道子單元設置TXACT 為有效。

發送 FIFO 狀態標志

標志 說明
TXFIFOF 當所有 32 個發送 FIFO 字都有有效的數據時,該標志為高。
TXFIFOE 當所有 32 個發送 FIFO 字都沒有有效的數據時,該標志為高。
TXFIFOHE 當 8 個或更多發送 FIFO 字為空時,該標志為高。該標志可以作為 DMA 請求。
TXDAVL 當發送 FIFO 包含有效數據時,該標志為高。該標志的意思剛好與 TXFIFOE 相反。
TXUNDERR 當發生下溢錯誤時,該標志為高。寫入 SDIO 清除寄存器時清除該標志。

?接收 FIFO:當數據通道子單元接收到一個數據字,它會把數據寫入 FIFO,寫操作結束后,寫指針自動加一;在另一端,有一個讀指針始終指向FIFO中的當前數據。如果關閉了接收FIFO,所有的狀態標志會被清除,讀寫指針也被復位。在接收到數據時數據通道子單元設置 RXACT。下表列出了接收 FIFO 的狀態標志。通過 32 個連續的地址可以訪問接收 FIFO。

接收 FIFO 狀態標志

標志 說明
RXFIFOF 當所有 32 個接收 FIFO 字都有有效的數據時,該標志為高。
RXFIFOE 當所有 32 個接收 FIFO 字都沒有有效的數據時,該標志為高。
RXFIFOHF 當 8 個或更多接收 FIFO 字有有效的數據時,該標志為高。該標志可以作為 DMA 請求。
RXDAVL 當接收 FIFO 包含有效數據時,該標志為高。該標志的意思剛好與 RXFIFOE 相反。
RXOVERR 當發生上溢錯誤時,該標志為高。寫入 SDIO 清除寄存器時清除該標志。

3.2 SDIOAHB 接口

AHB 接口產生中斷和 DMA 請求,并訪問 SDIO 接口寄存器和數據 FIFO。它包含一個數據通道、寄存器譯碼器和中斷/DMA 控制邏輯。

SDIO 中斷

當至少有一個選中的狀態標志為高時,中斷控制邏輯產生中斷請求。有一個屏蔽寄存器用于選擇可以產生中斷的條件,如果設置了相應的屏蔽標志,則對應的狀態標志可以產生中斷。

SDIO/DMA 接口:在 SDIO 和存儲器之間數據傳輸的過程

在下面的例子中,主機控制器使用 CMD24(WRITE_BLOCK)從主機傳送 512 字節到 MMC 卡,DMA 控制器用于從存儲器向 SDIO 的 FIFO 填充數據。

執行卡識別過程。

提高 SDIO_CK 頻率。

發送 CMD7 命令選擇卡。

按下述步驟配置 DMA2:

使能 DMA2 控制器并清除所有的中斷標志位。

設置 DMA2 通道 4 的源地址寄存器為存儲器緩沖區的基地址,DMA2 通道 4 的目標地址寄存器為SDIO_FIFO 寄存器的地址。

設置 DMA2 通道 4 控制寄存器(存儲器遞增,非外設遞增,外設和源的數據寬度為字寬度)。

使能 DMA2 通道 4。

發送 CMD24(WRITE_BLOCK),操作如下:

設置 SDIO 數據長度寄存器(SDIO 數據時鐘寄存器應該在執行卡識別過程之前設置好)。

設置 SDIO 參數寄存器為卡中需要傳送數據的地址。

設置 SDIO 命令寄存器:CmdIndex 置為 24(WRITE_BLOCK);WaitRest 置為 1(SDIO 卡主機等待響應);CPSMEN 置為 1(使能 SDIO 卡主機發送命令),保持其它域為他們的復位值。

等待 SDIO_STA[6]=CMDREND 中斷,然后設置 SDIO 數據寄存器:DTEN 置為 1(使能 SDIO卡主機發送數據);DTDIR 置為 0(控制器至卡方向);DTMODE 置為 0(塊數據傳送);DMAEN 置為 1(使能 DMA);DBLOCKSIZE 置為 9(512 字節);其它域不用設置。

等待 SDIO_STA[10]=DBCKEND。

查詢 DMA 通道的使能狀態寄存器,確認沒有通道仍處于使能狀態。

4 卡功能描述

4.1 卡識別模式

在卡識別模式,主機復位所有的卡、檢測操作電壓范圍、識別卡并為總線上每個卡設置相對地址(RCA)。在卡識別模式下,所有數據通信只使用命令信號線(CMD)。

4.2 卡復位

GO_IDLE_STATE 命令(CMD0)是一個軟件復位命令,它把多媒體卡和 SD 存儲器置于空閑狀態。

IO_RW_DIRECT 命令(CMD52)復位 SDI/O 卡。上電后或執行 CMD0 后,所有卡的輸出端都處于高阻狀態,同時所有卡都被初始化至一個默認的相對卡地址(RCA=0x0001)和默認的驅動器寄存器設置(最低的速度,最大的電流驅動能力)。

4.3 操作電壓范圍確認

所有的卡都可以使用任何規定范圍內的電壓與 SDIO卡主機通信,可支持的最小和最大電壓 VDD數值由卡上的操作條件寄存器(OCR)定義。內部存儲器存儲了卡識別號(CID)和卡特定數據(CSD)的卡 ,僅能在數據傳輸 VDD 條件下傳送這些信息。

當 SDIO 卡主機模塊與卡的 VDD 范圍不一致時,卡將不能完成識別周期,也不能發送 CSD數據;因此,在 VDD 范圍不匹配時,SDIO 卡主機可以用下面幾個特殊命令去識別和拒絕卡:SEND_OP_COND(CMD1)、SD_APP_OP_COND(SD 存儲卡的 ACMD41)和 IO_SEND_OP_COND(SDI/O卡的 CMD5)。

SDIO 卡主機在執行這幾個命令時會產生需要的 VDD 電壓。不能在指定的電壓范圍進行數據傳輸的卡,將從總線斷開并進入非激活狀態。使用這些不包含電壓范圍作為操作數的命令,SDIO 卡主機能夠查詢每個卡并在確定公共的電壓范圍前,把不在此范圍內的卡置于非激活狀態。當 SDIO 卡主機能夠選擇公共的電壓范圍或用戶需要知道卡是否能用時,SDIO 卡主機可以進行這樣的查詢。

4.4 卡識別過程

多媒體卡和 SD 卡的卡識別過程是有區別的;對于多媒體卡,卡識別過程以時鐘頻率 Fod 開始,所有 SDIO_CMD 輸出為開路驅動,允許在這個過程中的卡的并行連接,識別過程如下:

1. 總線被激活。

2. SDIO 卡主機廣播發送 SEND_OP_COND(CMD1)命令,并接收操作條件。

3. 得到的響應是所有卡的操作條件寄存器內容的“線與”。

4. 不兼容的卡會被置于非激活狀態。

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

6. 所有激活的卡同時串行地發送他們的 CID 號,那些檢測到輸出的 CID 位與命令線上的數據不相符的卡必須停止發送,并等待下一個識別周期。最終只有一個卡能夠成功地傳送完整的CID 至 SDIO 卡主機并進入識別狀態。

7. SDIO 卡主機發送 SET_RELATIVE_ADDR(CMD3)命令至這個卡,這個新的地址被稱為相對卡地址(RCA),它比 CID 短,用于對卡尋址。至此,這個卡轉入待機狀態,并不再響應新的識別過程,同時它的輸出驅動從開路轉變為推挽模式。

SDIO 卡主機重復上述步驟 5 至 7,直到收到超時條件。對于 SD 卡而言,卡識別過程以時鐘頻率 Fod 開始,所有 SDIO_CMD 輸出為推挽驅動而不是開路驅動,識別過程如下:

1. 總線被激活

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

3. 得到的響應是所有卡的操作條件寄存器的內容

4. 不兼容的卡會被置于非激活狀態

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

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

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

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

對于 SDI/O 卡而言,卡識別過程如下:

1. 總線被激活

2. SDIO 卡主機發送 IO_SEND_OP_COND(CMD5)命令

3. 得到的響應是卡的操作條件寄存器的內容

4. 不兼容的卡會被置于非激活狀態

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

4.5 寫數據塊

執行寫數據塊命令(CMD24-27)時,主機把一個或多個數據塊從主機傳送到卡中,同時在每個數據塊的末尾傳送一個 CRC 碼。一個支持寫數據塊命令的卡應該始終能夠接收由 WRITE_BL_LEN 定義的數據塊。如果CRC校驗錯誤,卡通過SDIO_D信號線指示錯誤,傳送的數據被丟棄而不被寫入,所有后續(在多塊寫模式下)傳送的數據塊將被忽略。

如果主機傳送部分數據,而累計的數據長度未與數據塊對齊,當不允許塊錯位(未設置 CSD 的參數WRITE_BLK_MISALIGN),卡將在第一個錯位的塊之前檢測到塊錯位錯誤(設置狀態寄存器中的ADDRESS_ERROR 錯誤位)。當主機試圖寫一個寫保護區域時,寫操作也會被中止,此時卡會設置WP_VIOLATION 位。設置 CID 和 CSD 寄存器不需要事先設置塊長度,傳送的數據也是通過 CRC 保護的。如果 CSD 或CID 寄存器的部分是存儲在 ROM 中,則這個不能更改的部分必須與接收緩沖區的對應部分相一致,如果有不一致之處,卡將報告一個錯誤同時不修改任何寄存器的內容。有些卡需要長的甚至不可預計的時間完成寫一個數據塊,在接收一個數據塊并完成 CRC 檢驗后,卡開始寫操作,如果它的寫緩沖區已經滿并且不能再從新的 WRITE_BLOCK 命令接受新的數據時,它會把 SDIO_D 信號線拉低。

主機可以在任何時候使用 SEND_STATUS(CMD13)查詢卡的狀態,卡將返回當前狀態。READY_FOR_DATA 狀態位指示卡是否可以接受新的數據或寫操作是否還在進行。主機可以使用CMD7(選擇另一個卡)不選中某個卡,而把這個卡置于斷開狀態,這樣可以釋放 SDIO_D 信號線而不中斷未完成的寫操作;當重新選擇了一個卡,如果寫操作仍然在進行并且寫緩沖區仍不能使用,它會重新通過拉低 SDIO_D 信號線指示忙的狀態。

4.6 讀數據塊

在讀數據塊模式下,數據傳輸的基本單元是數據塊,它的大小在 CSD 中(READ_BL_LEN)定義。如果設置了 READ_BL_PARTIAL,同樣可以傳送較小的數據塊,較小數據塊是指開始和結束地址完全包含在一個物理塊中,READ_BL_LEN 定義了物理塊的大小。為保證數據傳輸的正確,每個數據塊后都有一個 CRC 校驗碼。CMD17(READ_SINGLE_BLOCK)啟動一次讀數據塊操作,在傳輸結束后卡返回到發送狀態。

CMD18(READ_MULTIPLE_BLOCK)啟動一次連續多個數據塊的讀操作。主機可以在多數據塊讀操作的任何時候中止操作,而不管操作的類型。發送停止傳輸命令即可中止操作。如果在多數據塊讀操作中(任一種類型)卡檢測到錯誤(例如:越界、地址錯位或內部錯誤),它將停止數據傳輸并仍處于數據狀態;此時主機必須發送停止傳輸命令中止操作。在停止傳輸命令的響應中報告讀錯誤。如果主機發送停止傳輸命令時,卡已經傳輸完一個確定數目的多個數據塊操作中的最后一個數據塊,因為此時卡已經不在數據狀態,主機會得到一個非法命令的響應。如果主機傳輸部分數據塊,而累計的數據長度不能與物理塊對齊同時不允許塊錯位,卡會在出現第一個未對齊的塊時檢測出一個塊對齊錯誤,并在狀態寄存器中設置 ADDRESS_ERROR 錯誤標志。

4.7 數據流操作,數據流寫入和數據流讀出(只適用于多媒體卡)

在數據流模式,數據按字節傳輸,同時每個數據塊后沒有 CRC。數據流寫(只適用于多媒體卡)WRITE_DAT_UNTIL_STOP(CMD20)開始從 SDIO 卡主機至卡的數據傳輸,從指定的地址開始連續傳輸直到 SDIO 卡主機發出一個停止命令。如果允許部分數據塊傳輸(設置了 CSD 參 數WRITE_BL_PARTIAL),則數據流可以在卡的地址空間中的任意地址開始和停止,否則數據流只能在數據塊的邊界開始和停止。因為傳輸的數據數目沒有事先設定,不能使用 CRC 校驗。

如果發送數據時達到了存儲器的最大地址,即使 SDIO 卡主機沒有發送停止命令,隨后傳輸的數據也會被丟棄。

數據流寫操作的最大時鐘頻率可以通過下式計算:

wKgZO2g3_D2AGtc6AABK2oWz9MM479.png

?Maximumspeed=最大寫頻率

?TRANSPEED=最大數據傳輸率

?writebllen=最大寫數據塊長度

?NSAC=以 CLK 周期計算的數據讀操作時間 2

?TAAC=數據讀操作時間 1

?R2WFACTOR=寫速度因子

如果主機試圖使用更高的頻率,卡可能不能處理數據并停止編程,同時在狀態寄存器中設置OVERRUN 錯誤位,丟棄所有隨后傳輸的數據并(在接收數據狀態)等待停止命令。如果主機試圖寫入一個寫保護區域,寫操作將被中止,同時卡將設置 WP_VIOLATION 位。數據流讀(只適用于多媒體卡)READ_DAT_UNTIL_STOP(CMD11)控制數據流數據傳輸。這個命令要求卡從指定的地址讀出數據,直到 SDIO 卡主機發送 STOP_TRANSMISSION(CMD12)。

因為串行命令傳輸的延遲,停止命令的執行會有延遲,數據傳送會在停止命令的結束位后停止。如果發送數據時達到了存儲器的最大地址,SDIO 卡主機沒有發送命令,隨后傳輸的數據將是無效數據。

數據流讀操作的最大時鐘頻率可以通過下式計算:

wKgZO2g3_D2AW-q9AABBUtFFFNA358.png

?Maximumspeed=最大寫頻率

?TRANSPEED=最大數據傳輸率

?readbllen=最大讀數據塊長度

?NSAC=以 CLK 周期計算的數據讀操作時間 2

?TAAC=數據讀操作時間 1

?R2WFACTOR=寫速度因子

如果主機試圖使用更高的頻率,卡將不能處理數據傳輸,此時卡在狀態寄存器中設置 UNDERRUN錯誤位,中止數據傳輸并在數據狀態等待停止命令。

4.8 擦除:成組擦除和扇區擦除

多媒體卡的擦除單位是擦除組,擦除組是以寫數據塊計算,寫數據塊是卡的基本寫入單位。擦除組的大小是卡的特定參數,在 CSD 中定義。

主機可以擦除一個連續范圍的擦除組,開始擦除操作有三個步驟。

首先,主機使用 ERASE_GROUP_START(CMD35)命令定義連續范圍的開始地址,然后使用ERASE_GROUP_END(CMD36)命令定義連續范圍的結束地址,最后發送擦除命令 ERASE(CMD38)開始擦除操作。擦除命令的地址域是以字節為單位的擦除組地址。卡會舍棄未與擦除組大小對齊的部分,把地址邊界對齊到擦除組的邊界。如果未按照上述步驟收到了擦除命令,卡在狀態寄存器中設置 ERASE_SEQ_ERROR 位,并重新等待第一個步驟。如果收到了除 SEND_STATUS 和擦除命令之外的其它命令,卡在狀態寄存器中設置 ERASE_RESET位,解除擦除序列并執行新的命令。如果擦除范圍包含了寫保護數據塊,這些塊不被擦除,只有未保護的塊被擦除,同時卡在狀態寄存器中設置 WP_ERASE_SKIP 狀態位。在擦除過程中,卡拉低 SDIO_D 信號。實際的擦除時間可能很長,主機可以使用 CMD7 解除卡的選擇。

4.9 寬總線選擇和解除選擇

可以通過 SET_BUS_WIDTH(ACMD6)命令選擇或不選擇寬總線(4 位總線寬度)操作模式,上電后或GO_IDLE_STATE(CMD0)命令后默認的總線寬度為 1 位。SET_BUS_WIDTH(ACMD6)命令僅在傳輸狀態時有效,即只有在使用 SELECT/DESELECT_CARD(CMD7)命令選擇了卡后才能改變總線寬度。

4.10 保護管理

SDIO 卡主機模塊支持三種保護方式:

1. 內部卡保護(卡內管理)

2. 機械寫保護開關(僅由 SDIO 卡主機模塊管理)

3. 密碼管理的卡鎖操作

內部卡的寫保護

卡的數據可以被保護不被覆蓋或擦除。在 CSD 中永久地或臨時地設置寫保護位,生產廠商或內容提供商可以永久地對整個卡施行寫保護。對于支持在 CSD 中設置 WP_GRP_ENABLE 位從而提供一組扇區寫保護的卡,部分數據可以被保護,寫保護可以通過程序改變。寫保護的基本單位是 CSD參數 WP_GRP_SIZE 個扇區。

SET_WRITE_PROT 和 CLR_WRITE_PROT 命令控制指定組的保護,SEND_WRITE_PROT 命令與單數據塊讀命令類似,卡送出一個包含 32 個寫保護位(代表從指定地址開始的 32 個寫保護組)的數據塊,跟著一個 16 位的 CRC 碼。寫保護命令的地址域是一個以字節為單位的組地址。卡將截斷所有組大小以下的地址。

機械寫保護開關

在卡的側面有一個機械的滑動開關,允許用戶設置或清除卡的寫保護。當滑動開關置于小窗口打開的位置時,卡處于寫保護狀態,當滑動開關置于小窗口關閉的位置時,可以更改卡中內容。在卡的插槽上的對應部位也有一個開關指示 SDIO 卡主機模塊,卡是否處于寫保護狀態。卡的內部電路不知道寫保護開關的位置。

密碼保護

密碼保護功能允許 SDIO 卡主機模塊使用密碼對卡實行上鎖或解鎖。密碼存儲在 128 位的 PWD 寄存器中,它的長度設置在 8 位的 PWD_LEN 寄存器中。這些寄存器是不可揮發的,即掉電后它們的內容不丟失。已上鎖的卡能夠響應和執行相應的命令,即允許 SDIO 卡主機模塊執行復位、初始化和查詢狀態等操作,但不允許操作卡中的數據。當設置了密碼后(即 PWD_LEN 的數值不為 0),上電后卡自動處于上鎖狀態。

正如 CSD 和 CID 寄存器寫命令,上鎖/解鎖命令僅在傳輸狀態下有效,在這個狀態下,命令中沒有地址參數,但卡已經被選中。卡的上鎖/解鎖命令具有單數據塊寫命令的結構和總線操作類型,傳輸的數據塊包含所有命令所需要的信息(密碼設置模式、PWD內容和上鎖/解鎖指示)。在發送卡的上鎖/解鎖命令之前,命令數據塊的長度由 SDIO 卡主機模塊定義,命令結構示于表 110。

位的設置如下:

?ERASE:設置該位將執行強制擦除,所有其它位必須為 0,只發送命令字節。

?LOCK_UNLOCK:設置該位鎖住卡,LOCK_UNLOCK 與 SET_PWD 可以同時設置,但不能與CLR_PWD 同時設置。

?CLR_PWD:設置該位清除密碼數據。

?SET_PWD:設置該位將密碼數據保存至存儲器。

?PWD_LEN:以字節為單位定義密碼的長度。

?PWD:密碼(依不同的命令,新的密碼或正在使用的密碼)

以下幾節列出了設置/清除密碼、上鎖/解鎖和強制擦除的命令序列。

設置密碼

1. 選擇一個卡(SELECT/DESELECT_CARD,CMD7)。

2. 定義要在 8 位的卡上鎖/解鎖模式下發送的數據塊長度(SET_BLOCKLEN,CMD16),8 位的PWD_LEN,新密碼的字節數目。當更換了密碼后,發送命令的數據塊長度必須同時考慮新舊密碼的長度。

3. 以合適的數據塊長度在數據線上發送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數據塊包含了操作模式(SET_PWD=1)、長度(PWD_LEN)和密碼(PWD)。當更換了密碼后,長度數值(PWD_LEN)包含了新舊兩個密碼的長度,PWD 域包含了舊的密碼(正在使用的)和新的密碼。

4. 當舊的密碼匹配后,新的密碼和它的長度被分別存儲在 PWD 和 PWD_LEN 域。如果送出的舊密碼與期望的密碼(長度或內容)不吻合,則設置狀態寄存器中的 LOCK_UNLOCK_FAILED 錯誤位,同時密碼不變。密碼長度域(PWD_LEN)指示當前是否設置了密碼,如果該域為非零,則表示使用了密碼,卡在上電時自動上鎖。在不斷電的情況下,如果設置了密碼,可以通過設置 LOCK_UNLOCK 位或發送一個額外的上鎖命令,立即鎖住卡。

清除密碼

1. 選擇一個卡(SELECT/DESELECT_CARD,CMD7)。

2. 定義要在 8 位的卡上鎖/解鎖模式下發送的數據塊長度(SET_BLOCKLEN,CMD16),8 位的PWD_LEN,當前使用密碼的字節數目。

3. 當密碼匹配后,PWD 域被清除同時 PWD_LEN 被設為 0。如果送出的密碼與期望的密碼(長度或內容)不吻合,則設置狀態寄存器中的 LOCK_UNLOCK_FAILED 錯誤位,同時密碼不變。

卡上鎖

1. 選擇一個卡(SELECT/DESELECT_CARD,CMD7)

2. 定義要在 8 位的卡上鎖/解鎖模式(見表 110 的字節 0)下發送的數據塊長度(SET_BLOCKLEN,CMD16),8 位的 PWD_LEN,和當前密碼的字節數目。

3. 以合適的數據塊長度在數據線上發送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數據塊包含了操作模式(LOCK_UNLOCK=1)、長度(PWD_LEN)和密碼(PWD)。

4. 當密碼匹配后,卡被上鎖并則設置狀態寄存器中的 CARD_IS_LOCKED 狀態位。如果送出的密碼與期望的密碼(長度或內容)不吻合,則設置狀態寄存器中的 LOCK_UNLOCK_FAILED 錯誤位,同時上鎖操作失敗。設置密碼和為卡上鎖可以在同一個操作序列中進行,此時 SDIO 卡主機模塊按照前述的步驟設置密碼,但在發送新密碼命令的第 3 步需要設置 LOCK_UNLOCK 位。如果曾經設置過密碼(PWD_LEN 不為 0),卡會在上電復位時自動地上鎖。對已經上鎖的卡執行上鎖操作或對沒有密碼的卡執行上鎖操作會導致失敗,并設置狀態寄存器中的LOCK_UNLOCK_FAILED 錯誤位。

卡解鎖

1. 選擇一個卡(SELECT/DESELECT_CARD,CMD7)

2. 定義要在 8 位的卡上鎖/解鎖模式下發送的數據塊長度(SET_BLOCKLEN,CMD16),8 位的 PWD_LEN,和當前密碼的字節數目。

3. 以合適的數據塊長度在數據線上發送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數據塊包含了操作模式(LOCK_UNLOCK=0)、長度(PWD_LEN)和密碼(PWD)。

4. 當密碼匹配后,卡鎖被解除,同時狀態寄存器中的 CARD_IS_LOCKED 位被清除。如果送出的密碼與期望的密碼(長度或內容)不吻合,則設置狀態寄存器中的 LOCK_UNLOCK_FAILED 錯誤位,同時卡仍保持上鎖狀態。解鎖狀態只在當前的供電過程中有效,只要不清除 PWD 域,下次上電后卡會被自動上鎖。試圖對

已經解了鎖的卡執行解鎖操作會導致操作失敗,并設置狀態寄存器中的 LOCK_UNLOCK_FAILED 錯誤位。

強制擦除

如果用戶忘記了密碼(PWD 的內容),可以在清除卡中的所有內容后使用卡。強制擦除操作擦除所

有卡中的數據和密碼。

1. 選擇一個卡(SELECT/DESELECT_CARD,CMD7)

2. 設置發送的數據塊長度(SET_BLOCKLEN,CMD16)為 1,僅發送 8 位的卡上鎖/解鎖字節。

3. 以合適的數據塊長度在數據線上發送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數據塊包含了操作模式(ERASE=1)所有其它位為 0。

當 ERASE 位是數據域中僅有的位時,卡中的所有內容將被擦除,包括 PWD 和 PWD_LEN 域,同時卡不再被上鎖。如果有任何其它位不為 0,則設置狀態寄存器中的LOCK_UNLOCK_FAILED 錯誤位,卡中的數據保持不變,同時卡仍保持上鎖狀態。試圖對已經解了鎖的卡執行擦除操作會導致操作失敗,并設置狀態寄存器中的LOCK_UNLOCK_FAILED 錯誤位。

5 例程設計

5.1 SDIO_SDCardFatfs

該程序通過清晰的模塊化設計,實現了對 SD 卡 FATFS 文件系統的全面測試,適用于嵌入式系統存儲功能驗證和教學演示。

程序功能概述

1.硬件初始化

?系統時鐘、延時函數、串口(UART1)初始化。

?SD卡通過SDIO接口初始化,支持FATFS文件系統。

2.用戶交互


    while (1)
    {
        cmd = GetCmd();
        switch (cmd)
        {
        case '1': {
            printf("1.--->>>FatfsTestrn");
            FatfsTest();
            TestList();
            break;
        }
        case '2': {
            printf("2.--->>>FatfsBigDataTestrn");
            FatfsBigDataTest();
            TestList();
            break;
        }
        case '3': {
            printf("3.--->>>ViewRootDirrn");
            ViewRootDir();
            TestList();
            break;
        }
        case '4': {
            printf("4.--->>>CreateDirrn");
            CreateDir();
            TestList();
            break;
        }
        case '5': {
            printf("5.--->>>DeleteDirFilern");
            DeleteDirFile();
            TestList();
            break;
        }
        }
    }
}

void TestList(void)
{
    printf("/***************************SD Card Test*******************************/n");
    printf("==========================List==========================n");
    printf("1: Create a new file (FatFs read-write test file.txt) for read-write testingn");
    printf("2: Read and write large amounts of data (FatFs read and write test file .txt), perform read and write testsn");
    printf("3: Show the file test in the root directory of the SD Cardn");
    printf("4: Create directory(/Dir1,/Dir1/Die1_1,/Dir2)n");
    printf("5: Delete files and directories (/Dir1,/Dir1/Dir1_1,/Dir2, FatFs read and write test files.txt)n");
    printf("****************************************************************************/n");
}

void SDInfoShow(void)
{
    printf("/***************************SD Info Show*******************************/n");
    printf("SDCardInfo.CardType : %dn", SDCardInfo.CardType);
    printf("SDCardInfo.CardCapacity : %lld Byten", (SDCardInfo.CardCapacity));
    printf("SDCardInfo.CardBlockSize : %d Byten", SDCardInfo.CardBlockSize);
}

uint8_t GetCmd(void)
{
    uint8_t tmp = 0;

    if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
    {
        tmp = USART_ReceiveData(USART1);
    }
    return tmp;
}

?通過串口接收用戶命令(1-5),執行對應操作:

?基礎文件操作測試(創建文件、讀寫數據)。

?大數據讀寫性能測試(2MB文件)。

?顯示SD卡根目錄內容。

?創建多級目錄(/Dir1, /Dir1/Dir1_1, /Dir2)。

?刪除目錄及測試文件。

3.關鍵函數

void FatfsTest(void)
{
    res_sd = f_mount(&fs, "0:", 1);

    /***************************Format test**************************/
    printf("n format testn");
    if (res_sd == FR_NO_FILESYSTEM)
    {
        printf("The SD card has no file system and is about to be formattedrn");

        res_sd = f_mkfs("0:", 0, 0);

        if (res_sd == FR_OK)
        {
            printf("The SD card successfully mounted the file systemrn");
            res_sd = f_mount(NULL, "0:", 1);
            res_sd = f_mount(&fs, "0:", 1);
        }
        else
        {
            printf("SD card formatting failedrn");
            while (1);
        }
    }
    else if (res_sd != FR_OK)
    {
        printf("SD card mount failed (%d), maybe SD card initialization failedrn", res_sd);
        while (1);
    }
    else
    {
        printf("The file system is mounted and can be read and written for testingrn");
    }

    SDInfoShow();
    /***************************File system testing --->>> Write test*********************/
    printf("n file system test --->>> Write testn");
    res_sd = f_open(&fnew, "0:FatFs read and write test files.txt", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
    if (res_sd == FR_OK)
    {
        printf("Open/create FatFs to read and write the test file.txt successfully, and write data to the filern");

        res_sd = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);

        if (res_sd == FR_OK)
        {
            printf("The file was written successfully, the number of bytes written:% d The data written is: n%srn", fnum, WriteBuffer);
        }
        else
        {
            printf("File write failed (%d)n", res_sd);
        }
        f_close(&fnew);
    }
    else
    {
        printf("Failed to open/create, filern");
    }

    /*************************File system testing --->>> read test**************************/
    printf("n file system test --->>> read testn");
    res_sd = f_open(&fnew, "0:FatFs read and write test files.txt", FA_OPEN_ALWAYS | FA_READ);
    if (res_sd == FR_OK)
    {
        printf("File successfully openedrn");
        res_sd = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
        if (res_sd == FR_OK)
        {
            printf("File read successful. Bytes read:% d The data read was: n%srn", fnum, ReadBuffer);
        }
        else
        {
            printf("File read failed (%d)n", res_sd);
        }
    }
    else
    {
        printf("File opening failedn");
    }

    f_close(&fnew);

    f_mount(NULL, "0:", 1);
}

FatfsTest():掛載文件系統,格式化(若需要),測試文件讀寫。

void FatfsBigDataTest(void)
{
    uint32_t i;

    res_sd = f_mount(&fs, "0:", 1);

    /***************************File system testing --->>> Big data write test*********************/
    printf("nFile system test --->>> write testn");
    res_sd = f_open(&fnew, "0:FatFs read and write test files.txt", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
    if (res_sd == FR_OK)
    {
        printf("Open/create FatFs to read and write the test file.txt successfully, and write data to the filern");

        for (i = 0; i < 0xFFFFF; i++)
        {
            res_sd = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
            if ((i % 0x8FFF) == 0)
            {
                printf("......n");
            }
        }
        if (res_sd == FR_OK)
        {
            printf("File written successfullyn");
        }
        else
        {
            printf("File write failed (%d)n", res_sd);
        }
        f_close(&fnew);
    }
    else
    {
        printf("Failed to open/create, filern");
    }
}

FatfsBigDataTest():寫入大量數據測試性能。

void CreateDir(void)
{
    res_sd = f_mount(&fs, "0:", 1);
    if (res_sd != FR_OK)
    {
        printf("Failed to mount file system (%d)rn", res_sd);
    }

    res_sd = f_mkdir("/Dir1");
    if (res_sd == FR_OK)
    {
        printf("f_mkdir Dir1 OKrn");
    }
    else if (res_sd == FR_EXIST)
    {
        printf("Dir1 Target already exists(%d)rn", res_sd);
    }
    else
    {
        printf("f_mkdir Dir1 fail(%d)rn", res_sd);
        return;
    }

    res_sd = f_mkdir("/Dir2");
    if (res_sd == FR_OK)
    {
        printf("f_mkdir Dir2 OKrn");
    }
    else if (res_sd == FR_EXIST)
    {
        printf("Dir2 Target already exists(%d)rn", res_sd);
    }
    else
    {
        printf("f_mkdir Dir2 fail (%d)rn", res_sd);
        return;
    }

    res_sd = f_mkdir("/Dir1/Dir1_1");
    if (res_sd == FR_OK)
    {
        printf("f_mkdir Dir1_1 OKrn");
    }
    else if (res_sd == FR_EXIST)
    {
        printf("Dir1_1 Target already exists(%d)rn", res_sd);
    }
    else
    {
        printf("f_mkdir Dir1_1 fail (%d)rn", res_sd);
        return;
    }

    f_mount(NULL, "0:", 1);
}

CreateDir() 和 DeleteDirFile():目錄創建與刪除。

void ViewRootDir(void)
{
    DIR      dirinf;
    FILINFO  fileinf;
    uint32_t cnt = 0;
    char     name[256];

    res_sd = f_mount(&fs, "0:", 1);
    if (res_sd != FR_OK)
    {
        printf("Failed to mount file system (%d)rn", res_sd);
    }

    res_sd = f_opendir(&dirinf, "/");
    if (res_sd != FR_OK)
    {
        printf("Failed to open root directory (%d)rn", res_sd);
        return;
    }

    fileinf.lfname = name;
    fileinf.lfsize = 256;

    printf("attribute		|	file size	|	short filename	|	long file namern");
    for (cnt = 0;; cnt++)
    {
        res_sd = f_readdir(&dirinf, &fileinf);
        if (res_sd != FR_OK || fileinf.fname[0] == 0)
        {
            break;
        }

        if (fileinf.fname[0] == '.')
        {
            continue;
        }

        if (fileinf.fattrib & AM_DIR)
        {
            printf("(0x%02d)directory", fileinf.fattrib);
        }
        else
        {
            printf("(0x%02d)attribute", fileinf.fattrib);
        }

        printf("%10d	", fileinf.fsize);
        printf("	%s |", fileinf.fname);
        printf("	%srn", (char *)fileinf.lfname);
    }

    f_mount(NULL, "0:", 1);
}

ViewRootDir():顯示根目錄內容。

關鍵代碼分析:

1.文件系統初始化與掛載

res_sd = f_mount(&fs, "0:", 1);

?掛載SD卡(邏輯驅動號0:),失敗時嘗試格式化(f_mkfs)。

2.文件讀寫操作

?創建/打開文件:f_open使用FA_OPEN_ALWAYS模式,若文件不存在則創建。

?寫入數據:f_write將緩沖區數據寫入文件。

?讀取數據:f_read從文件讀取數據到緩沖區。

3.目錄操作

?創建目錄:f_mkdir創建目錄,處理已存在情況(FR_EXIST)。

?刪除目錄/文件:f_unlink刪除文件或空目錄(非空目錄需遞歸刪除)。

6 下載驗證

6.1 SDIO_SDCardFatfs

wKgZPGg3_D2ASj0eAACZ4_6kzQ4035.png

命令1:基礎文件測試(FatfsTest):

wKgZO2g3_D2AS1oeAACvQUEnGUQ729.png

命令2:大數據讀寫測試(FatfsBigDataTest):

wKgZPGg4AGKABaqvAABbg2AmASI051.jpg

命令3:查看根目錄(ViewRootDir):

wKgZO2g4AGKAElBiAAC1FqM_YSM236.jpg

命令4:創建目錄(CreateDir):

wKgZO2g3_D2AExTGAAC3xKmAvNo586.png

命令5:刪除目錄與文件(DeleteDirFile):

wKgZPGg3_D2ARXw9AACzS8Xnf7E636.png

WIZnet 是一家無晶圓廠半導體公司,成立于 1998 年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU? 面向各種應用中的嵌入式互聯網設備。

WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。

香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6076

    文章

    45494

    瀏覽量

    670252
  • SDIO
    +關注

    關注

    2

    文章

    78

    瀏覽量

    20617
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    明德揚視頻分享點撥FPGA課程--第二十一章 ?矩陣鍵盤工程

    第二十一章矩陣鍵盤工程1. 矩陣掃描模塊2. 數碼顯示模塊3. for循環的使用4. 統計模塊5. generate的使用6. 進制轉換模塊7. 頂層模塊http://yunpan.cn/cjZTiDA9pY56x訪問密碼 c359
    發表于 11-09 08:47

    第二十一講 組合邏輯電路中的競爭冒險

    第二十一講 組合邏輯電路中的競爭冒險 6.7.1 競爭冒險現象及其產生的原因一、競爭、冒險1.理想情況2.實際情況3.競
    發表于 03-30 16:25 ?3495次閱讀
    <b class='flag-5'>第二十一</b>講 組合邏輯電路中的競爭冒險

    模擬電路網絡課件 第二十一節:場效應管與BJT放大電路的比較

    模擬電路網絡課件 第二十一節:場效應管與BJT放大電路的比較 場效應管放大電路與BJT放大電路的性能比較
    發表于 09-17 11:01 ?1531次閱讀
    模擬電路網絡課件 <b class='flag-5'>第二十一</b>節:場效應管與BJT放大電路的比較

    第二十一屆中國西部國際投資貿易洽談會開幕 全方位展示工業4.0以來最新科技成果

    2018年5月25日上午九時,第二十一屆中國西部國際投資貿易洽談會在重慶國際博覽中心正式開幕。
    發表于 07-27 09:20 ?2732次閱讀

    西安高新第二十一小學能耗監測及電力監控系統的研究與應用

    ,為普通居民住宅的10~20倍。公共建筑是節能大戶和節能重點,做好公共建筑節能工作,對促進和帶動全社會節能工作,實現節能減排目標,落實“轉方式、調結構”重大戰略具有重要意義。本文介紹西安高新第二十一小學能耗監測及電力監控系統,采集現場配電室的
    發表于 11-25 15:57 ?1080次閱讀
    西安高新<b class='flag-5'>第二十一</b>小學能耗監測及電力監控系統的研究與應用

    獲雙項榮譽:中科智云受邀出席第二十一屆中國科學家論壇

    上海2023年5月1日?/美通社/ -- 第二十一屆中國科學家論壇于2023年4月27-28日在北京正式召開。本屆論壇以"中國式現代化與科學技術體系化創新"為主題,來自全國各地的科學家、院士、教授
    的頭像 發表于 05-02 21:38 ?1239次閱讀

    【節能學院】西安高新第二十一小學能耗監測及電力監控系統的研究與應用

    公共建筑節能工作,帶動全社會節能工作,實現節能減排目標,落實“轉方式、調結構”重大戰略具有重要意義。本文介紹西安高新第二十一小學能耗監測及電力監控系統,采集現場配電室的
    的頭像 發表于 11-25 18:08 ?1752次閱讀
    【節能學院】西安高新<b class='flag-5'>第二十一</b>小學能耗監測及電力監控系統的研究與應用

    圖撲軟件亮相第二十一屆中國·海峽創新項目成果交易會

    2023 年 6 月 18 日,第二十一屆中國·海峽創新項目成果交易會(以下簡稱“海創會”)在福建省福州市拉開帷幕。海創會作為福建省廣泛吸納國內外科技成果來閩對接,加快科技成果轉化的平臺,一直以來
    的頭像 發表于 06-30 10:33 ?1335次閱讀
    圖撲軟件亮相<b class='flag-5'>第二十一</b>屆中國·海峽創新項目成果交易會

    閃耀灣區,諾安智能獲評第二十一屆“深圳知名品牌(灣區知名品牌)”稱號

    2024年3月5日,深圳知名品牌評價委員會召開第二十一屆“深圳知名品牌”評審會議,審核評選出113個市場占有率高、誠信度高、品牌知名度高的企業品牌為第二十一屆深圳知名品牌。諾安智能在全市50多個細分
    的頭像 發表于 03-20 09:13 ?1521次閱讀
    閃耀灣區,諾安智能獲評<b class='flag-5'>第二十一</b>屆“深圳知名品牌(灣區知名品牌)”稱號

    2024第二十一屆(上海)國際物聯網展覽會4月24日-26日開幕

    交流產業信息,把脈發展方向,IOTE 國際物聯網展是每年物聯網行業、企業、用戶交流合作的大型平臺。2024年4月24-26日IOTE?2024第二十一屆國際物聯網展?上海站,在上海世博展覽館開展。
    的頭像 發表于 04-26 17:59 ?1223次閱讀
    2024<b class='flag-5'>第二十一</b>屆(上海)國際物聯網展覽會4月24日-26日開幕

    云知聲亮相第二十一屆中國-東盟博覽會

    以“親誠惠容同發展 鑲鉆成冠創未來——促進中國—東盟自由貿易區3.0版建設和區域高質量增長”為主題的第二十一屆中國—東盟博覽會(以下簡稱“東博會”)在廣西南寧舉辦。
    的頭像 發表于 10-12 14:18 ?1321次閱讀
    云知聲亮相<b class='flag-5'>第二十一</b>屆中國-東盟博覽會

    知存科技邀您相約第二十一屆全國容錯計算學術會議

    7月18日至20日,由中國計算機學會主辦的第二十一屆全國容錯計算學術會議(CCF CFTC 2025)將在杭州舉行。作為國內容錯計算領域一年一度的盛會,此次會議匯聚了來自學術界和產業界的眾多精英,知存科技將作為存算一體領域的代表企業參會,共同探討前沿技術與行業發展趨勢。
    的頭像 發表于 07-16 15:20 ?1050次閱讀

    魏德米勒亮相第二十一屆工業自動化與標準化研討會

    近日,由機械工業儀器儀表綜合技術經濟研究所、國際電工委員會(IEC)智能制造系統委員會中國專家委員會,聯合舉辦的第二十一屆工業自動化與標準化研討會(IASF)在北京盛大召開。
    的頭像 發表于 07-18 17:46 ?1213次閱讀

    龍芯中科亮相第二十一屆工業自動化與標準化研討會

    近日,由機械工業儀器儀表綜合技術經濟研究所(以下簡稱“儀綜所”)、國際電工委員會(IEC)智能制造系統委員會中國專家委員會聯合主辦的第二十一屆“工業自動化與標準化”研討會在北京召開。
    的頭像 發表于 07-24 15:27 ?964次閱讀

    【展會直擊】2025年第二十一屆中國國際消防設備技術交流展覽會展會現場

    【展會直擊】2025年第二十一屆中國國際消防設備技術交流展覽會展會現場
    的頭像 發表于 10-14 08:03 ?640次閱讀
    【展會直擊】2025年<b class='flag-5'>第二十一</b>屆中國國際消防設備技術交流展覽會展會現場