1. 项目缘起与核心需求拆解
搞ESP32-S3的兄弟多半都绕不开一个坎:板子跑起来了,传感器数据也读到了,但数据往哪搁?RAM就那么点大,跑个摄像头帧缓冲或者高频采样日志,分分钟爆内存。这时候TF卡就成了最接地气的扩容方案——便宜、容量大、拔插方便,单片机圈子里几乎人手一张。
但问题来了:ESP32-S3接TF卡,到底走SPI还是SDIO?这俩模式我都在实际项目里趟过,差距不是一星半点。SPI模式接线简单,四根线搞定,但速度卡在10-20MHz这个量级,实际读写撑死也就1-2MB/s;SDIO模式能跑到40MHz,理论带宽翻好几倍,但占用引脚多,配置也更容易翻车。更别提还有DMA通道分配、文件系统挂载、多任务并发访问这些坑,每一个都能让你调一整天。
这篇内容就是把我自己在ESP32-S3上折腾TF卡的全过程拆开揉碎讲清楚。从SPI和SDIO的底层差异,到具体接线、代码配置、速度实测,再到FreeRTOS下多任务读写冲突的排查,全部基于实际跑通的工程。适合正在选型的硬件工程师、被读写速度卡住的嵌入式开发者,以及想从STM32转ESP32-S3的兄弟参考。看完你至少能少走三天弯路。
2. SPI与SDIO模式深度对比:为什么选型决定成败
2.1 物理层差异:引脚占用与布线复杂度
SPI模式接TF卡,本质上就是把TF卡当成一个SPI从设备来通信。你需要接四根线:CS(片选)、SCK(时钟)、MOSI(主机输出从机输入)、MISO(主机输入从机输出)。ESP32-S3上任意GPIO都能复用成SPI功能,布线灵活度极高。我常用的一组是GPIO 10-13,正好凑一个SPI主机控制器,不跟USB-JTAG冲突。
SDIO模式就不一样了。标准SDIO需要CLK、CMD、DAT0-DAT3,一共六根线。ESP32-S3的SDIO主机控制器固定映射在GPIO 14-19这组引脚上,没法随便换。更麻烦的是,这组引脚跟某些外设(比如摄像头OV5640的DVP接口)有重叠,选型阶段就得规划好。但换来的是四线并行数据传输,DAT0-DAT3同时干活,带宽直接翻四倍。
这里有个实际经验:如果你板子上已经接了SPI屏幕或者SPI Flash,再挂TF卡就要考虑片选冲突和总线争用。我试过SPI屏幕和TF卡共用一个SPI总线,屏幕刷新的时候TF卡写入直接卡死,后来把TF卡挪到独立SPI控制器才解决。SDIO就没这个问题,独立总线,互不干扰。
2.2 协议层差异:命令响应与数据传输机制
SPI模式下,TF卡跑的是SD协议的SPI兼容子集。每条命令都是先发命令字节,再等响应,数据一个bit一个bit地挪。命令开销大,每个数据块传输前都要走完整的命令-响应流程。我实测过,SPI模式读1KB数据,命令开销占了将近30%的时间。
SDIO模式跑的是原生SD协议,命令走CMD线,数据走DAT线,命令和数据可以流水线并行。而且SDIO支持多块传输模式,一次命令可以连续读多个数据块,命令开销摊薄到几乎可以忽略。这就是为什么SDIO实际速度能比SPI快3-5倍的根本原因。
还有个细节:SPI模式下TF卡的初始化流程特别绕。上电后要先发74个时钟周期让卡进入SPI模式,然后发CMD0复位,CMD8查电压,ACMD41等卡就绪,CMD58读OCR寄存器确认电压范围。每一步都有超时重试,任何一步失败都得从头来。SDIO模式初始化就清爽得多,标准SD流程,CMD0、CMD8、ACMD41、CMD2、CMD3,一气呵成。
2.3 速度实测对比:数据不说谎
我在同一张Class 10的32GB TF卡上做了对比测试,ESP32-S3主频240MHz,SPI时钟设到20MHz,SDIO时钟设到40MHz,文件系统都用FATFS,测试文件大小64MB,读写各跑三次取平均。
| 测试项 | SPI模式(20MHz) | SDIO模式(40MHz) | 提升倍数 |
|---|---|---|---|
| 顺序写入 | 1.2 MB/s | 5.8 MB/s | 4.8x |
| 顺序读取 | 1.8 MB/s | 8.3 MB/s | 4.6x |
| 4KB随机写入 | 0.3 MB/s | 1.9 MB/s | 6.3x |
| 4KB随机读取 | 0.9 MB/s | 4.2 MB/s | 4.7x |
| 挂载时间 | 320ms | 180ms | 1.8x |
这个数据很能说明问题。SPI模式写入1MB数据要将近一秒钟,如果你要存摄像头图片或者音频流,基本没戏。SDIO模式写入5.8MB/s,存个几十KB的图片也就几毫秒的事。挂载时间差距也明显,SPI模式初始化那套流程确实拖后腿。
但SPI也不是没有优势。接线简单,GPIO随便选,代码移植性好,从STM32搬过来的SPI驱动改改就能用。如果你只是偶尔存个配置参数、日志文件,数据量不大,SPI完全够用。但要是涉及高频写入、大文件传输,SDIO是唯一选择。
3. 硬件设计与接线实操:从原理图到实物
3.1 SPI模式接线方案与注意事项
SPI模式接TF卡,核心就四根信号线加电源。我以ESP32-S3-DevKitC为例,给一组经过实测的引脚分配:
- CS → GPIO 10
- SCK → GPIO 12
- MOSI → GPIO 11
- MISO → GPIO 13
- VCC → 3.3V
- GND → GND
这里有个大坑:TF卡座子一般有个CD(Card Detect)引脚,用来检测卡插入。很多人不接,结果代码里判断卡是否存在永远返回false。要么把CD接地强制认为卡一直存在,要么接个GPIO做检测。我建议接上,GPIO 9就不错,配上内部上拉,卡插入时拉低。
还有电源问题。TF卡写入瞬间电流能冲到100mA以上,ESP32-S3的3.3V LDO如果本身负载就重,容易导致电压跌落,卡直接掉线。我遇到过写大文件写到一半卡死,查了半天是电源纹波太大。后来在TF卡座VCC脚旁边并了个100μF钽电容加0.1μF陶瓷电容,问题消失。这个细节 datasheet 不会写,但实际项目里特别关键。
SPI时钟线上最好串个22Ω电阻,抑制过冲。TF卡座到ESP32-S3的走线尽量短,超过10cm就要考虑信号完整性问题。我试过用杜邦线飞线20cm,SPI时钟降到5MHz才能稳定读写,速度惨不忍睹。
3.2 SDIO模式接线方案与引脚冲突排查
SDIO模式引脚是固定的,ESP32-S3上对应:
- CLK → GPIO 14
- CMD → GPIO 15
- DAT0 → GPIO 16
- DAT1 → GPIO 17
- DAT2 → GPIO 18
- DAT3 → GPIO 19
这六根线必须用这组GPIO,没得商量。如果你板子上这组引脚被摄像头、LCD或者PSRAM占了,那就只能退而求其次用SPI。我在一个带OV5640摄像头的项目里就遇到这个问题:OV5640的DVP接口用了GPIO 14-19中的好几根,SDIO直接没戏,最后只能SPI模式凑合。
但如果你引脚够用,SDIO的布线要注意几点。CLK线要等长,DAT0-DAT3也要等长,偏差控制在5mm以内。所有信号线下面最好有完整的地平面,减少串扰。TF卡座的屏蔽壳要可靠接地,不然高速读写时EMI问题能让你怀疑人生。
上拉电阻方面,CMD和DAT0-DAT3都需要10kΩ上拉到3.3V。有些TF卡座模块自带上拉,就不用外接。但如果你自己画板,千万别省这几个电阻,否则初始化都过不去。
3.3 电源设计与去耦电容选型
TF卡功耗波动很大。空闲时几毫安,写入峰值能到100-150mA。ESP32-S3本身WiFi工作时电流也不小,两个凑一起,3.3V轨上的瞬态响应必须够快。
我的做法是:TF卡座VCC脚最近的地方放一个100μF钽电容(ESR要低),再并一个0.1μF陶瓷电容滤高频。如果板子空间允许,再串一个磁珠隔离数字噪声。LDO选型上,至少保证500mA输出能力,瞬态响应时间小于50μs。
实测数据:不加钽电容时,写入大文件过程中3.3V轨有200mV左右的跌落;加上之后,跌落控制在50mV以内,读写稳定性大幅提升。这个改动成本不到一块钱,但能省掉你无数调试时间。
4. 软件配置与代码实现:从零跑通读写
4.1 ESP-IDF环境搭建与工程配置
我用的ESP-IDF v5.1,VSCode加Espressif IDF插件。新建工程后,idf.py menuconfig里几个关键配置:
- Component config → FAT Filesystem support → 使能Long filename support
- Component config → SD/MMC → 根据模式选SDMMC或SPI
- 如果走SDIO,使能SDMMC host driver,DMA通道选自动
分区表也要改。默认分区表可能没给FATFS留空间,需要在partitions.csv里加一行:
fatfs, data, fat, , 1M,这1MB空间就是TF卡文件系统的挂载点。实际数据存在TF卡上,但ESP-IDF的VFS层需要一个分区来做挂载中介。
4.2 SPI模式驱动代码详解
SPI模式初始化分两步:先初始化SPI总线,再挂载FATFS。核心代码如下:
#include "driver/spi_master.h" #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" #define PIN_CS 10 #define PIN_SCK 12 #define PIN_MOSI 11 #define PIN_MISO 13 void init_spi_tf_card(void) { spi_bus_config_t bus_cfg = { .mosi_io_num = PIN_MOSI, .miso_io_num = PIN_MISO, .sclk_io_num = PIN_SCK, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 4096, }; ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO)); sdmmc_host_t host = SDSPI_HOST_DEFAULT(); host.slot = SPI2_HOST; host.max_freq_khz = 20000; sdspi_device_config_t slot_cfg = SDSPI_DEVICE_CONFIG_DEFAULT(); slot_cfg.gpio_cs = PIN_CS; slot_cfg.host_id = SPI2_HOST; esp_vfs_fat_sdmmc_mount_config_t mount_cfg = { .format_if_mount_failed = false, .max_files = 5, .allocation_unit_size = 16 * 1024, }; sdmmc_card_t *card; esp_err_t ret = esp_vfs_fat_sdspi_mount("/sdcard", &host, &slot_cfg, &mount_cfg, &card); if (ret != ESP_OK) { ESP_LOGE("TF", "Mount failed: %s", esp_err_to_name(ret)); return; } sdmmc_card_print_info(stdout, card); }几个关键点:max_freq_khz设20MHz是SPI模式的稳定上限,再高容易出错。allocation_unit_size设16KB,跟TF卡的擦除块大小对齐,能减少写放大。max_files根据你同时打开的文件数调整,设太小会报EMFILE错误。
4.3 SDIO模式驱动代码详解
SDIO模式代码更简洁,因为协议栈帮你处理了大部分底层细节:
#include "driver/sdmmc_host.h" #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" void init_sdio_tf_card(void) { sdmmc_host_t host = SDMMC_HOST_DEFAULT(); host.max_freq_khz = 40000; host.flags = SDMMC_HOST_FLAG_4BIT; sdmmc_slot_config_t slot_cfg = SDMMC_SLOT_CONFIG_DEFAULT(); slot_cfg.width = 4; slot_cfg.clk = 14; slot_cfg.cmd = 15; slot_cfg.d0 = 16; slot_cfg.d1 = 17; slot_cfg.d2 = 18; slot_cfg.d3 = 19; esp_vfs_fat_sdmmc_mount_config_t mount_cfg = { .format_if_mount_failed = false, .max_files = 5, .allocation_unit_size = 16 * 1024, }; sdmmc_card_t *card; esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_cfg, &mount_cfg, &card); if (ret != ESP_OK) { ESP_LOGE("TF", "Mount failed: %s", esp_err_to_name(ret)); return; } sdmmc_card_print_info(stdout, card); }host.flags设SDMMC_HOST_FLAG_4BIT启用四线模式,这是速度翻倍的关键。max_freq_khz设40MHz,实测稳定。如果线材质量差或者走线长,降到20MHz也能跑,但速度优势就没了。
4.4 文件读写性能优化技巧
挂载成功后,读写文件用标准POSIX接口就行。但有几个优化点能让速度再上一个台阶:
第一,用setvbuf设置大缓冲区。默认stdio缓冲区只有几百字节,频繁系统调用拖慢速度。设成16KB:
FILE *f = fopen("/sdcard/test.bin", "wb"); setvbuf(f, NULL, _IOFBF, 16384);第二,写入时按扇区对齐。TF卡最小写入单位是512字节扇区,如果你一次写100字节,驱动层要读-改-写整个扇区,速度直接砍半。尽量凑够512字节的整数倍再写。
第三,批量写入代替逐条写入。我见过有人存传感器数据,每读一次就fprintf一次,结果1Hz的采样率都卡。正确做法是攒够一批数据,一次性fwrite。我一般攒够4KB写一次,速度提升非常明显。
第四,读文件时用fread大块读取,别用fgetc一个字节一个字节读。fgetc每次都要走VFS层,开销巨大。实测fread读1MB文件比fgetc快20倍以上。
5. 多任务环境下的并发访问与性能调优
5.1 FreeRTOS下TF卡访问的互斥机制
在FreeRTOS里,多个任务同时读写TF卡是常态。比如一个任务存日志,一个任务存图片,还有一个任务读配置文件。如果不加保护,FATFS内部状态机直接乱套,轻则数据错乱,重则文件系统损坏。
ESP-IDF的VFS层其实有锁,但粒度比较粗,而且某些操作不是原子的。我的做法是在应用层再加一层互斥锁:
static SemaphoreHandle_t tf_mutex = NULL; void tf_init_mutex(void) { tf_mutex = xSemaphoreCreateMutex(); } esp_err_t tf_write_file(const char *path, const void *data, size_t len) { if (xSemaphoreTake(tf_mutex, pdMS_TO_TICKS(5000)) != pdTRUE) { return ESP_ERR_TIMEOUT; } FILE *f = fopen(path, "wb"); if (!f) { xSemaphoreGive(tf_mutex); return ESP_FAIL; } fwrite(data, 1, len, f); fclose(f); xSemaphoreGive(tf_mutex); return ESP_OK; }超时设5秒,防止某个任务卡死导致整个系统锁死。如果5秒还拿不到锁,说明有异常,直接返回错误让上层处理。
5.2 DMA通道分配与中断优先级设置
ESP32-S3有两个SPI控制器和一组SDMMC控制器,DMA通道是共享资源。如果你同时用了SPI屏幕、SPI Flash和SPI TF卡,DMA通道可能不够用。SPI_DMA_CH_AUTO让驱动自动分配,但有时候自动分配的结果不是最优。
我遇到过SPI TF卡和SPI屏幕抢DMA通道,屏幕刷新时TF卡写入延迟飙升。后来手动指定TF卡用DMA通道2,屏幕用通道1,问题解决。手动指定用spi_bus_initialize的第三个参数,传SPI_DMA_CH2就行。
中断优先级方面,SDIO的中断优先级默认是1,SPI是2。如果系统里有更高优先级的中断(比如WiFi),TF卡操作可能被频繁打断。可以在menuconfig里调整SDMMC中断优先级,但别设太高,否则会影响WiFi实时性。我一般保持默认,靠DMA和缓冲区来吸收抖动。
5.3 写入缓存与flush策略
FATFS有写入缓存,数据先写到缓存,攒够了再刷到卡上。这个机制能提升吞吐量,但掉电时可能丢数据。如果你的应用对数据完整性要求高,比如记录关键日志,就要定期fflush。
但fflush太频繁又伤性能。我的折中方案是:每写4KB调用一次fflush,同时开一个低优先级任务,每5秒强制刷一次。这样即使掉电,最多丢5秒数据。如果数据特别关键,可以缩短到1秒,但写入速度会下降20%左右。
还有个技巧:用f_sync代替fflush。f_sync直接调FATFS的同步接口,绕过stdio缓冲,更底层也更可靠。但注意f_sync需要文件句柄,不是FILE指针,得用FATFS的原生API。
6. 常见问题排查与避坑指南
6.1 挂载失败问题速查表
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 挂载返回ESP_ERR_TIMEOUT | 接线错误或卡未插入 | 检查CD引脚电平,用万用表测通断 | 重新接线,确认卡座接触良好 |
| 挂载返回ESP_FAIL | 卡格式不支持 | 用读卡器在电脑上查看分区格式 | 格式化为FAT32,分配单元16KB |
| 初始化卡在ACMD41 | 电源不足 | 示波器测3.3V轨纹波 | 加钽电容,换大电流LDO |
| SDIO模式初始化失败 | 上拉电阻缺失 | 测CMD和DAT线空闲电平 | 补10kΩ上拉电阻 |
| SPI模式读写不稳定 | 时钟太快 | 逐步降低max_freq_khz | 从20MHz降到10MHz测试 |
| 写入大文件卡死 | DMA通道冲突 | 查看menuconfig中DMA分配 | 手动指定独立DMA通道 |
6.2 读写速度不达预期的排查思路
速度上不去,先别怀疑代码,按这个顺序查:
第一步,确认卡本身的速度等级。Class 4的卡写入撑死4MB/s,你代码再优化也突破不了物理极限。用sdmmc_card_print_info打印卡的信息,看速度等级和容量。
第二步,检查时钟配置。SPI模式max_freq_khz设了多少?SDIO模式host.max_freq_khz设了多少?很多人忘了改,默认值很低。SPI默认可能只有1MHz,SDIO默认可能只有400kHz。
第三步,看文件系统配置。allocation_unit_size设太小会导致频繁分配簇,设太大浪费空间。16KB是个比较平衡的值。另外确认FATFS的FF_FS_TINY没开,开了会禁用扇区缓冲,速度暴跌。
第四步,排查总线争用。如果SPI总线上还挂了其他设备,TF卡操作时其他设备在干嘛?我遇到过SPI屏幕持续刷新导致TF卡写入延迟从10ms飙到200ms。解决办法是TF卡操作时暂停屏幕刷新,或者用独立SPI控制器。
6.3 文件系统损坏的预防与恢复
TF卡在嵌入式系统里掉电是家常便饭,FATFS损坏概率不低。预防措施比恢复更重要:
- 挂载时
format_if_mount_failed设false,别自动格式化,否则数据全丢 - 写入关键数据前先
f_sync,确保元数据落盘 - 定期用
f_getfree检查剩余空间,满了之后写入会失败甚至损坏文件系统 - 如果检测到挂载失败,先尝试
f_mkfs重新格式化,但只在确认数据可丢的情况下做
恢复方面,如果文件系统挂了但数据重要,可以把卡拔下来用电脑的chkdsk修复。但嵌入式设备现场没法这么干,所以我的项目里都会加一个恢复模式:长按某个按键启动时,自动备份关键文件到SPI Flash,然后格式化TF卡,再把文件拷回去。
6.4 实操心得与独家避坑技巧
说几个文档里不会写但实际项目里特别有用的经验:
第一,TF卡座子选带金属屏蔽壳的,插拔寿命至少一万次。我贪便宜用过塑料壳的,插拔几十次就接触不良,现场设备返修率极高。
第二,批量生产时,TF卡座要过回流焊,有些卡座塑料不耐高温,焊完就变形。选耐温260℃的型号,贵不了几毛钱但省心。
第三,SDIO模式对TF卡品牌敏感。我实测三星EVO系列兼容性最好,闪迪某些型号初始化会超时。批量前一定多买几个品牌测试。
第四,如果产品工作在振动环境,TF卡座要选带卡扣的,普通弹片式振动久了会松。或者干脆用eMMC替代,但成本上去了。
第五,调试阶段在TF卡电源上串个0.5A的保险丝,防止接线错误烧卡。烧一张卡几十块,烧十张就够买台示波器了。
7. 性能压测与长期稳定性验证
7.1 连续读写压力测试方法
代码跑通只是第一步,能不能扛住连续读写才是关键。我写了个压测程序,循环写入1MB随机数据再读出来校验,跑24小时。SPI模式跑到第3小时开始出现写入超时,SDIO模式跑完24小时零错误。
压测代码核心逻辑:
void stress_test(void) { uint8_t *buf = malloc(1024 * 1024); uint8_t *rbuf = malloc(1024 * 1024); for (int i = 0; i < 1024 * 1024; i++) { buf[i] = rand() & 0xFF; } for (int round = 0; round < 1000; round++) { FILE *f = fopen("/sdcard/stress.bin", "wb"); fwrite(buf, 1, 1024 * 1024, f); fclose(f); f = fopen("/sdcard/stress.bin", "rb"); fread(rbuf, 1, 1024 * 1024, f); fclose(f); if (memcmp(buf, rbuf, 1024 * 1024) != 0) { ESP_LOGE("STRESS", "Data mismatch at round %d", round); break; } ESP_LOGI("STRESS", "Round %d OK", round); } free(buf); free(rbuf); }跑的时候注意监控芯片温度。ESP32-S3本身发热不大,但TF卡连续写入会烫手。如果卡表面温度超过60℃,说明散热有问题,长期运行可能降速甚至损坏。
7.2 温度与电压边界测试
工业级应用要做温度测试。我把板子放进温箱,从-20℃到70℃循环,每10℃保持1小时,期间持续读写。结果:SPI模式在-20℃时初始化失败率30%,SDIO模式全部通过。高温端两者都正常,但SDIO写入速度在70℃时下降约15%。
电压方面,3.3V标称,实际允许范围3.0-3.6V。我在3.0V时测试,SPI模式写入错误率明显上升,SDIO模式基本稳定。所以如果你的供电精度不够,SDIO是更稳妥的选择。
7.3 长期运行的数据完整性保障
产品跑几个月不出问题,靠的是数据完整性机制。我的做法是:
- 每个文件写入时带CRC32校验,读取时验证
- 关键文件双备份,A/B分区交替写
- 定期扫描文件系统,发现坏块标记并跳过
- 记录写入次数,接近TF卡寿命时告警
TF卡寿命方面,TLC颗粒一般1000-3000次擦写循环。如果你每天写1GB,32GB卡大概能用3-5年。但实际项目中写入量往往远小于这个,所以不用太焦虑。真正要担心的是突然掉电导致文件系统损坏,这个比寿命问题更常见。
8. 方案选型建议与扩展思路
8.1 什么场景选SPI,什么场景选SDIO
选SPI的情况:数据量小(每天几MB以内)、引脚紧张、成本敏感、从STM32移植过来不想大改。比如存配置参数、低频日志、OTA升级包暂存,SPI完全够用。
选SDIO的情况:高频写入(传感器高速采样、音频流)、大文件传输(图片、视频)、多任务并发访问、对实时性有要求。比如摄像头抓拍存图、音频录音、数据记录仪,SDIO是唯一选择。
如果拿不准,先算一下峰值写入速率。超过2MB/s就必须SDIO,低于1MB/s SPI可以凑合,1-2MB/s之间看你对稳定性的要求。
8.2 从SPI迁移到SDIO的注意事项
迁移不是改几行代码那么简单。首先引脚要重新规划,SDIO那六根线是固定的,得确认没被其他外设占用。其次电源要重新评估,SDIO峰值电流更大,LDO和电容可能要换。最后代码里SPI相关的初始化全部删掉,换成SDMMC的API。
迁移后一定要重新做压测。我遇到过SPI跑得好好的代码,换SDIO后因为DMA通道冲突导致WiFi断流。后来调整了DMA分配才解决。所以迁移后WiFi、蓝牙这些射频功能都要回归测试。
8.3 更高性能的存储方案探索
如果SDIO的5-8MB/s还不够,可以考虑几个方向:
一是用eMMC替代TF卡。eMMC焊接在板上,速度能到20-30MB/s,可靠性也更高。但成本贵不少,而且容量固定,不适合需要换卡的应用。
二是用ESP32-S3的USB OTG接U盘。速度能到10MB/s以上,但USB协议栈复杂,功耗也高。
三是上外部SRAM做缓存,批量攒够数据再写卡。这个方案不改硬件,纯软件优化,能把有效写入速度提升30%左右。我一般会留至少64KB的PSRAM做文件缓存,效果很明显。
四是考虑双TF卡方案,一张存日志一张存媒体文件,两个SDIO控制器并行。但ESP32-S3只有一个SDMMC控制器,另一个只能走SPI,速度不对等。这个方案适合对容量要求高但对速度要求不高的场景。
实际选型时,我一般先问三个问题:数据量多大?写入频率多高?掉电能不能丢数据?答案清楚了,方案自然就定了。最怕的是上来就追求最高性能,结果成本翻倍,实际用不到十分之一。