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…

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…

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…

【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;一个…

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

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

[Swift]组件化开发

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

车企如何利用数据技术,指导汽车全生命周期的业务运营?

引言&#xff1a;数据正作为重点&#xff0c;为行业提供不可或缺的指导 《汽车数据发展研究报告&#xff08;2023&#xff09;》指出&#xff0c;汽车行业正由传统硬件制造向“电动化、智能化、网联化”方向转变。德勤预测&#xff0c;到 2025 年&#xff0c;汽车行业 20%的利…

K8s: 部署 kubernetes dashboard

部署 Dashboard K8s 官方有一个项目叫 dashboard&#xff0c;通过这个项目更方便监控集群的状态 官方地址: https://github.com/kubernetes/dashboard 通常我们通过命令行 $ kubectl get po -n kube-system 能够查看到集群所有的组件&#xff0c;但这样的方式比较不太直观 …

【JavaScript】内置对象 ③ ( Math 内置对象 | Math 内置对象简介 | Math 内置对象的使用 )

文章目录 一、Math 内置对象1、Math 内置对象简介2、Math 内置对象的使用 二、代码示例1、代码示例 - Math 内置对象的使用2、代码示例 - 封装 Math 内置对象 一、Math 内置对象 1、Math 内置对象简介 JavaScript 中的 Math 内置对象 是一个 全局对象 , 该对象 提供了 常用的 数…

通过 QEMU 试用 ESP32-C3 的安全功能

概述 ESP32-C3 系列芯片支持可信启动、flash 加密、安全存储等多种安全功能&#xff0c;还有专用外设来支持 HMAC 和数字签名等用例。这些功能所需的私钥和配置大多存储在 ESP32-C3 的 eFuse 存储器中。 启用安全功能时需要谨慎&#xff0c;因为使用到的 eFuse 存储器是一次…

安卓studio插件开发(一)本地搭建工程

下载idea 社区版本 建立IDE Plugin工程 点击create就行&#xff0c;新建立的工程长这样 比较重要的文件 build.gradle&#xff1a;配置工程的参数 plugin.xml&#xff1a;设置插件的Action位置 build.gradle.kts内容如下&#xff1a; plugins {id("java")id(&quo…

【网络安全】安全事件管理处置 — 事件分级分类

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、安全事件分级 二、应急事件分级 三、安全事件分类 四、常见安全事件原因分析 1.web入侵 2.漏洞攻击 3.网络攻击 一、安全事件分级 在对安全事件的应急响应过程中&#xf…