SD 卡实验
这节课我们学习如何使用 MicroPython 控制 SD 卡模块。
实验原理
SD卡(Secure Digital Card)是一种常见的可移动存储设备,用于存储和传输数据。它是一种闪存存储卡,具有较小的尺寸、高存储容量和可擦写的特性。
SD 卡具有以下主要特点:
尺寸小
:SD 卡采用了较小的尺寸,便于携带和使用。标准尺寸的 SD 卡尺寸为 32mm × 24mm × 2.1mm,而微型 SD 卡和迷你 SD 卡则更小。高存储容量
:SD 卡的存储容量可以从几百兆字节到数百千兆字节不等。现代的 SD 卡通常具有较大的存储容量,可以满足各种数据存储需求。可擦写性
:SD 卡可以被多次擦写和重新写入,使其非常适合存储和传输数据。用户可以根据需要将数据写入 SD 卡,并随时进行修改或删除。高速传输
:SD 卡支持高速数据传输,以满足对快速读写速度的需求。不同类型的 SD 卡可能具有不同的传输速度标准,例如 SDSC、SDHC 和 SDXC 等。兼容性
:SD 卡具有广泛的兼容性,可以在许多设备上使用,例如数字相机、移动电话、音频播放器、电脑等。通过适配器,SD 卡还可以与其他类型的存储设备接口兼容。
SD 卡通常用于存储照片、音频、视频、文档和其他文件。它们广泛应用于数码相机、移动设备、嵌入式系统和各种消费电子产品中。在使用 SD 卡时,需要注意保护数据的安全性和完整性,避免数据丢失或损坏。
把 SD 卡通过读卡器连接到电脑,右击 SD 卡选择 格式化
选项,之后,我们可以看到 文件系统
选项,如下图
SD 卡使用的文件系统是指在 SD 卡上组织和管理文件和文件夹的方法。常见的 SD 卡文件系统有 FAT16、FAT32 和 exFAT 等。
FAT16(File Allocation Table 16)
:FAT16 是一种较早的文件系统,支持最大容量为 2GB 的存储设备。它使用 16 位的文件分配表来记录文件的存储位置和状态。FAT16 文件系统有一定的局限性,无法处理大容量存储设备和单个文件超过 2GB 的情况。FAT32(File Allocation Table 32)
:FAT32 是一种较为常见的文件系统,支持最大容量为 2TB 的存储设备。它采用 32 位的文件分配表,可以更有效地管理存储空间和文件索引。FAT32 文件系统被广泛用于移动存储设备、数码相机和其他消费电子设备。exFAT(Extended File Allocation Table)
:exFAT 是一种针对大容量存储设备设计的文件系统。它支持最大容量为 128PB 的存储设备和单个文件大小为 16EB 。exFAT 文件系统在支持大容量和大文件的同时,还具有较好的兼容性,可以在 Windows、Mac 和 Linux 等多个操作系统上使用。
SD 卡文件系统负责管理文件和目录的存储和访问。它使用文件分配表来记录文件的物理位置和状态,以及目录结构来组织文件和子目录。通过文件系统,用户可以方便地创建、读取、写入和删除文件,实现对存储设备中数据的管理和访问。
在使用 SD 卡时,需要选择适合的文件系统,根据存储设备的容量和应用需求进行设置。同时,还需要注意在使用过程中正确地操作文件系统,避免数据损坏和文件丢失的风险。
需要注意的是,在 SD 卡的文件系统选项中,存在 NTFS
选项,这个并不是 SD 卡的文件系统,如果你使用该选项格式化 SD 卡,会导致 SD 卡模块读取不到内容。
NTFS(New Technology File System)
是一种现代的文件系统,最早由微软引入并用于 Windows NT 操作系统及其后续版本。它具有许多先进的功能和优势,适用于处理大容量磁盘驱动器和大文件。
以下是 NTFS 的一些特点:
支持大容量存储
:NTFS 支持非常大的磁盘容量,可以处理多 TB 级别的存储设备。高性能
:NTFS 采用了先进的索引结构和数据组织方式,具有快速读取和写入文件的能力,可以提供较高的数据访问性能。安全性
:NTFS 支持文件和文件夹级别的访问控制,可以设置权限和加密保护,保障数据的安全性。容错能力
:NTFS 具有容错和恢复功能,可以自动修复文件系统错误和数据损坏,并提供一致性和完整性保护。支持大文件
:NTFS 支持单个文件的最大大小为 16EB(1EB = 1024PB),可以处理非常大的文件。支持文件压缩和加密
:NTFS 提供了文件压缩和加密的功能,可以节省存储空间并保护敏感数据的安全性。
NTFS 是在 Windows 操作系统中广泛使用的文件系统,适合用于处理大容量存储和大文件的场景。它在性能、安全性和功能方面都有一定的优势,可以满足现代计算机系统对文件系统的要求。
接着我们来了解一下 SD 卡模块,SD 卡模块通过标准的 SPI 协议与单片机进行连接,如果我们采用双线或者三线 SPI 协议就无法实现全双工的数据读写功能。唯一需要注意的是 SD 卡模块的 VCC 接 5V 电源引脚。
硬件电路设计
物料清单(BOM 表):
材料名称 | 数量 |
---|---|
SD 卡模块 | 1 |
SD 卡 | 1 |
杜邦线(跳线) | 若干 |
面包板 | 1 |
软件程序设计
在 Arduino 中对 SD 卡进行操作,可以使用 ESP32 自带的 SD
库。SD
库提供了一系列函数用于在 SD 卡上进行文件操作。下面是 SD
库中的一些常用函数的详细说明:
SD.begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false)
:初始化 SD 卡。此函数用于初始化 SD 卡并启动 SPI 通信。使用硬件 SPI,参数可以不填,使用默认参数即可。例如:SD.begin()
。open()
:打开一个文件,并返回一个 File 对象,以便进行后续的文件操作。它接受两个参数,第一个是文件路径,第二个是文件打开模式。常见的打开模式包括FILE_READ(只读)
、FILE_WRITE(只写)
、FILE_APPEND(追加写入)
等。available()
:检查文件是否可用(即是否已经打开),如果文件可用,则返回 true,否则返回 false。read()
:读取文件内容,从文件中读取一个字节的数据,并返回读取到的数据。write()
:写入文件内容。它接受一个参数,即要写入的数据。println()
:写入一行数据。此函数与write()
类似,但它会在写入数据后自动换行。close()
:关闭文件,释放 SD 卡的资源,结束 SD 卡的使用。remove()
:删除指定的文件。它接受一个参数,即要删除的文件路径。exists()
:检查指定路径的文件是否存在。如果文件存在,则返回 true,否则返回 false。mkdir()
:创建指定路径的目录。openNextFile()
:打开 SD 卡中的下一个文件。返回一个 File 对象,表示打开的文件。如果没有更多文件可打开,则返回一个空的 File 对象。name()
:获取打开文件的文件名。返回一个 char 类型的指针,指向文件名的字符串。isDirectory()
:检查打开的文件是否是一个目录。如果文件是一个目录,则返回 true;否则返回 false。
这些函数可以帮助你在 SD 卡上进行文件操作。使用 openNextFile()
函数,你可以迭代打开 SD 卡中的每个文件。使用 name()
函数,你可以获取打开文件的文件名。使用 isDirectory()
函数,你可以判断文件是一个目录还是一个普通文件。这些函数的组合可以帮助你遍历 SD 卡上的文件,并执行相应的操作。
以上是 SD
库中的一些常用函数,你可以根据具体的应用需求选择适合的函数来进行 SD 卡上的文件操作。你可以参考 SD
库的官方文档和示例代码以了解更多函数和用法。
因此,我们对 SD 卡中的文件进行读写操作的代码可以这么写:
#include <SD.h>
// 初始化文件对象
File my_file;
void setup() {
Serial.begin(9600);
if (!SD.begin()) {
Serial.println("SD卡初始化失败");
return;
}
Serial.println("SD卡初始化成功");
// 读取文件列表
list_files("/");
// 创建一个新的文件并写入数据
my_file = SD.open("/test.txt", FILE_WRITE);
if (my_file) {
my_file.println("你好,SD 卡"); // 写入数据
my_file.close(); // 关闭文件
Serial.println("数据写入完成");
} else {
Serial.println("无法打开文件");
}
delay(1000);
// 读取文件内容
my_file = SD.open("/test.txt");
while (my_file.available()) {
Serial.write(my_file.read());
}
my_file.close();
Serial.println("\n文件读取完成");
delay(1000);
// 修改文件内容
my_file = SD.open("/test.txt", FILE_APPEND);
my_file.println("修改文件");
my_file.close();
Serial.println("文件修改成功");
delay(1000);
// 读取文件内容
Serial.println("读取文件内容");
my_file = SD.open("/test.txt");
while (my_file.available()) {
Serial.write(my_file.read());
}
my_file.close();
Serial.println("\n文件读取完成");
delay(1000);
// 删除文件
if (SD.remove("/test.txt")) {
Serial.println("文件删除成功");
} else {
Serial.println("文件删除失败");
}
// 读取文件列表
list_files("/");
}
void loop() {
// 在这里进行其他操作
}
// 读取文件列表
void list_files(const char* path) {
Serial.println("文件列表:");
File root = SD.open(path);
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
Serial.print("目录:");
} else {
Serial.print("文件:");
}
Serial.println(file.name());
file = root.openNextFile();
}
root.close();
}
为什么文件列表中存在 System Volume Information?
System Volume Information
是 Windows 操作系统在存储设备上创建的隐藏文件夹,用于存储系统恢复信息和其他系统相关数据。当你在 Windows 中使用 SD 卡时,它会在 SD 卡的根目录下创建这个文件夹。
需要注意的是,使用 ESP32 自带的 SD 库时,在我们读取文件列表时,无法读取到中文名,因此,如果你想要读取到中文名的话,可以下载第三方库 SDFat
。