單芯片解決方案,開啟全新體驗(yàn)——W55MH32 高性能以太網(wǎng)單片機(jī)
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機(jī),它為用戶帶來前所未有的集成化體驗(yàn)。這顆芯片將強(qiáng)大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達(dá)216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲(chǔ)與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨(dú)立的32KB以太網(wǎng)收發(fā)緩存,可供8個(gè)獨(dú)立硬件socket使用。如此配置,真正實(shí)現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32 提供了兩種選擇:QFN68和QFN100。
W55MH32Q采用QFN68封裝版本,尺寸為8x8mm,它擁有36個(gè)GPIO、3個(gè)ADC、12通道DMA、17個(gè)定時(shí)器、2個(gè)I2C、3個(gè)串口、2個(gè)SPI接口(其中1個(gè)帶I2S接口復(fù)用)、1個(gè)CAN以及1個(gè)USB2.0。在保持與同系列其他版本一致的核心性能基礎(chǔ)上,僅減少了部分GPIO以及SDIO接口,其他參數(shù)保持一致,性價(jià)比優(yōu)勢(shì)顯著,尤其適合網(wǎng)關(guān)模組等對(duì)空間布局要求較高的場(chǎng)景。緊湊的尺寸和精簡(jiǎn)化外設(shè)配置,使其能夠在有限空間內(nèi)實(shí)現(xiàn)高效的網(wǎng)絡(luò)連接與數(shù)據(jù)交互,成為物聯(lián)網(wǎng)網(wǎng)關(guān)、邊緣計(jì)算節(jié)點(diǎn)等緊湊型設(shè)備的理想選擇。 同系列還有QFN100封裝的W55MH32L版本,該版本擁有更豐富的外設(shè)資源,適用于需要多接口擴(kuò)展的復(fù)雜工控場(chǎng)景,軟件使用方法一致。更多信息和資料請(qǐng)進(jìn)入http://www.w5500.com/網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32Q這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實(shí)現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評(píng)估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細(xì)信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價(jià)格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。
第二十一章 SDIO接口(SDIO)
1 SDIO 主要功能
SD/SDIOMMC 卡主機(jī)模塊(SDIO)在 AHB 外設(shè)總線和多媒體卡(MMC)、SD 存儲(chǔ)卡、SDIO 卡和 CE-ATA設(shè)備間提供了操作接口。多媒體卡系統(tǒng)規(guī)格書由 MMC技術(shù)委員會(huì)發(fā)布,可以在多媒體卡協(xié)會(huì)的網(wǎng)站上(www.mmca.org)獲得。CE-ATA 系統(tǒng)規(guī)格書可以在 CE-ATA 工作組的網(wǎng)站上(www.ce-ata.org)獲得。SDIO 的主要功能如下:
?與多媒體卡系統(tǒng)規(guī)格書版本 4.2 全兼容。支持三種不同的數(shù)據(jù)總線模式:1 位(默認(rèn))、4 位和8 位。
?與較早的多媒體卡系統(tǒng)規(guī)格版本全兼容(向前兼容)。
?與 SD 存儲(chǔ)卡規(guī)格版本 2.0 全兼容。
?與 SDI/O 卡規(guī)格版本 2.0 全兼容:支持良種不同的數(shù)據(jù)總線模式:1 位(默認(rèn))和 4 位。
?完全支持 CE-ATA 功能(與 CE-ATA 數(shù)字協(xié)議版本 1.1 全兼容)。
?8 位總線模式下數(shù)據(jù)傳輸速率可達(dá) 48MHz。
?數(shù)據(jù)和命令輸出使能信號(hào),用于控制外部雙向驅(qū)動(dòng)器。
注: 1.SDIO 沒有 SPI 兼容的通信模式
2.在多媒體卡系統(tǒng)規(guī)格書版本 2.11 中,定義 SD 存儲(chǔ)卡協(xié)議是多媒體卡協(xié)議的超集。只支持 I/O模式的 SD 卡或復(fù)合卡中的 I/O 部分不能支持 SD 存儲(chǔ)備中很多需要的命令,這里有些命令在SDI/O 設(shè)備中不起作用,如擦除命令,因此 SDIO 不支持這些命令。另外,SD 存儲(chǔ)卡和 SDI/O 卡中有些命令是不同的SDIO 也不支持這些命令。細(xì)節(jié)可以參考 SDI/O 卡規(guī)格書版本 1.0。使用現(xiàn)有的 MMC 命令機(jī)制,在 MMC 接口上可以實(shí)現(xiàn) CE-ATA 的支持。SDIO 接口的電氣和信號(hào)定義詳見MMC 參考資料。多媒體卡/SD 總線將所有卡與控制器相連。當(dāng)前版本的 SDIO 在同一時(shí)間里只能支持一個(gè) SD/SDIO/MMC4.2 卡,但可以支持多個(gè) MMC 版本4.1 或以前版本的卡。
2 SDIO 總線拓?fù)?/strong>
總線上的通信是通過傳送命令和數(shù)據(jù)實(shí)現(xiàn)。在多媒體卡/SD/SDI/O 總線上的基本操作是命令/響應(yīng)結(jié)構(gòu),這樣的總線操作在命令或總線機(jī)制下實(shí)現(xiàn)信息交換;另外,某些操作還具有數(shù)據(jù)令牌。在 SD/SDIO 存儲(chǔ)器卡上傳送的數(shù)據(jù)是以數(shù)據(jù)塊的形式傳輸;在 MMC 上傳送的數(shù)據(jù)是以數(shù)據(jù)塊或數(shù)據(jù)流的形式傳輸;在 CE-ATA 設(shè)備上傳送的數(shù)據(jù)也是以數(shù)據(jù)塊的形式傳輸。
SDIO“無響應(yīng)”和“無數(shù)據(jù)”操作
SDIO(多)數(shù)據(jù)塊讀操作
SDIO(多)數(shù)據(jù)塊寫操作
SDIO 連續(xù)讀操作
SDIO 連續(xù)寫操作
3 SDIO 功能描述
SDIO 包含 2 個(gè)部分:
?--SDIO 適配器模塊:實(shí)現(xiàn)所有 MMC/SD/SDI/O 卡的相關(guān)功能,如時(shí)鐘的產(chǎn)生、命令和數(shù)據(jù)的傳送。
?--AHB 總線接口:操作 SDIO 適配器模塊中的寄存器,并產(chǎn)生中斷和 DMA 請(qǐng)求信號(hào)。
SDIO 框圖
復(fù)位后默認(rèn)情況下 SDIO_D0 用于數(shù)據(jù)傳輸。初始化后主機(jī)可以改變數(shù)據(jù)總線的寬度。如果一個(gè)多媒體卡接到了總線上,則 SDIO_D0、SDIO_D[3:0]或 SDIO_D[7:0]可以用于數(shù)據(jù)傳輸。MMC 版本 V3.31 和之前版本的協(xié)議只支持 1 位數(shù)據(jù)線,所以只能用 SDIO_D0。如果一個(gè) SD 或 SDI/O 卡接到了總線上,可以通過主機(jī)配置數(shù)據(jù)傳輸使用 SDIO_D0 或 SDIO_D[3:0]。所有的數(shù)據(jù)線都工作在推挽模式。
SDIO_CMD 有兩種操作模式:
?用于初始化時(shí)的開路模式(僅用于 MMC 版本 V3.31 或之前版本)
?用于命令傳輸?shù)耐仆炷J?SD/SDI/O 卡和 MMCV4.2 在初始化時(shí)也使用推挽驅(qū)動(dòng))
SDIO_CK 是卡的時(shí)鐘:每個(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 或 SDI/O 卡,時(shí)鐘頻率可以在 0MHz 至 25MHz 間變化。SDIO 使用兩個(gè)時(shí)鐘信號(hào):
?SDIO 適配器時(shí)鐘(SDIOCLK=HCLK)
?AHB 總線時(shí)鐘(HCLK/2)
下表適用于多媒體卡/SD/SDI/O 卡總線:
表 SDIO 引腳定義
引腳 | 方向 | 說明 |
SDIO_CK | 輸出 | 多媒體卡 / SD/SDIO 卡時(shí)鐘。這是從主機(jī)至卡的時(shí)鐘線。 |
SDIO_CMD | 雙向 | 多媒體卡 / SD/SDIO 卡命令。這是雙向的命令 / 響應(yīng)信號(hào)線。 |
SDIO_D[7:0] | 雙向 | 多媒體卡 / SD/SDIO 卡數(shù)據(jù)。這些是雙向的數(shù)據(jù)總線。 |
3.1 SDIO 適配器
下圖是簡(jiǎn)化的 SDIO 適配器框圖:
SDIO 適配器
SDIO 適配器是多媒體/加密數(shù)字存儲(chǔ)卡總線的主設(shè)備(主機(jī)),用于連接一組多媒體卡或加密數(shù)字存儲(chǔ)卡,它包含以下 5 個(gè)部分:
?適配器寄存器模塊
?控制單元
?命令通道
?數(shù)據(jù)通道
?數(shù)據(jù) FIFO
注: 適配器寄存器和 FIFO 使用 AHB 總線一側(cè)的時(shí)鐘(HCLK/2),控制單元、命令通道和數(shù)據(jù)通道使SDIO 適配器一側(cè)的時(shí)鐘(SDIOCLK)。
適配器寄存器模塊
適配器寄存器模塊包含所有系統(tǒng)寄存器。該模塊還產(chǎn)生清除多媒體卡中靜態(tài)標(biāo)記的信號(hào),當(dāng)在SDIO 清除寄存器中的相應(yīng)位寫'1'時(shí)會(huì)產(chǎn)生清除信號(hào)。
控制單元
控制單元包含電源管理功能和為存儲(chǔ)器卡提供的時(shí)鐘分頻。共有三種電源階段:
?電源關(guān)閉
?電源啟動(dòng)
?電源開
控制單元
上圖為控制單元的框圖,有電源管理和時(shí)鐘管理子單元。在電源關(guān)閉和電源啟動(dòng)階段,電源管理子單元會(huì)關(guān)閉卡總線上的輸出信號(hào)。時(shí)鐘管理子單元產(chǎn)生和控制 SDIO_CK 信號(hào)。SDIO_CK 輸出可以使用時(shí)鐘分頻或時(shí)鐘旁路模式。下述情況下沒有時(shí)鐘輸出:
?復(fù)位后
?在電源關(guān)閉和電源啟動(dòng)階段
?當(dāng)啟動(dòng)了省電模式并且卡總線處于空閑狀態(tài)(命令通道和數(shù)據(jù)通道子單元進(jìn)入空閑階段后的 8個(gè)時(shí)鐘周期)
命令通道
命令通道單元向卡發(fā)送命令并從卡接收響應(yīng)。
SDIO適配器命令通道
命令通道狀態(tài)機(jī)(CPSM)
當(dāng)寫入命令寄存器并設(shè)置了使能位,開始發(fā)送命令。命令發(fā)送完成時(shí),命令通道狀態(tài)機(jī)(CPSM)設(shè)置狀態(tài)標(biāo)志并在不需要響應(yīng)時(shí)進(jìn)入空閑狀態(tài)(見下圖)。當(dāng)收到響應(yīng)后,接收到的CRC 碼將會(huì)與內(nèi)部產(chǎn)生的 CRC 碼比較,然后設(shè)置相應(yīng)的狀態(tài)標(biāo)志。
命令通道狀態(tài)機(jī)(CPSM)
當(dāng)進(jìn)入等待(Wait)狀態(tài)時(shí),命令定時(shí)器開始運(yùn)行;當(dāng) CPSM 進(jìn)入接收(Receive)狀態(tài)之前,產(chǎn)生了超時(shí),則設(shè)置超時(shí)標(biāo)志并進(jìn)入空閑(Idle)狀態(tài)。
注: 命令超時(shí)固定為 64 個(gè) SDIO_CK 時(shí)鐘周期。
如果在命令寄存器設(shè)置了中斷位,則關(guān)閉定時(shí)器,CPSM 等待某一個(gè)卡發(fā)出的中斷請(qǐng)求。如果命令寄存器中設(shè)置掛起位,CPSM 進(jìn)入掛起(Pend)狀態(tài)并等待數(shù)據(jù)通道子單元發(fā)出的 CmdPend 信號(hào),在檢測(cè)到 CmdPend 信號(hào)時(shí),CPSM 進(jìn)入發(fā)送(Send)狀態(tài),這將觸發(fā)數(shù)據(jù)計(jì)數(shù)器發(fā)送停止命令的功能。
注: CPSM 保持在空閑狀態(tài)至少 8 個(gè) SDIO_CK 周期,以滿足 NCC 和 NRC 時(shí)序限制。NCC 是兩個(gè)主機(jī)命令間的最小間隔;NRC 是主機(jī)命令與卡響應(yīng)之間的最小間隔。
SDIO命令傳輸
命令格式
命令:命令是用于開始一項(xiàng)操作。主機(jī)向一個(gè)指定的卡或所有的卡發(fā)出帶地址的命令或廣播命令(廣播命令只適合于 MMCV3.31 或之前的版本)。命令在 CMD 線上串行傳送。所有命令的長(zhǎng)度固定為 48 位,下表給出了多媒體卡、SD 存儲(chǔ)卡和 SDIO 卡上一般的命令格式。CE-ATA 命令是 MMCV4.2 命令的擴(kuò)充,所以具有相同的格式。命令通道操作于半雙工模式,這樣命令和響應(yīng)可以分別發(fā)送和接收。如果 CPSM 不處在發(fā)送狀態(tài),SDIO_CMD 輸出處于高阻狀態(tài),如圖 所示。SDIO_CMD 上的數(shù)據(jù)與 SDIO_CK 的上升沿同步。
位 | 寬度 | 數(shù)值 | 說明 |
47 | 1 | 0 | 開始位 |
46 | 1 | 1 | 傳輸位 |
[45:40] | 6 | - | 命令索引 |
[39:8] | 32 | - | 參數(shù) |
[7:1] | 7 | - | CRC7 |
0 | 1 | 1 | 結(jié)束位 |
響應(yīng):響應(yīng)是由一個(gè)被指定地址的卡發(fā)送到主機(jī),對(duì)于 MMCV3.31 或以前版本所有的卡同時(shí)發(fā)送響應(yīng);響應(yīng)是對(duì)先前接收到命令的一個(gè)應(yīng)答。響應(yīng)在 CMD 線上串行傳送。
SDIO 支持 2 種響應(yīng)類型,2 種類型都有 CRC 錯(cuò)誤檢測(cè):
?48 位短響應(yīng)
?136 位長(zhǎng)響應(yīng)
注: 如果響應(yīng)不包含 CRC(如 CMD1 的響應(yīng)),設(shè)備驅(qū)動(dòng)應(yīng)該忽略 CRC 失敗狀態(tài)
短響應(yīng)格式
位 | 寬度 | 數(shù)值 | 說明 |
47 | 1 | 0 | 開始位 |
46 | 1 | 1 | 傳輸位 |
[45:40] | 6 | - | 命令索引 |
[39:8] | 32 | - | 參數(shù) |
[7:1] | 7 | - | CRC7 (或 1111111) |
0 | 1 | 1 | 結(jié)束位 |
長(zhǎng)響應(yīng)格式
位 | 寬度 | 數(shù)值 | 說明 |
135 | 1 | 0 | 開始位 |
134 | 1 | 0 | 傳輸位 |
[133:128] | 6 | 111111 | 保留 |
[127:1] | 127 | - | CID 或 CSD (包含內(nèi)部 CRC7) |
0 | 1 | 1 | 結(jié)束位 |
命令寄存器包含命令索引(發(fā)至卡的 6 位)和命令類型;命令本身決定了是否需要響應(yīng)和響應(yīng)的類型、48 位還是 136 位(見 20.9.4 節(jié))。命令通道中的狀態(tài)標(biāo)志示于下表:
命令通道狀態(tài)標(biāo)志
標(biāo)志 | 說明 |
CMDRCEND | 響應(yīng)的 CRC 正確 |
CCRCFAIL | 響應(yīng)的 CRC 錯(cuò)誤 |
CMDSENT | 命令 (不需要響應(yīng)的命令) 已經(jīng)送出 |
CTIMEOUT | 響應(yīng)超時(shí) |
CMDACT | 正在發(fā)送命令 |
CRC發(fā)生器計(jì)算 CRC碼之前所有位的 CRC校驗(yàn)和,包括開始位、發(fā)送位、命令索引和命令參數(shù)(或卡狀態(tài))。對(duì)于長(zhǎng)響應(yīng)格式,CRC 校驗(yàn)和計(jì)算的是 CID 或 CSD 的前 120 位;注意,長(zhǎng)響應(yīng)格式中的開始位、傳輸位和 6 個(gè)保留位不參與 CRC 計(jì)算。
CRC 校驗(yàn)和是一個(gè) 7 位的數(shù)值:
CRC[6:0]=余數(shù)[(M(x)*x7)/G(x)]
G(x)=x7+x3+1
M(x)=(開始位)*x39+…+(CRC 前的最后一位)*x0,或
M(x)=(開始位)*x119+…+(CRC 前的最后一位)*x0,或
數(shù)據(jù)通道
數(shù)據(jù)通道子單元在主機(jī)與卡之間傳輸數(shù)據(jù)。下圖是數(shù)據(jù)通道的框圖。
數(shù)據(jù)通道
在時(shí)鐘控制寄存器中可以配置卡的數(shù)據(jù)總線寬度。如果選擇了 4 位總線模式,則每個(gè)時(shí)鐘周期四條數(shù)據(jù)信號(hào)線(SDIO_D[3:0])上將傳輸 4 位數(shù)據(jù);如果選擇了 8 位總線模式,則每個(gè)時(shí)鐘周期八條數(shù)據(jù)信號(hào)線(SDIO_D[7:0])上將傳輸 8 位數(shù)據(jù);如果沒有選擇寬總線模式,則每個(gè)時(shí)鐘周期只在SDIO_D0 上傳輸 1 位數(shù)據(jù)。根據(jù)傳輸?shù)姆较?發(fā)送或接收),使能時(shí)數(shù)據(jù)通道狀態(tài)機(jī)(DPSM)將進(jìn)入 Wait_S 或 Wait_R 狀態(tài):
?發(fā)送:DPSM 進(jìn)入 Wait_S 狀態(tài)。如果發(fā)送 FIFO 中有數(shù)據(jù),則 DPSM 進(jìn)入發(fā)送狀態(tài),同時(shí)數(shù)據(jù)通道子單元開始向卡發(fā)送數(shù)據(jù)。
?接收:DPSM 進(jìn)入 Wait_R 狀態(tài)并等待開始位;當(dāng)收到開始位時(shí),DPSM 進(jìn)入接收狀態(tài),同時(shí)數(shù)據(jù)通子單元開始從卡接收數(shù)據(jù)。
數(shù)據(jù)通道狀態(tài)機(jī)(DPSM)
DPSM 工作在 SDIO_CK 頻率,卡總線信號(hào)與 SDIO_CK 的上升沿同步。DPSM 有 6 個(gè)狀態(tài),如下圖所示:
數(shù)據(jù)通道狀態(tài)機(jī)(DPSM)
?空閑(Idle):數(shù)據(jù)通道不工作,SDIO_D[7:0]輸出處于高阻狀態(tài)。當(dāng)寫入數(shù)據(jù)控制寄存器并設(shè)置使能位時(shí),DPSM 為數(shù)據(jù)計(jì)數(shù)器加載新的數(shù)值,并依據(jù)數(shù)據(jù)方向位進(jìn)入 Wait_S 或 Wait_R狀態(tài)。
?Wait_R:如果數(shù)據(jù)計(jì)數(shù)器等于 0,當(dāng)接收 FIFO 為空時(shí) DPSM 進(jìn)入到空閑(Idle)狀態(tài)。如果數(shù)據(jù)計(jì)數(shù)器不等于 0,DPSM 等待 SDIO_D上的開始位。如果 DPSM 在超時(shí)之前接收到一個(gè)開始位,它會(huì)進(jìn)入接收(Receive)狀態(tài)并加載數(shù)據(jù)塊計(jì)數(shù)器。如果 DPSM 在檢測(cè)到一個(gè)開始位前出現(xiàn)超時(shí),或發(fā)生開始位錯(cuò)誤,DPSM 將進(jìn)入空閑狀態(tài)并設(shè)置超時(shí)狀態(tài)標(biāo)志。
?接收(Receive):接收到的串行數(shù)據(jù)被組合為字節(jié)并寫入數(shù)據(jù) FIFO。根據(jù)數(shù)據(jù)控制寄存器中傳輸模式位的設(shè)置,數(shù)據(jù)傳輸模式可以是塊傳輸或流傳輸:
······在塊模式下,當(dāng)數(shù)據(jù)塊計(jì)數(shù)器達(dá)到 0 時(shí),DPSM 等待接收 CRC 碼,如果接收到的代碼與內(nèi)部產(chǎn)生的 CRC 碼匹配,則 DPSM 進(jìn)入 Wait_R 狀態(tài),否則設(shè)置 CRC 失敗狀態(tài)標(biāo)志同時(shí) DPSM進(jìn)入到空閑狀態(tài)。
······在流模式下,當(dāng)數(shù)據(jù)計(jì)數(shù)器不為 0 時(shí),DPSM 接收數(shù)據(jù);當(dāng)計(jì)數(shù)器為 0 時(shí),將移位寄存器中的剩余數(shù)據(jù)寫入數(shù)據(jù) FIFO,同時(shí) DPSM 進(jìn)入 Wait_R 狀態(tài)。如果產(chǎn)生了 FIFO 上溢錯(cuò)誤,DPSM 設(shè)置 FIFO 的錯(cuò)誤標(biāo)志并進(jìn)入空閑狀態(tài)。
?Wait_S:如果數(shù)據(jù)計(jì)數(shù)器為 0,DPSM 進(jìn)入空閑狀態(tài);否則 DPSM 等待數(shù)據(jù) FIFO 空標(biāo)志消失后,進(jìn)入發(fā)送狀態(tài)。
注: DPSM 會(huì)在 Wait_S 狀態(tài)保持至少 2 個(gè)時(shí)鐘周期,以滿足 NWR 的時(shí)序要求,NWR 是接收到卡的響應(yīng)至主機(jī)開始數(shù)據(jù)傳輸?shù)拈g隔。
?發(fā)送(Send):DPSM 開始發(fā)送數(shù)據(jù)到卡設(shè)備。根據(jù)數(shù)據(jù)控制寄存器中傳輸模式位的設(shè)置,數(shù)據(jù)傳輸模式可以是塊傳輸或流傳輸:
······在塊模式下,當(dāng)數(shù)據(jù)塊計(jì)數(shù)器達(dá)到 0 時(shí),DPSM 發(fā)送內(nèi)部產(chǎn)生的 CRC 碼,然后是結(jié)束位,并進(jìn)入繁忙狀態(tài)。
······在流模式下,當(dāng)使能位為高同時(shí)數(shù)據(jù)計(jì)數(shù)器不為 0 時(shí),DPSM 向卡設(shè)備發(fā)送數(shù)據(jù),然后進(jìn)入空閑狀態(tài)。如果產(chǎn)生了 FIFO 下溢錯(cuò)誤,DPSM 設(shè)置 FIFO 的錯(cuò)誤標(biāo)志并進(jìn)入空閑狀態(tài)。
?繁忙(Busy):DPSM 等待 CRC 狀態(tài)標(biāo)志:
······如果沒有接收到正確的 CRC 狀態(tài),則 DPSM 進(jìn)入空閑狀態(tài)并設(shè)置 CRC 失敗狀態(tài)標(biāo)志。
······如果接收到正確的 CRC 狀態(tài),則當(dāng) SDIO_D0 不為低時(shí)(卡不繁忙)DPSM 進(jìn)入 Wait_S 狀態(tài)。
當(dāng) DPSM 處于繁忙狀態(tài)時(shí)發(fā)生了超時(shí),DPSM 則設(shè)置數(shù)據(jù)超時(shí)標(biāo)志并進(jìn)入空閑狀態(tài)。
當(dāng) DPSM 處于 Wait_R 或繁忙狀態(tài)時(shí),數(shù)據(jù)定時(shí)器被使能,并能夠產(chǎn)生數(shù)據(jù)超時(shí)錯(cuò)誤:
······發(fā)送數(shù)據(jù)時(shí),如果 DPSM 處于繁忙狀態(tài)超過程序設(shè)置的超時(shí)間隔,則產(chǎn)生超時(shí)。
······接收數(shù)據(jù)時(shí),如果未收完所有數(shù)據(jù),并且 DPSM 處于 Wait_R 狀態(tài)超過程序設(shè)置的超時(shí)間隔,則產(chǎn)生超時(shí)。
?數(shù)據(jù):數(shù)據(jù)可以從主機(jī)傳送到卡,也可以反向傳輸。數(shù)據(jù)在數(shù)據(jù)線上傳輸。數(shù)據(jù)存儲(chǔ)在一個(gè)32 字的 FIFO 中,每個(gè)字為 32 位寬。
數(shù)據(jù)令牌格式
說明 | 開始位 | 數(shù)據(jù) | CRC16 | 結(jié)束位 |
塊數(shù)據(jù) | 0 | - | 有 | 1 |
流數(shù)據(jù) | 0 | - | 無 | 1 |
數(shù)據(jù) FIFO
數(shù)據(jù) FIFO(先進(jìn)先出)子單元是一個(gè)具有發(fā)送和接收單元的數(shù)據(jù)緩沖區(qū)。FIFO 包含一個(gè)每字 32 位寬、共 32 個(gè)字的數(shù)據(jù)緩沖區(qū),和發(fā)送與接收電路。因?yàn)閿?shù)據(jù) FIFO 工作在AHB 時(shí)鐘區(qū)域(HCLK/2),所有與 SDIO 時(shí)鐘區(qū)域(SDIOCLK)連接的信號(hào)都進(jìn)行了重新同步。依據(jù) TXACT 和 RXACT 標(biāo)志,可以關(guān)閉 FIFO、使能發(fā)送或使能接收。TXACT 和 RXACT 由數(shù)據(jù)通道子單元設(shè)置而且是互斥的:
······當(dāng) TXACT 有效時(shí),發(fā)送 FIFO 代表發(fā)送電路和數(shù)據(jù)緩沖區(qū)
······當(dāng) RXACT 有效時(shí),接收 FIFO 代表接收電路和數(shù)據(jù)緩沖區(qū)
?發(fā)送 FIFO:當(dāng)使能了 SDIO 的發(fā)送功能,數(shù)據(jù)可以通過 AHB 接口寫入發(fā)送 FIFO。
發(fā)送 FIFO 有 32 個(gè)連續(xù)的地址。發(fā)送 FIFO 中有一個(gè)數(shù)據(jù)輸出寄存器,包含讀指針指向的數(shù)據(jù)字。當(dāng)數(shù)據(jù)通道子單元裝填了移位寄存器后,它移動(dòng)讀指針至下個(gè)數(shù)據(jù)并傳輸出數(shù)據(jù)。如果未使能發(fā)送 FIFO,所有的狀態(tài)標(biāo)志均處于無效狀態(tài)。當(dāng)發(fā)送數(shù)據(jù)時(shí),數(shù)據(jù)通道子單元設(shè)置TXACT 為有效。
發(fā)送 FIFO 狀態(tài)標(biāo)志
標(biāo)志 | 說明 |
TXFIFOF | 當(dāng)所有 32 個(gè)發(fā)送 FIFO 字都有有效的數(shù)據(jù)時(shí),該標(biāo)志為高。 |
TXFIFOE | 當(dāng)所有 32 個(gè)發(fā)送 FIFO 字都沒有有效的數(shù)據(jù)時(shí),該標(biāo)志為高。 |
TXFIFOHE | 當(dāng) 8 個(gè)或更多發(fā)送 FIFO 字為空時(shí),該標(biāo)志為高。該標(biāo)志可以作為 DMA 請(qǐng)求。 |
TXDAVL | 當(dāng)發(fā)送 FIFO 包含有效數(shù)據(jù)時(shí),該標(biāo)志為高。該標(biāo)志的意思剛好與 TXFIFOE 相反。 |
TXUNDERR | 當(dāng)發(fā)生下溢錯(cuò)誤時(shí),該標(biāo)志為高。寫入 SDIO 清除寄存器時(shí)清除該標(biāo)志。 |
?接收 FIFO:當(dāng)數(shù)據(jù)通道子單元接收到一個(gè)數(shù)據(jù)字,它會(huì)把數(shù)據(jù)寫入 FIFO,寫操作結(jié)束后,寫指針自動(dòng)加一;在另一端,有一個(gè)讀指針始終指向FIFO中的當(dāng)前數(shù)據(jù)。如果關(guān)閉了接收FIFO,所有的狀態(tài)標(biāo)志會(huì)被清除,讀寫指針也被復(fù)位。在接收到數(shù)據(jù)時(shí)數(shù)據(jù)通道子單元設(shè)置 RXACT。下表列出了接收 FIFO 的狀態(tài)標(biāo)志。通過 32 個(gè)連續(xù)的地址可以訪問接收 FIFO。
接收 FIFO 狀態(tài)標(biāo)志
標(biāo)志 | 說明 |
RXFIFOF | 當(dāng)所有 32 個(gè)接收 FIFO 字都有有效的數(shù)據(jù)時(shí),該標(biāo)志為高。 |
RXFIFOE | 當(dāng)所有 32 個(gè)接收 FIFO 字都沒有有效的數(shù)據(jù)時(shí),該標(biāo)志為高。 |
RXFIFOHF | 當(dāng) 8 個(gè)或更多接收 FIFO 字有有效的數(shù)據(jù)時(shí),該標(biāo)志為高。該標(biāo)志可以作為 DMA 請(qǐng)求。 |
RXDAVL | 當(dāng)接收 FIFO 包含有效數(shù)據(jù)時(shí),該標(biāo)志為高。該標(biāo)志的意思剛好與 RXFIFOE 相反。 |
RXOVERR | 當(dāng)發(fā)生上溢錯(cuò)誤時(shí),該標(biāo)志為高。寫入 SDIO 清除寄存器時(shí)清除該標(biāo)志。 |
3.2 SDIOAHB 接口
AHB 接口產(chǎn)生中斷和 DMA 請(qǐng)求,并訪問 SDIO 接口寄存器和數(shù)據(jù) FIFO。它包含一個(gè)數(shù)據(jù)通道、寄存器譯碼器和中斷/DMA 控制邏輯。
SDIO 中斷
當(dāng)至少有一個(gè)選中的狀態(tài)標(biāo)志為高時(shí),中斷控制邏輯產(chǎn)生中斷請(qǐng)求。有一個(gè)屏蔽寄存器用于選擇可以產(chǎn)生中斷的條件,如果設(shè)置了相應(yīng)的屏蔽標(biāo)志,則對(duì)應(yīng)的狀態(tài)標(biāo)志可以產(chǎn)生中斷。
SDIO/DMA 接口:在 SDIO 和存儲(chǔ)器之間數(shù)據(jù)傳輸?shù)倪^程
在下面的例子中,主機(jī)控制器使用 CMD24(WRITE_BLOCK)從主機(jī)傳送 512 字節(jié)到 MMC 卡,DMA 控制器用于從存儲(chǔ)器向 SDIO 的 FIFO 填充數(shù)據(jù)。
執(zhí)行卡識(shí)別過程。
提高 SDIO_CK 頻率。
發(fā)送 CMD7 命令選擇卡。
按下述步驟配置 DMA2:
使能 DMA2 控制器并清除所有的中斷標(biāo)志位。
設(shè)置 DMA2 通道 4 的源地址寄存器為存儲(chǔ)器緩沖區(qū)的基地址,DMA2 通道 4 的目標(biāo)地址寄存器為SDIO_FIFO 寄存器的地址。
設(shè)置 DMA2 通道 4 控制寄存器(存儲(chǔ)器遞增,非外設(shè)遞增,外設(shè)和源的數(shù)據(jù)寬度為字寬度)。
使能 DMA2 通道 4。
發(fā)送 CMD24(WRITE_BLOCK),操作如下:
設(shè)置 SDIO 數(shù)據(jù)長(zhǎng)度寄存器(SDIO 數(shù)據(jù)時(shí)鐘寄存器應(yīng)該在執(zhí)行卡識(shí)別過程之前設(shè)置好)。
設(shè)置 SDIO 參數(shù)寄存器為卡中需要傳送數(shù)據(jù)的地址。
設(shè)置 SDIO 命令寄存器:CmdIndex 置為 24(WRITE_BLOCK);WaitRest 置為 1(SDIO 卡主機(jī)等待響應(yīng));CPSMEN 置為 1(使能 SDIO 卡主機(jī)發(fā)送命令),保持其它域?yàn)樗麄兊膹?fù)位值。
等待 SDIO_STA[6]=CMDREND 中斷,然后設(shè)置 SDIO 數(shù)據(jù)寄存器:DTEN 置為 1(使能 SDIO卡主機(jī)發(fā)送數(shù)據(jù));DTDIR 置為 0(控制器至卡方向);DTMODE 置為 0(塊數(shù)據(jù)傳送);DMAEN 置為 1(使能 DMA);DBLOCKSIZE 置為 9(512 字節(jié));其它域不用設(shè)置。
等待 SDIO_STA[10]=DBCKEND。
查詢 DMA 通道的使能狀態(tài)寄存器,確認(rèn)沒有通道仍處于使能狀態(tài)。
4 卡功能描述
4.1 卡識(shí)別模式
在卡識(shí)別模式,主機(jī)復(fù)位所有的卡、檢測(cè)操作電壓范圍、識(shí)別卡并為總線上每個(gè)卡設(shè)置相對(duì)地址(RCA)。在卡識(shí)別模式下,所有數(shù)據(jù)通信只使用命令信號(hào)線(CMD)。
4.2 卡復(fù)位
GO_IDLE_STATE 命令(CMD0)是一個(gè)軟件復(fù)位命令,它把多媒體卡和 SD 存儲(chǔ)器置于空閑狀態(tài)。
IO_RW_DIRECT 命令(CMD52)復(fù)位 SDI/O 卡。上電后或執(zhí)行 CMD0 后,所有卡的輸出端都處于高阻狀態(tài),同時(shí)所有卡都被初始化至一個(gè)默認(rèn)的相對(duì)卡地址(RCA=0x0001)和默認(rèn)的驅(qū)動(dòng)器寄存器設(shè)置(最低的速度,最大的電流驅(qū)動(dòng)能力)。
4.3 操作電壓范圍確認(rèn)
所有的卡都可以使用任何規(guī)定范圍內(nèi)的電壓與 SDIO卡主機(jī)通信,可支持的最小和最大電壓 VDD數(shù)值由卡上的操作條件寄存器(OCR)定義。內(nèi)部存儲(chǔ)器存儲(chǔ)了卡識(shí)別號(hào)(CID)和卡特定數(shù)據(jù)(CSD)的卡 ,僅能在數(shù)據(jù)傳輸 VDD 條件下傳送這些信息。
當(dāng) SDIO 卡主機(jī)模塊與卡的 VDD 范圍不一致時(shí),卡將不能完成識(shí)別周期,也不能發(fā)送 CSD數(shù)據(jù);因此,在 VDD 范圍不匹配時(shí),SDIO 卡主機(jī)可以用下面幾個(gè)特殊命令去識(shí)別和拒絕卡:SEND_OP_COND(CMD1)、SD_APP_OP_COND(SD 存儲(chǔ)卡的 ACMD41)和 IO_SEND_OP_COND(SDI/O卡的 CMD5)。
SDIO 卡主機(jī)在執(zhí)行這幾個(gè)命令時(shí)會(huì)產(chǎn)生需要的 VDD 電壓。不能在指定的電壓范圍進(jìn)行數(shù)據(jù)傳輸?shù)目ǎ瑢目偩€斷開并進(jìn)入非激活狀態(tài)。使用這些不包含電壓范圍作為操作數(shù)的命令,SDIO 卡主機(jī)能夠查詢每個(gè)卡并在確定公共的電壓范圍前,把不在此范圍內(nèi)的卡置于非激活狀態(tài)。當(dāng) SDIO 卡主機(jī)能夠選擇公共的電壓范圍或用戶需要知道卡是否能用時(shí),SDIO 卡主機(jī)可以進(jìn)行這樣的查詢。
4.4 卡識(shí)別過程
多媒體卡和 SD 卡的卡識(shí)別過程是有區(qū)別的;對(duì)于多媒體卡,卡識(shí)別過程以時(shí)鐘頻率 Fod 開始,所有 SDIO_CMD 輸出為開路驅(qū)動(dòng),允許在這個(gè)過程中的卡的并行連接,識(shí)別過程如下:
1. 總線被激活。
2. SDIO 卡主機(jī)廣播發(fā)送 SEND_OP_COND(CMD1)命令,并接收操作條件。
3. 得到的響應(yīng)是所有卡的操作條件寄存器內(nèi)容的“線與”。
4. 不兼容的卡會(huì)被置于非激活狀態(tài)。
5. SDIO 卡主機(jī)廣播發(fā)送 ALL_SEND_CID(CMD2)至所有激活的卡。
6. 所有激活的卡同時(shí)串行地發(fā)送他們的 CID 號(hào),那些檢測(cè)到輸出的 CID 位與命令線上的數(shù)據(jù)不相符的卡必須停止發(fā)送,并等待下一個(gè)識(shí)別周期。最終只有一個(gè)卡能夠成功地傳送完整的CID 至 SDIO 卡主機(jī)并進(jìn)入識(shí)別狀態(tài)。
7. SDIO 卡主機(jī)發(fā)送 SET_RELATIVE_ADDR(CMD3)命令至這個(gè)卡,這個(gè)新的地址被稱為相對(duì)卡地址(RCA),它比 CID 短,用于對(duì)卡尋址。至此,這個(gè)卡轉(zhuǎn)入待機(jī)狀態(tài),并不再響應(yīng)新的識(shí)別過程,同時(shí)它的輸出驅(qū)動(dòng)從開路轉(zhuǎn)變?yōu)橥仆炷J健?/p>
SDIO 卡主機(jī)重復(fù)上述步驟 5 至 7,直到收到超時(shí)條件。對(duì)于 SD 卡而言,卡識(shí)別過程以時(shí)鐘頻率 Fod 開始,所有 SDIO_CMD 輸出為推挽驅(qū)動(dòng)而不是開路驅(qū)動(dòng),識(shí)別過程如下:
1. 總線被激活
2. SDIO 卡主機(jī)廣播發(fā)送 SEND_APP_OP_COND(ACMD41)命令
3. 得到的響應(yīng)是所有卡的操作條件寄存器的內(nèi)容
4. 不兼容的卡會(huì)被置于非激活狀態(tài)
5. SDIO 卡主機(jī)廣播發(fā)送 ALL_SEND_CID(CMD2)至所有激活的卡
6. 所有激活的卡發(fā)送回他們唯一卡識(shí)別號(hào)(CID)并進(jìn)入識(shí)別狀態(tài)。
7. SDIO 卡主機(jī)發(fā)送 SET_RELATIVE_ADDR(CMD3)命令和一個(gè)地址到一個(gè)激活的卡,這個(gè)新的地址被稱為相對(duì)卡地址(RCA),它比 CID 短,用于對(duì)卡尋址。至此,這個(gè)卡轉(zhuǎn)入待機(jī)狀態(tài)。SDIO卡主機(jī)可以再次發(fā)送該命令更改 RCA,卡的 RCA 將是最后一次的賦值。
8. SDIO 卡主機(jī)對(duì)所有激活的卡重復(fù)上述步驟 5 至 7。
對(duì)于 SDI/O 卡而言,卡識(shí)別過程如下:
1. 總線被激活
2. SDIO 卡主機(jī)發(fā)送 IO_SEND_OP_COND(CMD5)命令
3. 得到的響應(yīng)是卡的操作條件寄存器的內(nèi)容
4. 不兼容的卡會(huì)被置于非激活狀態(tài)
5. SDIO 卡主機(jī)發(fā)送 SET_RELATIVE_ADDR(CMD3)命令和一個(gè)地址到一個(gè)激活的卡,這個(gè)新的地址被稱為相對(duì)卡地址(RCA),它比 CID 短,用于對(duì)卡尋址。至此,這個(gè)卡轉(zhuǎn)入待機(jī)狀態(tài)。SDIO卡主機(jī)可以再次發(fā)送該命令更改 RCA,卡的 RCA 將是最后一次的賦值。
4.5 寫數(shù)據(jù)塊
執(zhí)行寫數(shù)據(jù)塊命令(CMD24-27)時(shí),主機(jī)把一個(gè)或多個(gè)數(shù)據(jù)塊從主機(jī)傳送到卡中,同時(shí)在每個(gè)數(shù)據(jù)塊的末尾傳送一個(gè) CRC 碼。一個(gè)支持寫數(shù)據(jù)塊命令的卡應(yīng)該始終能夠接收由 WRITE_BL_LEN 定義的數(shù)據(jù)塊。如果CRC校驗(yàn)錯(cuò)誤,卡通過SDIO_D信號(hào)線指示錯(cuò)誤,傳送的數(shù)據(jù)被丟棄而不被寫入,所有后續(xù)(在多塊寫模式下)傳送的數(shù)據(jù)塊將被忽略。
如果主機(jī)傳送部分?jǐn)?shù)據(jù),而累計(jì)的數(shù)據(jù)長(zhǎng)度未與數(shù)據(jù)塊對(duì)齊,當(dāng)不允許塊錯(cuò)位(未設(shè)置 CSD 的參數(shù)WRITE_BLK_MISALIGN),卡將在第一個(gè)錯(cuò)位的塊之前檢測(cè)到塊錯(cuò)位錯(cuò)誤(設(shè)置狀態(tài)寄存器中的ADDRESS_ERROR 錯(cuò)誤位)。當(dāng)主機(jī)試圖寫一個(gè)寫保護(hù)區(qū)域時(shí),寫操作也會(huì)被中止,此時(shí)卡會(huì)設(shè)置WP_VIOLATION 位。設(shè)置 CID 和 CSD 寄存器不需要事先設(shè)置塊長(zhǎng)度,傳送的數(shù)據(jù)也是通過 CRC 保護(hù)的。如果 CSD 或CID 寄存器的部分是存儲(chǔ)在 ROM 中,則這個(gè)不能更改的部分必須與接收緩沖區(qū)的對(duì)應(yīng)部分相一致,如果有不一致之處,卡將報(bào)告一個(gè)錯(cuò)誤同時(shí)不修改任何寄存器的內(nèi)容。有些卡需要長(zhǎng)的甚至不可預(yù)計(jì)的時(shí)間完成寫一個(gè)數(shù)據(jù)塊,在接收一個(gè)數(shù)據(jù)塊并完成 CRC 檢驗(yàn)后,卡開始寫操作,如果它的寫緩沖區(qū)已經(jīng)滿并且不能再從新的 WRITE_BLOCK 命令接受新的數(shù)據(jù)時(shí),它會(huì)把 SDIO_D 信號(hào)線拉低。
主機(jī)可以在任何時(shí)候使用 SEND_STATUS(CMD13)查詢卡的狀態(tài),卡將返回當(dāng)前狀態(tài)。READY_FOR_DATA 狀態(tài)位指示卡是否可以接受新的數(shù)據(jù)或?qū)懖僮魇欠襁€在進(jìn)行。主機(jī)可以使用CMD7(選擇另一個(gè)卡)不選中某個(gè)卡,而把這個(gè)卡置于斷開狀態(tài),這樣可以釋放 SDIO_D 信號(hào)線而不中斷未完成的寫操作;當(dāng)重新選擇了一個(gè)卡,如果寫操作仍然在進(jìn)行并且寫緩沖區(qū)仍不能使用,它會(huì)重新通過拉低 SDIO_D 信號(hào)線指示忙的狀態(tài)。
4.6 讀數(shù)據(jù)塊
在讀數(shù)據(jù)塊模式下,數(shù)據(jù)傳輸?shù)幕締卧菙?shù)據(jù)塊,它的大小在 CSD 中(READ_BL_LEN)定義。如果設(shè)置了 READ_BL_PARTIAL,同樣可以傳送較小的數(shù)據(jù)塊,較小數(shù)據(jù)塊是指開始和結(jié)束地址完全包含在一個(gè)物理塊中,READ_BL_LEN 定義了物理塊的大小。為保證數(shù)據(jù)傳輸?shù)恼_,每個(gè)數(shù)據(jù)塊后都有一個(gè) CRC 校驗(yàn)碼。CMD17(READ_SINGLE_BLOCK)啟動(dòng)一次讀數(shù)據(jù)塊操作,在傳輸結(jié)束后卡返回到發(fā)送狀態(tài)。
CMD18(READ_MULTIPLE_BLOCK)啟動(dòng)一次連續(xù)多個(gè)數(shù)據(jù)塊的讀操作。主機(jī)可以在多數(shù)據(jù)塊讀操作的任何時(shí)候中止操作,而不管操作的類型。發(fā)送停止傳輸命令即可中止操作。如果在多數(shù)據(jù)塊讀操作中(任一種類型)卡檢測(cè)到錯(cuò)誤(例如:越界、地址錯(cuò)位或內(nèi)部錯(cuò)誤),它將停止數(shù)據(jù)傳輸并仍處于數(shù)據(jù)狀態(tài);此時(shí)主機(jī)必須發(fā)送停止傳輸命令中止操作。在停止傳輸命令的響應(yīng)中報(bào)告讀錯(cuò)誤。如果主機(jī)發(fā)送停止傳輸命令時(shí),卡已經(jīng)傳輸完一個(gè)確定數(shù)目的多個(gè)數(shù)據(jù)塊操作中的最后一個(gè)數(shù)據(jù)塊,因?yàn)榇藭r(shí)卡已經(jīng)不在數(shù)據(jù)狀態(tài),主機(jī)會(huì)得到一個(gè)非法命令的響應(yīng)。如果主機(jī)傳輸部分?jǐn)?shù)據(jù)塊,而累計(jì)的數(shù)據(jù)長(zhǎng)度不能與物理塊對(duì)齊同時(shí)不允許塊錯(cuò)位,卡會(huì)在出現(xiàn)第一個(gè)未對(duì)齊的塊時(shí)檢測(cè)出一個(gè)塊對(duì)齊錯(cuò)誤,并在狀態(tài)寄存器中設(shè)置 ADDRESS_ERROR 錯(cuò)誤標(biāo)志。
4.7 數(shù)據(jù)流操作,數(shù)據(jù)流寫入和數(shù)據(jù)流讀出(只適用于多媒體卡)
在數(shù)據(jù)流模式,數(shù)據(jù)按字節(jié)傳輸,同時(shí)每個(gè)數(shù)據(jù)塊后沒有 CRC。數(shù)據(jù)流寫(只適用于多媒體卡)WRITE_DAT_UNTIL_STOP(CMD20)開始從 SDIO 卡主機(jī)至卡的數(shù)據(jù)傳輸,從指定的地址開始連續(xù)傳輸直到 SDIO 卡主機(jī)發(fā)出一個(gè)停止命令。如果允許部分?jǐn)?shù)據(jù)塊傳輸(設(shè)置了 CSD 參 數(shù)WRITE_BL_PARTIAL),則數(shù)據(jù)流可以在卡的地址空間中的任意地址開始和停止,否則數(shù)據(jù)流只能在數(shù)據(jù)塊的邊界開始和停止。因?yàn)閭鬏數(shù)臄?shù)據(jù)數(shù)目沒有事先設(shè)定,不能使用 CRC 校驗(yàn)。
如果發(fā)送數(shù)據(jù)時(shí)達(dá)到了存儲(chǔ)器的最大地址,即使 SDIO 卡主機(jī)沒有發(fā)送停止命令,隨后傳輸?shù)臄?shù)據(jù)也會(huì)被丟棄。
數(shù)據(jù)流寫操作的最大時(shí)鐘頻率可以通過下式計(jì)算:
?Maximumspeed=最大寫頻率
?TRANSPEED=最大數(shù)據(jù)傳輸率
?writebllen=最大寫數(shù)據(jù)塊長(zhǎng)度
?NSAC=以 CLK 周期計(jì)算的數(shù)據(jù)讀操作時(shí)間 2
?TAAC=數(shù)據(jù)讀操作時(shí)間 1
?R2WFACTOR=寫速度因子
如果主機(jī)試圖使用更高的頻率,卡可能不能處理數(shù)據(jù)并停止編程,同時(shí)在狀態(tài)寄存器中設(shè)置OVERRUN 錯(cuò)誤位,丟棄所有隨后傳輸?shù)臄?shù)據(jù)并(在接收數(shù)據(jù)狀態(tài))等待停止命令。如果主機(jī)試圖寫入一個(gè)寫保護(hù)區(qū)域,寫操作將被中止,同時(shí)卡將設(shè)置 WP_VIOLATION 位。數(shù)據(jù)流讀(只適用于多媒體卡)READ_DAT_UNTIL_STOP(CMD11)控制數(shù)據(jù)流數(shù)據(jù)傳輸。這個(gè)命令要求卡從指定的地址讀出數(shù)據(jù),直到 SDIO 卡主機(jī)發(fā)送 STOP_TRANSMISSION(CMD12)。
因?yàn)榇忻顐鬏數(shù)难舆t,停止命令的執(zhí)行會(huì)有延遲,數(shù)據(jù)傳送會(huì)在停止命令的結(jié)束位后停止。如果發(fā)送數(shù)據(jù)時(shí)達(dá)到了存儲(chǔ)器的最大地址,SDIO 卡主機(jī)沒有發(fā)送命令,隨后傳輸?shù)臄?shù)據(jù)將是無效數(shù)據(jù)。
數(shù)據(jù)流讀操作的最大時(shí)鐘頻率可以通過下式計(jì)算:
?Maximumspeed=最大寫頻率
?TRANSPEED=最大數(shù)據(jù)傳輸率
?readbllen=最大讀數(shù)據(jù)塊長(zhǎng)度
?NSAC=以 CLK 周期計(jì)算的數(shù)據(jù)讀操作時(shí)間 2
?TAAC=數(shù)據(jù)讀操作時(shí)間 1
?R2WFACTOR=寫速度因子
如果主機(jī)試圖使用更高的頻率,卡將不能處理數(shù)據(jù)傳輸,此時(shí)卡在狀態(tài)寄存器中設(shè)置 UNDERRUN錯(cuò)誤位,中止數(shù)據(jù)傳輸并在數(shù)據(jù)狀態(tài)等待停止命令。
4.8 擦除:成組擦除和扇區(qū)擦除
多媒體卡的擦除單位是擦除組,擦除組是以寫數(shù)據(jù)塊計(jì)算,寫數(shù)據(jù)塊是卡的基本寫入單位。擦除組的大小是卡的特定參數(shù),在 CSD 中定義。
主機(jī)可以擦除一個(gè)連續(xù)范圍的擦除組,開始擦除操作有三個(gè)步驟。
首先,主機(jī)使用 ERASE_GROUP_START(CMD35)命令定義連續(xù)范圍的開始地址,然后使用ERASE_GROUP_END(CMD36)命令定義連續(xù)范圍的結(jié)束地址,最后發(fā)送擦除命令 ERASE(CMD38)開始擦除操作。擦除命令的地址域是以字節(jié)為單位的擦除組地址。卡會(huì)舍棄未與擦除組大小對(duì)齊的部分,把地址邊界對(duì)齊到擦除組的邊界。如果未按照上述步驟收到了擦除命令,卡在狀態(tài)寄存器中設(shè)置 ERASE_SEQ_ERROR 位,并重新等待第一個(gè)步驟。如果收到了除 SEND_STATUS 和擦除命令之外的其它命令,卡在狀態(tài)寄存器中設(shè)置 ERASE_RESET位,解除擦除序列并執(zhí)行新的命令。如果擦除范圍包含了寫保護(hù)數(shù)據(jù)塊,這些塊不被擦除,只有未保護(hù)的塊被擦除,同時(shí)卡在狀態(tài)寄存器中設(shè)置 WP_ERASE_SKIP 狀態(tài)位。在擦除過程中,卡拉低 SDIO_D 信號(hào)。實(shí)際的擦除時(shí)間可能很長(zhǎng),主機(jī)可以使用 CMD7 解除卡的選擇。
4.9 寬總線選擇和解除選擇
可以通過 SET_BUS_WIDTH(ACMD6)命令選擇或不選擇寬總線(4 位總線寬度)操作模式,上電后或GO_IDLE_STATE(CMD0)命令后默認(rèn)的總線寬度為 1 位。SET_BUS_WIDTH(ACMD6)命令僅在傳輸狀態(tài)時(shí)有效,即只有在使用 SELECT/DESELECT_CARD(CMD7)命令選擇了卡后才能改變總線寬度。
4.10 保護(hù)管理
SDIO 卡主機(jī)模塊支持三種保護(hù)方式:
1. 內(nèi)部卡保護(hù)(卡內(nèi)管理)
2. 機(jī)械寫保護(hù)開關(guān)(僅由 SDIO 卡主機(jī)模塊管理)
3. 密碼管理的卡鎖操作
內(nèi)部卡的寫保護(hù)
卡的數(shù)據(jù)可以被保護(hù)不被覆蓋或擦除。在 CSD 中永久地或臨時(shí)地設(shè)置寫保護(hù)位,生產(chǎn)廠商或內(nèi)容提供商可以永久地對(duì)整個(gè)卡施行寫保護(hù)。對(duì)于支持在 CSD 中設(shè)置 WP_GRP_ENABLE 位從而提供一組扇區(qū)寫保護(hù)的卡,部分?jǐn)?shù)據(jù)可以被保護(hù),寫保護(hù)可以通過程序改變。寫保護(hù)的基本單位是 CSD參數(shù) WP_GRP_SIZE 個(gè)扇區(qū)。
SET_WRITE_PROT 和 CLR_WRITE_PROT 命令控制指定組的保護(hù),SEND_WRITE_PROT 命令與單數(shù)據(jù)塊讀命令類似,卡送出一個(gè)包含 32 個(gè)寫保護(hù)位(代表從指定地址開始的 32 個(gè)寫保護(hù)組)的數(shù)據(jù)塊,跟著一個(gè) 16 位的 CRC 碼。寫保護(hù)命令的地址域是一個(gè)以字節(jié)為單位的組地址。卡將截?cái)嗨薪M大小以下的地址。
機(jī)械寫保護(hù)開關(guān)
在卡的側(cè)面有一個(gè)機(jī)械的滑動(dòng)開關(guān),允許用戶設(shè)置或清除卡的寫保護(hù)。當(dāng)滑動(dòng)開關(guān)置于小窗口打開的位置時(shí),卡處于寫保護(hù)狀態(tài),當(dāng)滑動(dòng)開關(guān)置于小窗口關(guān)閉的位置時(shí),可以更改卡中內(nèi)容。在卡的插槽上的對(duì)應(yīng)部位也有一個(gè)開關(guān)指示 SDIO 卡主機(jī)模塊,卡是否處于寫保護(hù)狀態(tài)。卡的內(nèi)部電路不知道寫保護(hù)開關(guān)的位置。
密碼保護(hù)
密碼保護(hù)功能允許 SDIO 卡主機(jī)模塊使用密碼對(duì)卡實(shí)行上鎖或解鎖。密碼存儲(chǔ)在 128 位的 PWD 寄存器中,它的長(zhǎng)度設(shè)置在 8 位的 PWD_LEN 寄存器中。這些寄存器是不可揮發(fā)的,即掉電后它們的內(nèi)容不丟失。已上鎖的卡能夠響應(yīng)和執(zhí)行相應(yīng)的命令,即允許 SDIO 卡主機(jī)模塊執(zhí)行復(fù)位、初始化和查詢狀態(tài)等操作,但不允許操作卡中的數(shù)據(jù)。當(dāng)設(shè)置了密碼后(即 PWD_LEN 的數(shù)值不為 0),上電后卡自動(dòng)處于上鎖狀態(tài)。
正如 CSD 和 CID 寄存器寫命令,上鎖/解鎖命令僅在傳輸狀態(tài)下有效,在這個(gè)狀態(tài)下,命令中沒有地址參數(shù),但卡已經(jīng)被選中。卡的上鎖/解鎖命令具有單數(shù)據(jù)塊寫命令的結(jié)構(gòu)和總線操作類型,傳輸?shù)臄?shù)據(jù)塊包含所有命令所需要的信息(密碼設(shè)置模式、PWD內(nèi)容和上鎖/解鎖指示)。在發(fā)送卡的上鎖/解鎖命令之前,命令數(shù)據(jù)塊的長(zhǎng)度由 SDIO 卡主機(jī)模塊定義,命令結(jié)構(gòu)示于表 110。
位的設(shè)置如下:
?ERASE:設(shè)置該位將執(zhí)行強(qiáng)制擦除,所有其它位必須為 0,只發(fā)送命令字節(jié)。
?LOCK_UNLOCK:設(shè)置該位鎖住卡,LOCK_UNLOCK 與 SET_PWD 可以同時(shí)設(shè)置,但不能與CLR_PWD 同時(shí)設(shè)置。
?CLR_PWD:設(shè)置該位清除密碼數(shù)據(jù)。
?SET_PWD:設(shè)置該位將密碼數(shù)據(jù)保存至存儲(chǔ)器。
?PWD_LEN:以字節(jié)為單位定義密碼的長(zhǎng)度。
?PWD:密碼(依不同的命令,新的密碼或正在使用的密碼)
以下幾節(jié)列出了設(shè)置/清除密碼、上鎖/解鎖和強(qiáng)制擦除的命令序列。
設(shè)置密碼
1. 選擇一個(gè)卡(SELECT/DESELECT_CARD,CMD7)。
2. 定義要在 8 位的卡上鎖/解鎖模式下發(fā)送的數(shù)據(jù)塊長(zhǎng)度(SET_BLOCKLEN,CMD16),8 位的PWD_LEN,新密碼的字節(jié)數(shù)目。當(dāng)更換了密碼后,發(fā)送命令的數(shù)據(jù)塊長(zhǎng)度必須同時(shí)考慮新舊密碼的長(zhǎng)度。
3. 以合適的數(shù)據(jù)塊長(zhǎng)度在數(shù)據(jù)線上發(fā)送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數(shù)據(jù)塊包含了操作模式(SET_PWD=1)、長(zhǎng)度(PWD_LEN)和密碼(PWD)。當(dāng)更換了密碼后,長(zhǎng)度數(shù)值(PWD_LEN)包含了新舊兩個(gè)密碼的長(zhǎng)度,PWD 域包含了舊的密碼(正在使用的)和新的密碼。
4. 當(dāng)舊的密碼匹配后,新的密碼和它的長(zhǎng)度被分別存儲(chǔ)在 PWD 和 PWD_LEN 域。如果送出的舊密碼與期望的密碼(長(zhǎng)度或內(nèi)容)不吻合,則設(shè)置狀態(tài)寄存器中的 LOCK_UNLOCK_FAILED 錯(cuò)誤位,同時(shí)密碼不變。密碼長(zhǎng)度域(PWD_LEN)指示當(dāng)前是否設(shè)置了密碼,如果該域?yàn)榉橇悖瑒t表示使用了密碼,卡在上電時(shí)自動(dòng)上鎖。在不斷電的情況下,如果設(shè)置了密碼,可以通過設(shè)置 LOCK_UNLOCK 位或發(fā)送一個(gè)額外的上鎖命令,立即鎖住卡。
清除密碼
1. 選擇一個(gè)卡(SELECT/DESELECT_CARD,CMD7)。
2. 定義要在 8 位的卡上鎖/解鎖模式下發(fā)送的數(shù)據(jù)塊長(zhǎng)度(SET_BLOCKLEN,CMD16),8 位的PWD_LEN,當(dāng)前使用密碼的字節(jié)數(shù)目。
3. 當(dāng)密碼匹配后,PWD 域被清除同時(shí) PWD_LEN 被設(shè)為 0。如果送出的密碼與期望的密碼(長(zhǎng)度或內(nèi)容)不吻合,則設(shè)置狀態(tài)寄存器中的 LOCK_UNLOCK_FAILED 錯(cuò)誤位,同時(shí)密碼不變。
卡上鎖
1. 選擇一個(gè)卡(SELECT/DESELECT_CARD,CMD7)
2. 定義要在 8 位的卡上鎖/解鎖模式(見表 110 的字節(jié) 0)下發(fā)送的數(shù)據(jù)塊長(zhǎng)度(SET_BLOCKLEN,CMD16),8 位的 PWD_LEN,和當(dāng)前密碼的字節(jié)數(shù)目。
3. 以合適的數(shù)據(jù)塊長(zhǎng)度在數(shù)據(jù)線上發(fā)送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數(shù)據(jù)塊包含了操作模式(LOCK_UNLOCK=1)、長(zhǎng)度(PWD_LEN)和密碼(PWD)。
4. 當(dāng)密碼匹配后,卡被上鎖并則設(shè)置狀態(tài)寄存器中的 CARD_IS_LOCKED 狀態(tài)位。如果送出的密碼與期望的密碼(長(zhǎng)度或內(nèi)容)不吻合,則設(shè)置狀態(tài)寄存器中的 LOCK_UNLOCK_FAILED 錯(cuò)誤位,同時(shí)上鎖操作失敗。設(shè)置密碼和為卡上鎖可以在同一個(gè)操作序列中進(jìn)行,此時(shí) SDIO 卡主機(jī)模塊按照前述的步驟設(shè)置密碼,但在發(fā)送新密碼命令的第 3 步需要設(shè)置 LOCK_UNLOCK 位。如果曾經(jīng)設(shè)置過密碼(PWD_LEN 不為 0),卡會(huì)在上電復(fù)位時(shí)自動(dòng)地上鎖。對(duì)已經(jīng)上鎖的卡執(zhí)行上鎖操作或?qū)]有密碼的卡執(zhí)行上鎖操作會(huì)導(dǎo)致失敗,并設(shè)置狀態(tài)寄存器中的LOCK_UNLOCK_FAILED 錯(cuò)誤位。
卡解鎖
1. 選擇一個(gè)卡(SELECT/DESELECT_CARD,CMD7)
2. 定義要在 8 位的卡上鎖/解鎖模式下發(fā)送的數(shù)據(jù)塊長(zhǎng)度(SET_BLOCKLEN,CMD16),8 位的 PWD_LEN,和當(dāng)前密碼的字節(jié)數(shù)目。
3. 以合適的數(shù)據(jù)塊長(zhǎng)度在數(shù)據(jù)線上發(fā)送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數(shù)據(jù)塊包含了操作模式(LOCK_UNLOCK=0)、長(zhǎng)度(PWD_LEN)和密碼(PWD)。
4. 當(dāng)密碼匹配后,卡鎖被解除,同時(shí)狀態(tài)寄存器中的 CARD_IS_LOCKED 位被清除。如果送出的密碼與期望的密碼(長(zhǎng)度或內(nèi)容)不吻合,則設(shè)置狀態(tài)寄存器中的 LOCK_UNLOCK_FAILED 錯(cuò)誤位,同時(shí)卡仍保持上鎖狀態(tài)。解鎖狀態(tài)只在當(dāng)前的供電過程中有效,只要不清除 PWD 域,下次上電后卡會(huì)被自動(dòng)上鎖。試圖對(duì)
已經(jīng)解了鎖的卡執(zhí)行解鎖操作會(huì)導(dǎo)致操作失敗,并設(shè)置狀態(tài)寄存器中的 LOCK_UNLOCK_FAILED 錯(cuò)誤位。
強(qiáng)制擦除
如果用戶忘記了密碼(PWD 的內(nèi)容),可以在清除卡中的所有內(nèi)容后使用卡。強(qiáng)制擦除操作擦除所
有卡中的數(shù)據(jù)和密碼。
1. 選擇一個(gè)卡(SELECT/DESELECT_CARD,CMD7)
2. 設(shè)置發(fā)送的數(shù)據(jù)塊長(zhǎng)度(SET_BLOCKLEN,CMD16)為 1,僅發(fā)送 8 位的卡上鎖/解鎖字節(jié)。
3. 以合適的數(shù)據(jù)塊長(zhǎng)度在數(shù)據(jù)線上發(fā)送 LOCK/UNLOCK(CMD42)命令,并包含 16 位的 CRC 碼。數(shù)據(jù)塊包含了操作模式(ERASE=1)所有其它位為 0。
當(dāng) ERASE 位是數(shù)據(jù)域中僅有的位時(shí),卡中的所有內(nèi)容將被擦除,包括 PWD 和 PWD_LEN 域,同時(shí)卡不再被上鎖。如果有任何其它位不為 0,則設(shè)置狀態(tài)寄存器中的LOCK_UNLOCK_FAILED 錯(cuò)誤位,卡中的數(shù)據(jù)保持不變,同時(shí)卡仍保持上鎖狀態(tài)。試圖對(duì)已經(jīng)解了鎖的卡執(zhí)行擦除操作會(huì)導(dǎo)致操作失敗,并設(shè)置狀態(tài)寄存器中的LOCK_UNLOCK_FAILED 錯(cuò)誤位。
5 例程設(shè)計(jì)
5.1 SDIO_SDCardFatfs
該程序通過清晰的模塊化設(shè)計(jì),實(shí)現(xiàn)了對(duì) SD 卡 FATFS 文件系統(tǒng)的全面測(cè)試,適用于嵌入式系統(tǒng)存儲(chǔ)功能驗(yàn)證和教學(xué)演示。
程序功能概述
1.硬件初始化
?系統(tǒng)時(shí)鐘、延時(shí)函數(shù)、串口(UART1)初始化。
?SD卡通過SDIO接口初始化,支持FATFS文件系統(tǒng)。
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),執(zhí)行對(duì)應(yīng)操作:
?基礎(chǔ)文件操作測(cè)試(創(chuàng)建文件、讀寫數(shù)據(jù))。
?大數(shù)據(jù)讀寫性能測(cè)試(2MB文件)。
?顯示SD卡根目錄內(nèi)容。
?創(chuàng)建多級(jí)目錄(/Dir1, /Dir1/Dir1_1, /Dir2)。
?刪除目錄及測(cè)試文件。
3.關(guān)鍵函數(shù)
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():掛載文件系統(tǒng),格式化(若需要),測(cè)試文件讀寫。
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():寫入大量數(shù)據(jù)測(cè)試性能。
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():目錄創(chuàng)建與刪除。
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():顯示根目錄內(nèi)容。
關(guān)鍵代碼分析:
1.文件系統(tǒng)初始化與掛載
res_sd = f_mount(&fs, "0:", 1);
?掛載SD卡(邏輯驅(qū)動(dòng)號(hào)0:),失敗時(shí)嘗試格式化(f_mkfs)。
2.文件讀寫操作
?創(chuàng)建/打開文件:f_open使用FA_OPEN_ALWAYS模式,若文件不存在則創(chuàng)建。
?寫入數(shù)據(jù):f_write將緩沖區(qū)數(shù)據(jù)寫入文件。
?讀取數(shù)據(jù):f_read從文件讀取數(shù)據(jù)到緩沖區(qū)。
3.目錄操作
?創(chuàng)建目錄:f_mkdir創(chuàng)建目錄,處理已存在情況(FR_EXIST)。
?刪除目錄/文件:f_unlink刪除文件或空目錄(非空目錄需遞歸刪除)。
6 下載驗(yàn)證
6.1 SDIO_SDCardFatfs
命令1:基礎(chǔ)文件測(cè)試(FatfsTest):
命令2:大數(shù)據(jù)讀寫測(cè)試(FatfsBigDataTest):
命令3:查看根目錄(ViewRootDir):
命令4:創(chuàng)建目錄(CreateDir):
命令5:刪除目錄與文件(DeleteDirFile):
WIZnet 是一家無晶圓廠半導(dǎo)體公司,成立于 1998 年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨(dú)特的專利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營銷。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
單片機(jī)
+關(guān)注
關(guān)注
6063文章
44915瀏覽量
646824 -
SDIO
+關(guān)注
關(guān)注
2文章
74瀏覽量
19756
發(fā)布評(píng)論請(qǐng)先 登錄
有哪位仁兄做了nios控制ds18b20顯示在12864上,求指教!!!
明德?lián)P視頻分享點(diǎn)撥FPGA課程--第二十一章 ?矩陣鍵盤工程
第二十一講 組合邏輯電路中的競(jìng)爭(zhēng)冒險(xiǎn)

模擬電路網(wǎng)絡(luò)課件 第二十一節(jié):場(chǎng)效應(yīng)管與BJT放大電路的比較

第二十一屆中國西部國際投資貿(mào)易洽談會(huì)開幕 全方位展示工業(yè)4.0以來最新科技成果
西安高新第二十一小學(xué)能耗監(jiān)測(cè)及電力監(jiān)控系統(tǒng)的研究與應(yīng)用

獲雙項(xiàng)榮譽(yù):中科智云受邀出席第二十一屆中國科學(xué)家論壇
【節(jié)能學(xué)院】西安高新第二十一小學(xué)能耗監(jiān)測(cè)及電力監(jiān)控系統(tǒng)的研究與應(yīng)用

第二十一屆電感變壓器產(chǎn)業(yè)峰會(huì)正式啟動(dòng)!

圖撲軟件亮相第二十一屆中國·海峽創(chuàng)新項(xiàng)目成果交易會(huì)

展會(huì)邀請(qǐng)函 | 羅克韋爾自動(dòng)化邀您共聚第二十一屆中國國際橡膠技術(shù)展覽會(huì)

閃耀灣區(qū),諾安智能獲評(píng)第二十一屆“深圳知名品牌(灣區(qū)知名品牌)”稱號(hào)

2024第二十一屆(上海)國際物聯(lián)網(wǎng)展覽會(huì)4月24日-26日開幕

第二十一屆亞太智能建筑論壇精彩回顧

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

評(píng)論