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

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

**作者：Bird**

上一回【Maker電子學】Flash 記憶體的原理與應用—PART22，我們說明了如何從 SD 卡中讀取資料，也說明了讀取資料的時序，以及單一 block 讀取指令 CMD17 和連續讀取指令 CMD18。

這一回我們要介紹如何抹除 SD 卡上的資料及寫入資料，由於 Flash 記憶體的擦除及寫入速度比讀取慢很多，在寫入時要做的檢查及等待會比讀取時要複雜一點。

### 抹除

我們在介紹 Flash記憶體的工作原理時，有說明過，Flash記憶體在寫入之前必須要先背抹除（erase），抹除就是把要抹除區域的所有內容變成 1，之後在寫入時，寫入電路可以將特定的儲存單元從 1 變成 0，但沒辦法將 0 變成 1（只有「抹除」這個動作可以將整區的儲存單元都從 0 變成 1）。

SD 卡的抹除動作分成三個指令：

- CMD32（ERASE_WR_BLK_START）：設定開始抹除的位址
- CMD33（ERASE_WR_BLK_END）：設定結束抹除的位址
- CMD38（ERASE）：抹！

這三個指令一定要按照上面的順序下，否則在下最後一個指令時 SD 卡會回應錯誤。

CMD32 和 CMD33 的格式是這樣的：

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

（圖片來源：Bird 提供）

它其實跟我們之前介紹的讀取指令一樣，只有一個 32-bit 的參數，代表要從哪裡到哪裡需要被抹除。和讀取指令的定義一樣，如果是標準 SD 卡，定址的單位就是 byte；如果是 SDHC、SDXC，定址的單位就是 512-byte。

設定好要抹除的範圍之後，就可以用 CMD38 將這個區域的內容抹除了。

CMD38 的格式更簡單：

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

（圖片來源：Bird 提供）

CMD38 沒有參數，那 31 個 bit 不管填什麼都沒關係。

下了這個指令之後，SD 卡裡面的控制器就會開始抹除我們所指定的位址或是 block。

但我們在說明Flash記憶體的原理時也說過，flash 記憶體的抹除和寫入是遠比讀取要花時間的，而且相對來說時間都很長，因此下完 CMD38 後，我們需要有一個方法來知道 SD 卡到底完成抹除了沒，確實完成後我們才能繼續其它的操作，比方說寫資料到這些位址。

這時我們就要用到 CMD38 的回應 token 了。CMD38 的 response 格式叫做 R1b，基本上跟 R1 response 一樣，但如果卡片還在忙碌的話，R1b response 會把 MISO 接腳拉低，直到卡片結束忙碌，因此 host 可以一直送出 clock，一直偵測 MISO 的狀態。如果 MOSI 一直是 0，就代表卡片還在努力 erase，請再等等，一旦讀到的資料有非 0 的結果，就代表卡片已經忙完了，可以繼續下一個指令了。

Erase 指令在 SPI 模式下的時序大概是這樣：

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

（圖片來源：Bird 提供）

Flash 記憶體抹除時，是利用相對來說較強的電場迫使浮動閘極裡的電子離開，至於能不能成功迫使足夠的電子離開，讓電晶體的狀態變回 1，則要在抹除完之後讀讀看才知道；如果失敗，就再抹一次，直到整個要抹除的區域裡的內容都變成 1 為止。

隨著Flash記憶體使用時間愈來越長、壽命越來越短，抹除的動作會越來越困難，可能每一個 block 都需要多次的電晶體操作動作才能讓全部的內容都變成 1，因此隨著 SD 卡的使用次數漸增，抹除所需要的時間會越來越長，這時我們在 R1b response 等待的時間就會越來越長。

### **寫入**

抹除之後，我們就可以寫資料到 SD 卡裡面了。

寫入跟讀取一樣，也分成單一 block 的寫入以及連續 block 的寫入，分別是：

- CMD24（WRITE_BLOCK）：單一 block 寫入
- CMD25（WRITE_MULTIPLE_BLOCK）：連續 blocks 寫入

這兩個指令的格式也一樣：

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

（圖片來源：Bird 提供）

寫入的位址定義跟讀取一樣，對標準 SD 來說單位是 byte，對 SDHC、SDXC 來說單位是 512 bytes。

送往這個指令後，SD 卡會回應 R1 response。如同我們已經很熟悉的其它指令，R1 response 最好裡面都不要有 1，不然就是哪裡出了錯。

接下來，host 就可以送出要寫入的資料。在每一包資料前面有一個叫做 data marker 的記號，也叫做 start block token，它其實就是一個內容為 0xFE 的 byte，隨後就是 512 bytes 的資料。

送完資料之後，卡片會送出一個叫 data response 的回應，這是一個 1 byte 的 token，它有幾個不同的可能：

- 0b00000101 - 資料正確
- 0b00001011 - CRC 檢查錯誤
- 0b00001101 - 資料不被接受，可能是其它錯誤導致

只有當 data response token 的值是 0x05 時，才代表卡片收到資料，可以開始寫入了。

當寫入過程進行時，SD 卡會把 MISO 接腳拉低，因此我們只要持續送出 SPI clock，讀取 MISO 的狀態，就可以知道寫入完成沒。

整體的時序是這樣：

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

（圖片來源：Bird 提供）

而連續寫入的指令 CMD25，則是允許我們在 data response token 的 busy 結束後，繼續送出 data block。如果我們要結束連續寫入，可以在即將傳送新的一個 block 時，傳送一個叫做「Stop Tran」的 token，它也是 1 個 byte 的 token，值是 0xFD，當卡片收到這個 token，就會結束連續寫入的指令。

連續寫入的指令在每一個 data block 送出後，都要檢查 data response 及 busy 的狀態，等待卡片處理完一個 block 的寫入，才可以繼續送出下一個 block。

### **小結**

這一回，我們介紹了 SD 卡的抹除及寫入的指令，以及使用這些指令相關的程序。

其實 SD 卡的操作非常複雜，官方規格書中所定義的操作比起我們這裡能說明的，多上不只十倍，而且由於 SD 卡的標準經過多年的演進、迭代，光是不同卡片對各種指令的支援，就有非常多的差異，我們在這裡只能很簡單的利用幾個最重要的例子，讓讀者們了解 SD 卡最基本的運作，對細節有興趣的讀者，可以去 SD Association 的官網下載規格書，該單位還很貼心準備了簡化版（simplified）的各種規格，讓想了解 SD 卡但不用製造或設計它的人，可以快速了解 SD 卡的規範。

下一回會是介紹 SD 卡的最後一回，我們要補充一些前面沒有說明的特性。

（責任編輯：賴佩萱）
