2011年5月2日 星期一

SD Card Driver Design (Read & Write)

經過重重關卡, 爬過千山萬嶺
終於將SD Card的初始化搞定了
接下來就可以對SD Card進行資料的讀寫囉
不過在這之前呢
還有一件非常重要的事情要做
如果不做
就算你的SD Card是class 10的速度
也發揮不出來喔

先回顧SD Card Driver Designe (init.)這篇裡面的一句話:
而在初始化的過程中
SPI的CLK不能超過400KHz
所以要先將SPI的設定低於400KHz
是的
還記得嗎
我們的SPI clock是設定在低於400KHz的情況下運作
這樣的速度會讓你在對SD Card進行讀寫時
感到有如早上八點從竹北往竹科的經國大橋上一樣
(說這麼多還不就是要說塞車嘛...)
因此在進行讀寫之前呢
記得要把SPI clock調到最快喔
(至於最快是多少? 坦白說看各個IC本身的SPI Module囉...)

將速度重新設定完畢後
接著介紹SD Card中幾個強大的功能: 讀和寫
(哪個記憶體不是讀和寫...= =)

介紹前先來看一下SD卡的資料傳輸格式吧

data.png

Command

Description

CMD17 READ_SINGLE_BLOCK
CMD18 READ_MULTIPLE_BLOCK
CMD24 WRITE_BLOCK
CMD25 WRITE_MULTIPLE_BLOCK

在SD卡的傳輸過程中, 是以block做為定址單位的
也就是說, 不管你的資料有多少個byte
不足一個block的量, 仍是以一個block來傳輸
在資料傳輸方式上, 分為single block與multiple block
一般而言, 一個block的大小為512 byte
當然你也可以利用SD Card command來設定block大小(CMD16, SET_BLOCKLEN)
不過都會建議設成512 byte
因為這樣比較符合檔案系統上的設定(這點有待商榷)

  • Single Block Read
    rs.png
  • Single Block Write
    ws.png
  • Multiple Block Read
    rm.png
  • Multiple Block Write
  • wm.png

以上為SD卡的四種傳輸方式
而指令所使用的方式也跟先前初始化時差不多
因此這次就不另行解說
但這次會將完整的SD卡驅動程式附加在blog裡面
各位可以自行參考及修改

另外要提的一點是
關於erase(清除)這個功能的用法
在SD SPEC中是有這個指令可以使用的(CMD32, CMD33, CMD38)
但要注意的是
這裡所謂的"清除", 並不是將資料清為"0x00"
而是將它清成"0xFF"
這個特性是因為SD卡的本質是Flash
當然也是可以使用指令將它erase成0x00
(只是我一時找不到, 但我曾經看過...= =)

寫到這裡, SD Card driver也介紹告一段落
若是各位看倌仍是意猶未盡
那就靜待下一回新單元: SD卡的應用

SD Card Driver下載

10 則留言:

宇傑 提到...
作者已經移除這則留言。
匿名 提到...

您好,
我現在也是正在用SPI做SD Card Driver的design,看了您詳細的介紹之後,真的收穫很多.看過您的code之後,我想請問一下,code裡一些關於SPI資料傳輸和CS設定的部分,是可以依照個人所使用的mcu的SPI寫法去補上就能動作嗎?另外,不知道是否可以請問一下您是用哪顆mcu?如果剛好相同或是類似,希望能再請教您一些相關問題.謝謝您:)

Unknown 提到...

您好:
非常感謝你對本人文章的肯定
關於SPI的部分, 你可以用兩種方式來實現
一個是MCU本身的SPI module
另一個是用io pin去模擬SPI的訊號
我所使用的MCU是公司自行研發的
但它內部的核心仍是以標準的8051為主
而在本文中所討論的SPI
是在MCU中已經有內建了
所以只有對SPI的REG填值而已
不知道您是使用哪個MCU
基本上我目前使用過的有silicon lab和
還有ARM9 S3C2410

Unknown 提到...

至於您所提到的CS設定
是我拉一隻空的IO PIN去當CS訊號用
基本上如果您要porting這個code
到你自己所使用的MCU
你只需要注意所使用的那顆MCU
內部的SPI暫存器怎麼填值就可以了
當然, 先決條件是
你的MCU必須內建SPI module
如果沒有, 就要麻煩點
用IO PORT自己產生SPI的訊號了...

匿名 提到...

我目前使用的是Renesas的RX62T,它本身有內建SPI的module,所以我是可以像您說的去填各register的值就好,但因為我是用full-duplex的方式在傳送資料,而且我對於傳送的資料的格式不是很清楚(看過datasheet還是不太懂...),所以不僅會產生overrun的error,也不知道怎麼送指令給SD card並接收回應.看過您的程式後,是大概知道大架構了,只是在data transfer和receive的function上依然不太清楚,才會想說如果您有用過這顆mcu的話,想跟您請教一下

Unknown 提到...

看樣子你的SD卡初始化應該沒有成功吧
如果有成功的話, 接下來的指令應該都很好操作
若初始化有成功, 只是像你說的
卡在data transfer的部分
你可以直接把我的code po上來
把你不懂的地方直接問
我覺得這樣會比較快能解決你的問題
(我承認這篇是我偷懶, 才沒解釋code的= =)

匿名 提到...

嗯嗯,我晚點會試著將我的code和你的做結合並測試,結果如何我會再跟你說.另外,不知道是否方便跟您拿e-mail,這樣子討論比較發便,也不會把您文章的版面用得很亂,謝謝

Unknown 提到...

roger7313@gmail.com
歡迎討論

匿名 提到...

版主你好.
我想問的問題是, 直接使用FPGA對SD card做控制是否可行,它會比用MCU控制來的難寫嗎?版主是否有經驗?

Unknown 提到...

您好,我最近在學習使用SPI讀寫SD Card,看到您的文章覺得很有幫助,不過有許多圖片的連結皆已失效,不知是否有流原始文章可以提供給我參考呢? 麻煩了,謝謝!

lalilata888@hotmail.com