问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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

创作时间:
作者:
@小白创作中心

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

引用
CSDN
1.
https://blog.csdn.net/idfengming/article/details/138080588

本文详细介绍了如何使用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引脚。

引脚名称 描述 引脚编号

CS Chip Select 5

SCK Clock 18

MISO Master In Slave Out 19

MOSI Master Out Slave In 23

1.3.2 代码一:


/*  

  SD Card Interface code for ESP32  

  SPI 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各个引脚进行了重定义

引脚名称 描述 引脚编号

CS Chip Select 23

SCK Clock 16

MISO Master In Slave Out 2

MOSI Master Out Slave In 17

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 ESP32  

  SPI 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,并延迟500ms  

  Serial.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()  

{  

}  
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号