ESP32与SD卡交互实现:文件读写实战与初始化详解及引脚定义

本代码实现ESP32与SD卡的交互,包括定义SPI引脚、创建自定义SPI类实例、编写WriteFile与ReadFile函数进行文件读写。setup函数初始化串口、SPI、SD卡,向“/test.txt”写入“myfirstmessage”,读取并打印其内容。loop函数留空待扩展。

1. 需要准备的软硬件:

1.1 硬件:

  1. ESP32开发板在这里插入图片描述

  2. SD卡模块(如下图),可以是单独的TF卡模块也可以是集成到TFT屏幕的SD模块,TF卡与SD卡的硬件逻辑是一样,这主里不做区分在这里插入图片描述

  3. SD卡,Arduino 库仅支持 FAT16 和 FAT32 文件系统。 确保您的 SD 卡仅使用这两种格式进行格式化,否则将初始化错误。
    写本文时,在电脑上将SD卡以FAT32格式来格式化
    对于不同卡格式如下:

  • 对于SDSC卡:
    容量介于 16 MB 和 32 MB 之间 - FAT 16
    容量大于32 MB-FAT 16B
  • 对于SDHC卡
    容量小于 7.8 GB- FAT 32
    容量大于 7.8 GB- FAT 32
  • 对于SDXC卡
    exFAT

1.2 软件

  1. Arduino IDE或者在VS Code里的PlatformIO

1.3 连线方式一及代码

1.3.1 连接方式一如下表,本连线方式是用的ESP32的默认SPI接线方式,注意1.1的引脚图里23脚是VSPI MISO, 19脚是VSPI MOSI, 18脚是VSPI CLK 因此在接下来的代码中没有单独定义MISO、MOSI和CLK引脚。

引脚名称描述引脚编号
CSChip Select5
SCKClock18
MISOMaster In Slave Out19
MOSIMaster Out Slave In23

1.3.2 代码一:

/*SD Card Interface code for ESP32SPI Pins of ESP32 SD card as follows:CS    = 5;MOSI  = 23;MISO  = 19;SCK   = 18; 
*/#include <SPI.h>
#include <SD.h>File myFile;
const int CS = 5;/*** @brief 将指定消息写入到文件中。* * @param path 指向要写入的文件路径的字符指针。* @param message 指向要写入文件的消息的字符指针。* 该函数尝试打开指定路径的文件以进行写操作。如果文件成功打开,它将写入给定的消息,* 然后关闭文件,并通过串口打印一条完成消息。如果无法打开文件,它将打印错误消息和文件路径。*/
void WriteFile(const char *path, const char *message){// 尝试打开文件以写入myFile = SD.open(path, FILE_WRITE);if (myFile) { // 文件打开成功Serial.printf("Writing to %s ", path); // 打印正在写入的文件路径myFile.println(message); // 写入消息到文件myFile.close(); // 关闭文件Serial.println("completed."); // 打印写入完成信息} else { // 文件打开失败Serial.println("error opening file "); // 打印错误信息Serial.println(path); // 打印文件路径}
}/*** 读取指定路径的文件* * @param path 指向要打开的文件路径的字符指针* * 该函数尝试打开指定路径的文件,如果成功打开,则逐字节读取文件内容并通过串口打印。* 如果无法打开文件,将打印错误信息。*/
void ReadFile(const char *path){myFile = SD.open(path); // 尝试打开文件if (myFile) { // 如果文件成功打开Serial.printf("Reading file from %s\n", path); // 打印读取文件的路径信息while (myFile.available()) { // 循环,直到文件没有更多可用数据Serial.write(myFile.read()); // 读取并打印文件的一个字节}myFile.close(); // 关闭文件} else {Serial.println("error opening test.txt"); // 如果无法打开文件,打印错误信息}
}void setup() {Serial.begin(9600);delay(500);while (!Serial) { ; }Serial.println("Initializing SD card...");if (!SD.begin(CS)) {Serial.println("initialization failed!");return;}Serial.println("initialization done.");WriteFile("/test.txt", "ElectronicWings.com");ReadFile("/test.txt");
}void loop() {// nothing happens after setup
}

1.4 连线方式二及代码

1.4.1 连接方式二如下表,本连线方式并没有使用ESP32默认的引脚,而是对SPI各个引脚进行了重定义

引脚名称描述引脚编号
CSChip Select23
SCKClock16
MISOMaster In Slave Out2
MOSIMaster Out Slave In17

1.4.2 代码二:

与代码一的主要不同只有下面几行:

const int MOSI_PIN = 17; // 定义SPI通信中MOSI(Master Out Slave In)信号的常量
const int MISO_PIN = 2; // 定义SPI通信中MISO(Master In Slave Out)信号的常量
const int SCK_PIN = 16; // 定义SPI通信中SCK(Serial Clock)信号的常量// 定义一个自定义的SPI类实例
SPIClass CustomSPI;void setup(){// 初始化自定义SPI通信,传入SCK、MISO、MOSI引脚及CS控制信号CustomSPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS);// 初始化SD卡,如果初始化失败则打印错误信息并返回if (!SD.begin(CS, CustomSPI, 1000000)){Serial.println("initialization failed!");return;}
}

完整代码如下:

#include <Arduino.h>
/*SD Card Interface code for ESP32SPI Pins of ESP32 SD card as follows:CS    = 23;MOSI  = 17;MISO  = 2;SCK   = 16;
*/#include <SPI.h>
#include <SD.h>// 定义一个文件对象
File myFile; const int CS = 23; // 定义SPI通信中CS(Chip Select)信号的常量
const int MOSI_PIN = 17; // 定义SPI通信中MOSI(Master Out Slave In)信号的常量
const int MISO_PIN = 2; // 定义SPI通信中MISO(Master In Slave Out)信号的常量
const int SCK_PIN = 16; // 定义SPI通信中SCK(Serial Clock)信号的常量// 定义一个自定义的SPI类实例
SPIClass CustomSPI;
/*** @brief 将指定消息写入到文件中。* * @param path 指向要写入的文件路径的字符指针。* @param message 指向要写入文件的消息的字符指针。* 说明:函数不返回任何值,但会在串口打印操作的结果。*/
void WriteFile(const char *path, const char *message)
{// 尝试打开文件以便写入myFile = SD.open(path, FILE_WRITE);if (myFile){// 打印正在写入的文件路径Serial.printf("Writing to %s ", path);// 写入消息到文件,并在末尾添加换行符myFile.println(message);// 关闭文件myFile.close(); // 打印写入操作完成的通知Serial.println("completed.");}else{// 打印打开文件失败的通知Serial.println("error opening file ");// 打印失败的文件路径Serial.println(path);}
}/*** 读取指定路径的文件* * @param path 指向要打开的文件路径的字符指针* * 该函数尝试打开指定路径的文件,如果成功打开,则逐字节读取文件内容并通过串口打印。* 如果无法打开文件,将打印错误信息。*/
void ReadFile(const char *path)
{myFile = SD.open(path); // 尝试打开文件if (myFile) // 如果文件成功打开{Serial.printf("Reading file from %s\n", path); // 打印读取文件的路径信息while (myFile.available()) // 循环读取文件中的所有内容{Serial.write(myFile.read()); // 将读取到的每个字节通过串口发送}myFile.close(); // 关闭文件}else // 如果文件打开失败{Serial.println("error opening test.txt"); // 打印错误信息}
}/*** @brief 初始化设置函数* 该函数主要完成以下初始化工作:* 1. 初始化串口通信,设置波特率为9600;* 2. 初始化自定义SPI通信,并传入SCK、MISO、MOSI引脚及CS控制信号;* 3. 等待串口完全初始化;* 4. 初始化SD卡,如果初始化失败则打印错误信息并返回;* 5. 写入测试文件"/test.txt";* 6. 读取测试文件"/test.txt"的内容。* * 该函数没有参数和返回值。*/
void setup()
{// 初始化串口通信,设置波特率为9600,并延迟500msSerial.begin(9600);delay(500);// 初始化自定义SPI通信,传入SCK、MISO、MOSI引脚及CS控制信号CustomSPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS);// 等待直到串口完全初始化while (!Serial){;} // 打印初始化SD卡的开始信息Serial.println("Initializing SD card...");// 初始化SD卡,如果初始化失败则打印错误信息并返回if (!SD.begin(CS, CustomSPI, 1000000)){Serial.println("initialization failed!");return;}// 打印SD卡初始化成功的消息Serial.println("initialization done.");// 写入测试文件"/test.txt"WriteFile("/test.txt", "myfirstmessage");// 读取测试文件"/test.txt"的内容ReadFile("/test.txt");//打印读取到的内容Serial.println("Reading from test.txt");}void loop()
{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/640739.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习-10-基于paddle实现神经网络

文章目录 总结参考本门课程的目标机器学习定义第一步&#xff1a;数据准备第二步&#xff1a;定义网络第三步&#xff1a;训练网络第四步&#xff1a;测试训练好的网络 总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍基于paddle实现神经网络。 参考 MNIST 训练_副…

直播美颜工具与视频美颜SDK:技术深入探索

直播美颜工具和视频美颜SDK的出现&#xff0c;为直播平台和应用开发者提供了丰富的选择。本文将深入探讨这些技术的原理、应用和发展趋势。 一、美颜算法 直播美颜工具的核心在于其先进的美颜算法。这些算法通过对图像进行分析和处理&#xff0c;实时地修饰主播的面部特征&am…

机器学习-10-神经网络python实现-从零开始

文章目录 总结参考本门课程的目标机器学习定义从零构建神经网络手写数据集MNIST介绍代码读取数据集MNIST神经网络实现测试手写的图片 带有反向查询的神经网络实现 总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍基于python实现神经网络。 参考 BP神经网络及pytho…

stm32——GPIO学习

对于许多刚入门stm32的同学们来说&#xff0c;GPIO是我们的第一课&#xff0c;初出茅庐的我们会对GPIO的配置感到疑惑不解&#xff0c;也是劝退我们的第一课&#xff0c;今天我们就来一起学习一下stm32的GPIO&#xff0c;提振一下信心。好的&#xff0c;发车了小卷卷们&#xf…

力扣146. LRU 缓存

Problem: 146. LRU 缓存 文章目录 题目描述思路复杂度Code 题目描述 思路 主要说明大致思路&#xff0c;具体实现看代码。 1.为了实现题目中的O(1)时间复杂度的get与put方法&#xff0c;我们利用哈希表和双链表的结合&#xff0c;将key作为键&#xff0c;对应的链表的节点作为…

【前后端】django前后端交互

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、django是什么二、django前后端交互指引三、总结 前言 随着开发语言及人工智能工具的普及&#xff0c;使得越来越多的人会主动学习使用一些开发语言&#x…

零售数据分析方案:深度剖析人、货、场

人&#xff0c;即会员分析、用户分析&#xff0c;通过分析获得直观的用户画像&#xff0c;了解目标用户群体的消费水平、喜好、频率&#xff0c;为销售营销决策提供必要的数据支持&#xff1b;货&#xff0c;即商品分析&#xff0c;包括但不限于分析商品结构、分析销售top10商品…

构建云原生湖仓:Apache Iceberg与Amoro的结合实践

随着大数据技术的快速发展&#xff0c;企业对数据的处理和分析需求日益增长。传统的数据仓库已逐渐无法满足现代业务对数据多样性和实时性的要求&#xff0c;这促使了数据湖和数据仓库的融合&#xff0c;即湖仓一体架构的诞生。在云原生技术的推动下&#xff0c;构建云原生湖仓…

Opensbi初始化分析:设备初始化

Opensbi初始化分析&#xff1a;设备初始化 设备初始化sbi_init函数coldinit&#xff0c;冷启动初始化sbi_scratch_init函数sbi_domain_init函数sbi_hsm_initsbi_platform_early_initsbi_hart_initsbi_console_initsbi_platform_irqchip_init中断控制器的初始化sbi_ipi_init函数…

C++奇迹之旅:从0开始实现日期时间计算器

文章目录 &#x1f4dd;前言&#x1f320; 头文件Date.h&#x1f309;日期计算函数&#x1f320;前后置&#x1f309;前后置-- &#x1f320;两对象日期相减&#x1f309;自定义流输入和输出 &#x1f309; 代码&#x1f309; 头文件Date.h&#x1f320;Date.cpp&#x1f309; …

数据挖掘实验(Apriori,fpgrowth)

Apriori&#xff1a;这里做了个小优化&#xff0c;比如abcde和adcef自连接出的新项集abcdef&#xff0c;可以用abcde的位置和f的位置取交集&#xff0c;这样第n项集的计算可以用n-1项集的信息和数字本身的位置信息计算出来&#xff0c;只需要保存第n-1项集的位置信息就可以提速…

在Qt creator中使用多光标

2024年4月22日&#xff0c;周一下午 Qt Creator 支持多光标模式。 多光标模式允许你在同一时间在多个光标位置进行编辑&#xff0c;从而可以更快地进行一些重复性的编辑操作。 要启用多光标模式&#xff0c;请按住 Alt 键&#xff0c;并用鼠标左键在文本编辑器中选择多个光标…