---
title: Flash 記憶體的原理與應用—PART21
description: "**作者：Bird** 上一回 [【Maker電子學】Flash 記憶體的原理與…"
url: "https://makerpro.cc/docs/flash-memory-principle-and-application-part21/"
updated: "2025-03-31"
category: Flash記憶體
---

# Flash 記憶體的原理與應用—PART21

**作者：Bird**

上一回 [【Maker電子學】Flash 記憶體的原理與應用—PART20](https://makerpro.cc/2025/01/flash-memory-principle-and-application-part20/)，我們簡單說明了 SD 卡初始化後，利用一些指令組合來辨認卡片的容量、電壓、版本等特性的流程，這一回我們要來介紹讀取 SD 卡內容的方法。

### **暫存器**

在說明 SD 卡的資料讀取程序前，我們先來講一下 SD 裡的暫存器。

所有的 SD 卡都有一組長度不等的暫存器，用來指示卡片的功能、狀態，我們上一回提到的 CSD（card specific data）就是其中一個暫存器。這些暫存器總有：

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213401.png)

（圖片來源：Bird 提供）

之後有用到相關的暫存器時，我們會再詳細說明它們的內容和用途，現在先讓我們繼續看看資料的讀取。

### **資料讀取指令**

我們已經在前幾回的模式切換、卡片辨認程序中，用過幾次 SD 卡的指令，指令格式是這樣：

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213415.png)

（圖片來源：Bird 提供）

在 SD 卡的世界中，這樣一個 48-bit 包含完整指令碼、參數、CRC 的格式，稱之為一個 token。而資料的傳輸則會在指令 token 之外發生，以一種叫做「packet」的單位進行。

之所以會分為 command token 或 data packet，是因為在 SD 模式下，command token 是在 CMD 腳上傳輸，而 data packet 則是在 D0-D3 腳上傳輸，但如果在 SPI 模式下，這兩者都在 SPI 的 MOSI 和 MISO 腳上傳輸。

讀取資料時的 command token 與 data packet 時序關係是這樣的：

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213425.png)

（圖片來源：Bird 提供）

SD 卡的資料讀取原則上是以 512 bytes 為單位。但在 CSD 暫存器中有一個 bit，叫做「partial block read allowed」，如果這個 bit 為 1，就表示卡片可以支援比 512 bytes 短的資料讀取，否則所有的讀取都必須要以 512 bytes 為單位，不過容量比較大的 SDHC 和 SDXC 卡片就只支援 512 bytes 的讀取了。

而讀出來的資料會利用 CCITT 標準的 CRC16 多項式 X16+X12+X5+1 計算出 16-bit 的 CRC，並附在 data packet 之後供 host 端檢查資料有沒有出錯。

讀取一個 block 的指令是 CMD17，格式如下：

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213434.png)

（圖片來源：Bird 提供）

這個指令只有一個參數，就是 32-bit 的位址，代表要讀取的資料在卡片上的位址，但 32-bit 最大只能定址到 4G bytes，對於超過 4G bytes 的卡片怎麼辦呢？其實是這樣的：如果卡片是標準的 SD，最大只支援到 2GB，這個參數的定義就是以 byte 為單位的資料位址，但如果是容量較大的 SDHC、SDXC，這個參數就是以 512 bytes 的 block 為單位，也就是說，如果是 0，就從位址 0 讀起，如果是 1，就代表從位址 512 讀起；如果是 2，就從位址 1024 讀起。

下完這個指令後，host 要持續送出 clock，接著卡片就會吐出我們之前說明過的 R1 response token。我們需要檢查 R1 response 中有沒有任何錯誤，如果沒有的話，繼續送出 clock 之後，卡片就會開始送出 data packet，以及它對應的 CRC，完成一個 block 的讀取。

### **連續讀取**

如同大部分的記憶體介面一樣，為了避免將介面的時序浪費在傳送位址，SD 介面也有連續讀取的指令：CMD18。它的格式是這樣的：

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213441.png)

（圖片來源：Bird 提供）

其實它長得跟 CMD17 一模一樣，只有指令碼不一樣。

當我們對卡片送出 CMD18 的 token 後，在 R1 response 確認沒有 error 之後，卡片就會從我們設定的讀取位址開始，源源不絕地送出 data packet，每 512 bytes 一個單位。

 ![](https://makerpro.cc/wp-content/uploads/2025/02/Screenshot-2025-02-22-213455.png)

（圖片來源：Bird 提供）

只要 host 持續送出 clock，卡片就會一個接著一個 block 地把資料送出來，直到 host 送出 CMD12 為止。CMD12 叫做「STOP_TRANSMISSION」，是個專門用來停止 multiple block 讀取的指令。

利用 CMD18 連續讀取的功能，我們可以只下一次位址，就從 SD 卡讀取大量連續的資料。

### **小結**

這一回我們說明了如何從 SD 卡中讀取資料，也說明了讀取資料的時序，以及單一 block 讀取和連續讀取的不同，下一回我們要介紹如何抹除 SD 卡上的資料、如何寫入資料（由於 flash 記憶體的擦除及寫入速度比讀取慢很多，在寫入時要做的檢查及等待會比讀取時要複雜一點）。

（責任編輯：賴佩萱）
