SDIO接口的理解

運用SD卡第一步,認識SDIO接口

做畢業設計需要用到大量的音頻文件,一般的存儲器滿足不了存儲要求,故選擇SD卡作爲存儲器件。在這裏記錄一下自己的學習經歷,學習一個新的IC,無非是要麼根據時序圖寫出Read和Write函數,要麼是根據通信總線和IC相關操作指令去完成Read和Write函數。只有能與對應IC“說話”,我們才能去開發它更多地可能性。這裏以原子探索者爲例,爲大家介紹一下SD卡相關知識。

簡要的介紹一下什麼是SDIO接口

SDIO------>安全數字輸入輸出接口。它是在SD卡接口基礎上發展而來。
SDIO 和 SD卡規範間的一個重要的區別是增加了低速標準,低速卡的目標應用是以最小硬件開支支持低速I/O能力,低速卡支持類似調制解調器,條碼掃描儀和GPS接收器等應用。STM32的SDIO控制器支持多媒體卡(MMC卡)、SD存儲卡、SD I/O卡和CE-ATA設備。

其特點我們直接上圖:
在這裏插入圖片描述
我們可以看到SDIO接口具有向前兼容的特點,支持多種多個版本的存儲卡。在高位總線模式下,也同樣具有優秀的讀取速度。

stm32內核自帶了SDIO適配器,下面上框圖(手冊自帶):
在這裏插入圖片描述
根據框圖我們可以看到SDIO適配器的時鐘與PCLK2和SDIOCLK有關,SDIO適配器的控制與SDIO_CK和SDIO_CMD有關,其數據的傳輸又與SDIO_D[7:0]有關(最高可以配置8位數據總線寬度)。復位情況下,SDIO_D0用於數據傳輸,初始化後主機可以改變數據總線的寬度通過(ACMD6命令設置)。

SDIO與外圍設備的命令與響應均是通過SDIO_CMD來完成的。這裏我們可以調用SDIO_SendCommand()這個庫函數,用來通過SDIO總線的SDIO_CMD以SDIO_CK這樣的頻率,對外圍設備如SD卡發送CMD命令,並且可以獲取響應數據。

那麼問題來了,這個SDIO_CK到底是怎麼計算的呢?話不多說,我們接着上圖:
在這裏插入圖片描述在這裏插入圖片描述
通過上圖我們可以得出,SDIO時鐘計算公式:SDIO_CK時鐘=SDIOCLK/[clkdiv+2];其中,SDIOCLK固定爲48Mhz。那麼我們只要配置clkdiv這個位,就能夠完成對SDIO_CK的配置。clkdiv這個位在SDIO初始化函數裏即可進行配置,下面上代碼:

  SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;	/* HCLK = 72MHz, SDIOCLK = 72MHz, SDIO_CK = HCLK/(178 + 2) = 400 KHz */
  SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
  SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;  //不使用bypass模式,直接用HCLK進行分頻得到SDIO_CK
  SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;	// 空閒時不關閉時鐘電源
  SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;	 				//1位數據線
  SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;//硬件流
  SDIO_Init(&SDIO_InitStructure);

這裏SDIO_INIT_CLK_DIV = 0x76,計算一下就可以知道SDIO_CK的時鐘爲400KHz,數據寬度爲1位。看到這裏大家能可會問,這麼慢的頻率,這麼短的數據傳輸位數,傳輸的效率能高嗎?其實這裏對SD卡的初始化只是爲了激活SD卡,開啓SDIO總線與SD卡之間的通信。真正的初始化需要一大串命令。

初始化完以後我們需要使能SDIO_CK這個時鐘,SDIO->CLKCR|=1<<8; 這個寄存器我們後面再說。

SD卡與SDIO的接口

說完了SDIO接口,我們再說說這個接口需要操作的外圍設備,SD卡。隨便在網上買了個4GB的SD卡,大概長這個樣子:
在這裏插入圖片描述
這種SD卡有9個接口,每個接口的定義如下:
在這裏插入圖片描述
一般的對於SD卡,我們的開發板上都有對應的卡槽,自己畫板子的話也很好畫,網上買個卡槽也很便宜,所以不要怕SD卡不好放置。

SDIO的命令與響應

SDIO的命令分爲:應用相關命令(ACMD)和通用命令(CMD)兩部分。發送ACMD時,需先發送CMD55。

需要注意的是,發送CMD命令只需要填充命令索引和參數即可,這兩個數據相關的寄存器
SDICARG[31:0] ----->CMD[39:8] 命令的參數(根據命令所需的參數位格式設置)
SDICCON[7:0] -----> CMD[47:40] 包含Start Bit,Transmission Bit,Command Index.
關於寄存器的操作都被封裝成了庫函數,所以我們只需要調用SDIO_SendCommand()這個庫函數,即可完成發送CMD命令的要求,這個庫函數還帶一個參數是響應類型參數,根據長響應還是短響應到對應的寄存器去尋找返回的參數。

SDIO的所有命令和響應都是在SDIO_CMD引腳上面傳輸的,命令長度固定位48位,SDIO命令格式如下表所示:
在這裏插入圖片描述
其中除了命令索引和參數需要我們設置,其他都是由SDIO硬件自動控制。命令索引(如CMD0,CMD1之類)由SDIO_CMD寄存器設置,命令參數則由SDIO_ARG寄存器設置。
一般SD卡在接收到命令行以後都會有一個應答(CMD0例外),這個應答我們也稱之爲響應。

對於stm32的SDIO接口,支持2種響應類型:短響應(48位)和長響應(136位)。
在這裏插入圖片描述
在這裏插入圖片描述
SDIO塊數據傳輸不論是短響應還是長響應,硬件都會自動濾除了起始位,傳輸位,CRC7以及結束位等信息,對於短響應,命令索引存放在SDIO_RESPCMD寄存器。參數則存放在SDIO_RESP1寄存器裏面。對於長響應,則僅留CID/CSD位域,存放在SDIO_RESP1~SDIO_RESP4等4個寄存器裏面。每個響應都有自己的響應格式(6種)。

到這裏我們其實可以給SD卡的初始化和工作流程簡要的總結一下了:
①、首先我們通過配置SDIO的初始化函數初始化SD卡,就是可以想象成把SD卡給喚醒。
②、喚醒完了以後,我們就可以通過SDIO總線,給SD卡發送命令。
③、SD卡收到命令後會反饋一個響應,我們可以通過響應的信息去獲取SD卡的各項信息,以方便我們根據信息對於SD卡做出相應的初始化操作,比如設置數據總線寬度,設置SD卡工作頻率等等。
④、無論發送命令或者接收響應,均是通過SDIO_CMD這一個位來完成的,在沒有涉及發送或者接收數據的時候,SDIO_D數據線是不參與的。

這樣一看SD卡的初始化其實就是一個端口的發送和接收,是不是感覺簡單了很多呢?

SD卡讀寫多塊數據過程

讀取多塊數據過程

在這裏插入圖片描述
在這裏插入圖片描述
怎麼說呢,就是我們發送命令,然後接收到響應的響應後通過SDIO_D數據線接收來自SD卡的數據,直到發送了STOP命令。

寫入多塊數據過程

在這裏插入圖片描述
在這裏插入圖片描述
至此,SD卡基本的初始化和讀寫信息已經介紹完畢了,SDIO總線的通信方式相信大家也很瞭解了,但是SD卡本身是一個非常複雜的存儲IC,下一篇文章我將介紹SD卡初始化和讀寫數據的詳細步驟。

發佈了7 篇原創文章 · 獲贊 5 · 訪問量 2870
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章