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.mzph.cn/diannao/3533.shtml

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

相关文章

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

PCV库之调用SIFT.py中process_image()执行错误的解决方案

背景介绍: windows10,python3.x,64位AMD R9处理器,ROG电脑,pycharm开发,已经安装好了PCV库 如何安装PCV库 请看我的博客Python之PCV库安装教程以及解说-CSDN博客文章浏览阅读111次&#xff0c;点赞5次&#xff0c;收藏3次。GitHub - Ultravioletrayss/PCVfile: 文档内含有pyt…

Docker搭建Codiad

Codiad Docker 镜像功能介绍 Codiad 是一个基于 Web 的代码编辑器&#xff0c;它提供了一个全功能的代码编写和管理界面&#xff0c;支持多种编程语言的语法高亮。Codiad 允许用户通过浏览器访问和管理远程服务器上的代码文件&#xff0c;非常适合开发者进行远程开发或者团队协…

Nginx 配置 SSL(HTTPS)详解

Nginx作为一款高性能的HTTP和反向代理服务器&#xff0c;自然支持SSL/TLS加密通信。本文将详细介绍如何在Nginx中配置SSL&#xff0c;实现HTTPS的访问。 随着互联网安全性的日益重要&#xff0c;HTTPS协议逐渐成为网站加密通信的标配。Nginx作为一款高性能的HTTP和反向代理服务…

OpenCV 实现霍夫圆变换

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV实现霍夫变换 下一篇:OpenCV 实现重新映射 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 HoughCircles()检测图像中的圆圈。 理论 Hough 圆变换 H…

Cgicc搭建交叉编译环境(移植到arm)

Cgicc GUN Project官网连接&#xff1a;Cgicc- GNU Project - Free Software Foundation 1. 下载源码 Cgicc下载地址&#xff1a; [via http] Index of /gnu/cgicc [via FTP] ftp://ftp.gnu.org/gnu/cgicc/ 目前最新版&#xff1a;3.2.20 2. 源码构建原理 一般&#xff…

在VSCode中调试其他软件执行的python文件

在VSCode中调试其他软件执行的python文件 0. 实际场景 我有一段python代码想在Metashape中运行&#xff0c;但是又想在中间某一步停下来查看变量值。由于Metashape的python环境不容易在vscode中配置&#xff0c;所以直接用vscode调试单个文件的方式无法实现这个想法。还好&am…

42. UE5 RPG 实现火球术伤害

上一篇&#xff0c;我们解决了火球术于物体碰撞的问题&#xff0c;现在火球术能够正确的和攻击目标产生碰撞。接下来&#xff0c;我们要实现火球术的伤害功能&#xff0c;在火球术击中目标后&#xff0c;给目标造成伤害。 实现伤害功能的思路是给技能一个GameplayEffect&#x…

3DTiles生产流程与规范

一篇19年整理的比较老的笔记了。更多精彩内容尽在数字孪生平台。 瓦片切分 标准的四叉树切分对于均匀分布的地理数据切片非常有效&#xff0c;但是这样均等的切分不适用于随机分布、不均匀分布的地理数据&#xff0c;当地理数据稀疏分布的时候&#xff0c;均等的四叉树就不再高…

跟着Datawhale重学数据结构与算法(3)---排序算法

开源链接&#xff1a;【 教程地址 】【电子网站】 【写博客的目的是记录自己学习过程&#xff0c;方便自己复盘&#xff0c;专业课复习】 数组排序&#xff1a; #mermaid-svg-F3iLcKsVv8gcmqqC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16p…

jenkins自动化工具简介

Jenkins 是一个开源的自动化服务器&#xff0c;它允许您自动化各种任务&#xff0c;包括构建、测试和部署软件。它是一个用Java编写的应用程序&#xff0c;可以运行在任何支持Java的平台上。Jenkins 通过其插件系统提供了大量的功能&#xff0c;使其成为一个非常灵活和强大的工…

PHP项目搭建与启动

1、拉取项目 2、安装phpstudy 下载地址&#xff1a; Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 软件安装&#xff1a; Apache2.4.39、Nginx1.15.11、MySQL8.0.12、 composer2.5.8 添加伪静态 将下面代码写入到伪静态配置文本域框内&#xff1a; location ~* (ru…

redis模糊查询redis中的key

redis模糊查询redis中的key 方式一&#xff1a;使用keys命令 /*** 查找匹配的key** param pattern* return*/ public Set<String> keys(String pattern) {return redisTemplate.keys(pattern); }方式二&#xff1a;使用san命令 /*** 查找匹配的key** param pattern* r…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Text Edit的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 输入类控件 | Text Edit的使用及说明 文章编号&#xff…

VScode使用cmake编译

一&#xff1a;输入 ctrlshiftp打开用于命令执行的输入框 二&#xff1a;输入cmake&#xff0c;选择quick start 模式 三&#xff1a;选择版本最高的gcc版本 四&#xff1a;输入项目名称 选择C 五&#xff1a;选择executable 这样便创建好了最简单的cmake例程&#xff0c;一个…

使用MySQL和SQL Server生成最近七天的日期

在数据处理和报表生成过程中&#xff0c;经常需要生成最近一段时间内的数据。本文将介绍如何在MySQL和SQL Server数据库中使用SQL编写代码来生成最近七天的日期数据。 MySQL示例 在MySQL中&#xff0c;可以使用日期函数和临时表来生成最近七天的日期。以下是一个示例代码&…

企业微信代开发应用登录操作

首先声明&#xff1a;企微的文档写得真烂&#xff01;&#xff01;&#xff01;有一些问题&#xff0c;官方情愿在问答区给用户一个个解答&#xff0c;也不愿意在文档写清楚&#xff0c;生怕自己工作量不饱和被优化。 概念说明 代开发应用&#xff0c;是相对于自建应用来说的。…

【后端学习笔记·Golang】邮箱邮件验证

文章目录 邮箱登陆验证生成随机验证码向用户邮箱发送验证码接口获取验证码校验验证码 邮箱登陆验证 流程&#xff1a; 接收用户请求后生成随机验证码&#xff0c;并将验证码存入Redis中&#xff0c;并设置TTL 通过gomail发送验证码给用户邮箱 接收用户输入的验证码&#xff…

[Swift]组件化开发

一、组件化开发基础 1.组件定义 在软件开发中&#xff0c;一个组件是指一个独立的、可替换的软件单元&#xff0c;它封装了一组相关的功能。组件通过定义的接口与外界交互&#xff0c;并且这些接口隔离了组件内部的实现细节。在Swift语言中&#xff0c;组件可以是一个模块、一…

CVaR模型

CVaR模型&#xff08;Conditional Value at Risk&#xff09;是一种风险管理工具&#xff0c;用于衡量金融资产或投资组合在不同市场条件下的风险。CVaR模型衡量的是在某个置信水平下&#xff08;通常是95%或99%&#xff09;资产或投资组合在损失情况下的平均损失。与VaR&#…