開發板購買鏈接
https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674
開發板簡介
開發環境搭建 windows
原始碼示例:
0_Hello Bug (ESP_LOGX與printf) 工程模板/列印除錯輸出
1_LED LED亮滅控制
2_LED_Task 使用任務方式控制LED
3_LEDC_PWM 使用LEDC來控制LED實作呼吸燈效果
4_ADC_LightR 使用ADC讀取光敏電阻實作光照傳感
5_KEY_Short_Long 按鈕長按短按實作
6_TouchPad_Interrupt 電容觸摸中斷實作
7_WS2812_RMT RGB_LED彩虹變色示例
8_DHT11_RMT 使用RMT實作讀取DHT11溫濕度傳感器
9_SPI_SDCard 使用SPI總線實作TF卡檔案系統示例
10_IIC_ADXL345 使用IIC總線實作讀取ADXL345角度加速度傳感器
11_IIC_AT24C02 使用IIC總線實作小容量資料儲存測驗
12_IR_Rev_RMT 使用RMT實作紅外遙控接收掃碼(NEC)
13_IR_Send_RMT 使用RMT實作紅外資料發送(NEC)
14_WIFI_Scan 附近WIFI信號掃描示例
15_WIFI_AP 創建軟AP示例
16_WIFI_AP_TCP_Server 在軟AP模式下實作TCP服務端
17_WIFI_AP_TCP_Client 在軟AP模式下實作TCP客戶端
18_WIFI_AP_UDP 在軟AP模式下實作UDP通訊
19_WIFI_STA 創建STA站模
20_WIFI_STA_TCP_Server 在站模式STA下實作TCP服務端
21_WIFI_STA_TCP_Client 在站模式STA下實作TCP客戶端
22_WIFI_STA_UDP 在站模式STA下實作UDP通訊
23_LVGL_Test LVGL圖形庫簡單示例
Micro SD Card,原名Trans-flash Card(TF卡),2004年正式更名為Micro SD Card,由SanDisk(閃迪)公司發明,主要用于移動電話,
在Micro SD面市之前,手機制造商都采用嵌入式記憶體,雖然這類模組容易裝設,然而有著無法應實際應潮流需求的困擾——容量被限制住了,無法再有升級空間,Micro SD仿效SIM卡的應用模式,即是同一張卡可以應用在不同型號的行動電話內,讓行動電話制造商不用再為插卡式的研發設計而傷腦筋, Micro SD卡足以堪稱可移動式的儲存IC,
Micro SD卡是一種極細小的快閃存盤器卡,其格式源自SanDisk創造,原本這種記憶卡稱為T-Flash,及后改稱為Trans Flash;而重新命名為Micro SD的原因是因為被SD協會 (SDA) 采立,另一些被SDA采立的記憶卡包括Mini SD和SD卡,其主要應用于移動電話,但因它的體積微小和儲存容量的不斷提高,已經使用于GPS設備、便攜式音樂播放器和一些快閃存盤器盤中,它的體積為 15mm x 11mm x1mm ,差不多相等于手指甲的大小,是現時最細小的記憶卡,它也能通過SD轉接卡來接駁于SD卡插槽中使用, 現時MicroSD卡提供128MB、256MB、512MB、1G、2G、4G、8G、16G、32G、64G、128G的容量(MWC 2014 世界移動通信大會期間,SanDisk(閃迪)打破了儲存卡最高64GB容量的傳統,正式發布了一款容量高達128GB的 Micro SD XC 儲存卡,
SD卡的操作模式:SD卡模式(SDIO)、SPI模式(默認為SD模式),
其中SD卡模式的信號線有:CLK、CMD、DAT0-DAT3,6根線,
SPI模式的信號線有:CS、CLK、MISO(DATAOUT)、MOSI(DATAIN),4根線,

- CLK 時鐘同步線
- CMD 命令信號線,主機發出的命令以及從機對命令的回應都是通過這條線進行傳輸
- DAT[3:0] 表示4條資料線,主機和從機的資料都是從這四條資料線上傳輸

SD卡只能使用3.3V的I/O電平,SPI模式下信號線要加10-100K的上拉電阻,
SD卡有五個暫存器:
| 名稱 | 寬度 | 描述 |
|---|---|---|
| CID | 128 | 卡標識暫存器 |
| RCA | 16 | 相對地址暫存器(Relative Card Address):本地系統中卡的地址,動態變化,在主機初始化的時候確定,SPI模式中沒有, |
| CSD | 128 | 卡描述資料:卡操作條件相關的資訊資料 |
| SCR | 64 | SD配置暫存器:SD卡特定資訊資料 |
| OCR | 32 | 操作條件暫存器 |
SD卡的命令格式:
命令CMD0就是0,CMD16就是16,以此類推,
SPI命令格式為6位元組構成,高位在前(MSB),
| 位元組1 | 位元組2-5 | 位元組6 |
|---|---|---|
| 7 | 6 | 5-0 |
| 0 | 1 | command |
位元組1的最高2位固定是01,低6位為命令號(CMD0就是0,CMD16就是16,以此類推),位元組2-5為命令引數,有些命令是沒有引數的;位元組6的高7位為CRC,最低位恒為1,
SD卡的命令總共有12類,下表為幾個比較重要的命令:
SD卡的主要相關各種命令決議
CMD0: SD卡進入IDLE和復位SD卡
CMD1: 讀OCR,是否為SD卡
CMD2: 獲取卡CID資訊
CMD3: 獲取SD卡所分配的相對地址
CMD9: 獲取SD卡的存盤資訊(容量、塊大小等)
CMD12:停止傳輸操作
CMD13:獲取卡的狀態
CMD16:設定SD卡塊大小
CMD17:使SD卡進入傳輸狀態、讀取單個塊
CMD18: 使SD卡進入傳輸狀態、讀取多個塊,直到收到CMD12為止
CMD24:使SD卡進入傳輸狀態、寫入單個塊
CMD25: 使SD卡進入傳輸狀態、寫入多個塊
| 命令 | 引數 | 回應 | 描述 |
|---|---|---|---|
| CMD0(0X00) | NONE | R1 | 復位SD卡 |
| CMD8(0X08) | VHS+Check Pattern | R7 | 發送介面狀態命令 |
| CMD9(0X09) | NONE | R1 | 讀取卡特定資料暫存器 |
| CMD10(0X0A) | NONE | R1 | 讀取卡標志資料暫存器 |
| CMD16(0X10) | 塊大小 | R1 | 設定塊大小(位元組數) |
| CMD17(0X11) | 地址 | R1 | 讀取一個塊的資料 |
| CMD24(0X18) | 地址 | R1 | 寫入一個塊的資料 |
| CMD41(0X29) | NONE | R3 | 發送給主機容量支持資訊和激活卡初始化程序 |
| CMD55(0X37) | NONE | R1 | 告訴SD卡,下一個是特定應用命令 |
| CMD58(0X3A) | NONE | R3 | 讀取OCR暫存器 |
SD卡和單片機的通信采用發送應答機制:

ESP32 FAT 檔案系統
ESP-IDF 使用 FatFs 庫來實作 FAT 檔案系統,FatFs 庫位于 fatfs 組件中,您可以直接使用,也可以借助 C 標準庫和 POSIX API 通過 VFS(虛擬檔案系統)使用 FatFs 庫的大多數功能,
此外,對 FatFs 庫進行了擴展,新增了支持可插拔磁盤 I/O 調度層,從而允許在運行時將 FatFs 驅動映射到物理磁盤,
FatFs 與 VFS 配合使用
函式 esp_vfs_fat_register() 分配一個 FATFS 結構,并在 VFS 中注冊特定路徑前綴,如果檔案路徑以此前綴開頭,則對此檔案的后續操作將轉至 FatFs API,函式 esp_vfs_fat_unregister_path() 洗掉在 VFS 中的注冊,并釋放 FATFS 結構,
多數應用程式在使用 esp_vfs_fat_ 函式時,采用如下步驟:
呼叫 esp_vfs_fat_register(),指定:
掛載檔案系統的路徑前綴(例如,"/sdcard" 或 "/spiflash")
FatFs 驅動編號
一個用于接收指向 FATFS 結構指標的變數
呼叫 ff_diskio_register() 為上述步驟中的驅動編號注冊磁盤 I/O 驅動;
呼叫 FatFs 函式 f_mount,或 f_fdisk, f_mkfs,并使用與傳遞到 esp_vfs_fat_register() 相同的驅動編號掛載檔案系統,請參考 FatFs 檔案,
呼叫 C 標準庫和 POSIX API 對路徑中帶有步驟 1 中所述前綴的檔案(例如,"/sdcard/hello.txt")執行打開、讀取、寫入、擦除、復制等操作,
您可以選擇直接呼叫 FatFs 庫函式,但需要使用沒有 VFS 前綴的路徑(例如,"/hello.txt");
關閉所有打開的檔案;
呼叫 f_mount 并使用 NULL FATFS* 引數為與上述編號相同的驅動卸載檔案系統;
呼叫 FatFs 函式 ff_diskio_register() 并使用 NULL ff_diskio_impl_t* 引數和相同的驅動編號來釋放注冊的磁盤 I/O 驅動,
呼叫 esp_vfs_fat_unregister_path() 并使用檔案系統掛載的路徑將 FatFs 從 NVS 中移除,并釋放步驟 1 中分配的 FatFs 結構,
esp_vfs_fat_sdmmc_mount 和 esp_vfs_fat_sdmmc_unmount 這兩個便捷函式對上述步驟進行了封裝,并加入對 SD 卡初始化的處理,非常便捷,
一、硬體設計/原理
查看開發板原理圖,TF卡使用SPI總線連接到ESP32主控,對信號線進行10K上拉,

二、程式設計
先參考必要頭檔案
// SD card and FAT filesystem example
#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "driver/sdspi_host.h"
#include "driver/spi_common.h"
#include "sdmmc_cmd.h"
#include "sdkconfig.h"
定義SPI總線GPIO
static const char *TAG = "TF Card Fat Example";
#define MOUNT_POINT "/sdcard"
#define SPI_DMA_CHAN 1
//在測驗SD和SPI模式時,請記住,一旦在SPI模式下初始化了卡,在不接通卡電源的情況下就無法在SD模式下將其重新初始化,
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 5
主函式,測驗檔案系統,讀取,寫入、獲取總容量、卡資訊、剩余容量、更名、洗掉等操作
void app_main(void)
{
esp_err_t ret; // ESP錯誤定義
sdmmc_card_t* card; // SD / MMC卡資訊結構
const char mount_point[] = MOUNT_POINT; // 根目錄
char ReadFileBuff[64];
esp_vfs_fat_sdmmc_mount_config_t mount_config = { // 檔案系統掛載配置
.format_if_mount_failed = false, // 如果掛載失敗:true會重新磁區和格式化/false不會重新磁區和格式化
.max_files = 5, // 打開檔案最大數量
.allocation_unit_size = 16 * 1024
};
printf("%s->Initializing SD card\r\n",TAG);
printf("%s->Using SPI peripheralr\r\n",TAG);
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
spi_bus_config_t bus_cfg = {
.mosi_io_num = PIN_NUM_MOSI,
.miso_io_num = PIN_NUM_MISO,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
// SPI總線初始化
ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN);
if (ret != ESP_OK) {
printf("%s->Failed to initialize bus.\r\n",TAG);
return;
}
// 這將初始化沒有卡檢測(CD)和寫保護(WP)信號的插槽,
// 如果您的主板有這些信號,請修改slot_config.gpio_cd和slot_config.gpio_wp,
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = PIN_NUM_CS;
slot_config.host_id = host.slot;
// 掛載檔案系統
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
printf("%s->Failed to mount filesystem.%s\r\n",TAG,
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
} else {
printf("%s->Failed to initialize the card %s (%s). ",TAG,
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
return;
}
// TF卡已經初始化,列印TF卡屬性
sdmmc_card_print_info(stdout, card);
// Print FAT FS size information
size_t bytes_total, bytes_free;
get_fatfs_usage(&bytes_total, &bytes_free);
printf("%s->FAT FS Total: %d MB, Free: %d MB \r\n",TAG, bytes_total / 1024, bytes_free / 1024);
// 使用POSIX和C標準庫函式來處理檔案,
printf("%s->Opening file\r\n",TAG);
FILE* f = fopen(MOUNT_POINT"/hello.txt", "w");// 創建一個檔案
if (f == NULL) {
printf("%s->Failed to open file for writing\r\n",TAG);
return;
}
fprintf(f, "Hello %s!\n", card->cid.name);
fclose(f);
printf("%s->File written\r\n",TAG);
// 重命名前檢查目標檔案是否存在
struct stat st;
if (stat(MOUNT_POINT"/foo.txt", &st) == 0) {
unlink(MOUNT_POINT"/foo.txt");// 洗掉(如果存在)
}
// 重命名檔案
printf("%s->Renaming file\r\n",TAG);
if (rename(MOUNT_POINT"/hello.txt", MOUNT_POINT"/foo.txt") != 0) {
printf("%s->Rename failed\r\n",TAG);
return;
}
// 讀取檔案
printf("%s->Reading file\r\n",TAG);
f = fopen(MOUNT_POINT"/foo.txt", "r");// 讀取方式打開檔案
if (f == NULL) {
printf("%s->Failed to open file for reading\r\n",TAG);
return;
}
fgets(ReadFileBuff, sizeof(ReadFileBuff), f); // 讀取一行資料
fclose(f); // 關閉檔案
char* pos = strchr(ReadFileBuff, '\n'); // 在字串中查找換行
if (pos) {
*pos = '\0'; // 替換為結束符
}
printf("%s->Read from file: '%s'\r\n",TAG,ReadFileBuff);
// 卸載磁區并禁用SDMMC或SPI外設
esp_vfs_fat_sdcard_unmount(mount_point, card);
printf("%s->Card unmounted\r\n",TAG);
//卸載總線
spi_bus_free(host.slot);
}
三、下載測驗
打開ESP-IDF Command Prompt
cd命令進入此工程目錄
cd F:\ESP32_DevBoard_File\9_SPI_SDCard
查看電腦設備管理器中開發板的串口號

執行idf.py -p COM9 flash monitor從串口9下載并運行打開口顯示設備除錯資訊 Ctrl+c退出運行,查看串口資訊輸出
測驗卡為16G閃迪 class 10 TF卡

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/5677.html
標籤:其他
