SD card + Arduino IDE 如何提高SD card的读写速度

目录

一、前言

二、开发环境

三、实验原理与测试代码

(1)使用的是File.write()来写入数据,理论上会比File.print()要更快

(2)使用数据块来传输数据,也就是一次性写入尽可能多字节数的buffer

(3)尽可能提高SPI的始终频率,我的时钟频率达到了80MHz

(4)实际项目中我会使用多线程,把传感器的数据读取和SD卡的数据写入分开

(5)完整测试代码

四、总结


一、前言

SD卡几乎出现在每一个需要用到电子产品的场合。可移动存储设备TF卡、SD卡、U盘、移动硬盘这些都是我们所熟知的设备,而本文的初衷是记录一下对于SD card写入速度的测试过程,由于在工作项目中遇到对数据存储速率要求高的情况,所以本文重点会集中于如何提高SD card的写入速度,希望对大家有所帮助。

二、开发环境

硬件:ESP32S3 + SD card模块

硬件连接:

|---------|------|
| ESP32S3 | SD |
| 5V | VCC |
| GND | GND |
| PIN10 | CS |
| PIN11 | MOSI |
| PIN12 | SCLK |
| PIN13 | MISO |

软件:Arduino IDE

开发库:arduino-libraries/SD: SD Library for Arduino (github.com)

三、实验原理与测试代码

由于我买的测试模块是SPI连接方式的,所以还未对SD_MMC模式进行过读写速度测试。我的重点在于测试SD的写入速度,用于记录传感器的数据,参考了一些资料,大概SPI的最快读写速度会比SD_MMC模式慢50%。

测试代码设计与改动:

(1)使用的是File.write()来写入数据,理论上会比File.print()要更快
cpp 复制代码
  myFile = SD.open(filename, FILE_APPEND);
  
  if(myFile){
    for(int i = 0; i < 102; i++){
      myFile.write((uint8_t *)buffer, DATASIZE);
      //Serial.print("write over");
      myFile.flush();
    }
  }else{
    Serial.println("file open fail");
  }
  myFile.close();
(2)使用数据块来传输数据,也就是一次性写入尽可能多字节数的buffer

至少从1024字节往上增长,但是得要权衡有没有足够的空间来使用,在我的测试代码中我最后是直接用10240字节的buffer,后续没有测试了。(对于我的项目来说够用了)

cpp 复制代码
#define DATASIZE 10240        //10kb data

String dataBuffer;

char buffer[DATASIZE];
(3)尽可能提高SPI的始终频率,我的时钟频率达到了80MHz

这并不是最理想的时钟频率, 我查阅资料发现有的地方说40MHz以上就不会有很明显的提高效果了,但我最终还是直接使用了推荐值(有地方说是50MHz)

我觉得比较有意义的几个建议可以看这个连接的讨论:

sd card的写入速度 - ESP32 Forum

(4)实际项目中我会使用多线程,把传感器的数据读取和SD卡的数据写入分开

详细内容可以搜索多线程的相关知识点查看

(5)完整测试代码

如下:最终是达到了545KB/S,对于我的项目来说已经足够了

cpp 复制代码
/*
 * use SPI connect between ESP32S3 and Micro-SD,
 * CS 10, SCLK 12, MOSI 11, MISO 13
 * Last we have try to write 102 DATAbuffers(each for 10 kb data) into the SD card,
 * and we spend 1820~1840 ms for this process.
 * Write data rate : 545 KB/S(2024.09.28); 
 * 2s can write 1MB
 */

#include <SD.h>

#define DATASIZE 10240        //10kb data

const int CS_SD = 10;

const char filename[] = "/240929.csv";

File myFile;

String dataBuffer;

char buffer[DATASIZE];

unsigned long lastTime = 0, newTime = 0;

void setup() {
  Serial.begin(9600);

  while(!Serial);

  dataBuffer.reserve(DATASIZE);

  if(!SD.begin(CS_SD, SPI, 80000000)){
    Serial.println("SD init fail!");
    delay(2000);
  }

  Serial.println("initialize SD card succcessfully ");

  //every data need 3 bytes for number and 1 byte for ",", and "\n" for each 20 datas
  for(int i = 0; i < (DATASIZE/4 + DATASIZE*3/160); i++){
    if(i%20 == 0){
      dataBuffer += "\n";
    }
    else{
      dataBuffer += "123";
      dataBuffer += ",";
    }
  }

  strncpy(buffer, dataBuffer.c_str(), sizeof(buffer));
  
  myFile = SD.open(filename, FILE_WRITE);
  if(myFile){
    myFile.println("929 begin write in");
  }

  myFile.close();

  lastTime = millis();
  
  myFile = SD.open(filename, FILE_APPEND);
  
  if(myFile){
    for(int i = 0; i < 102; i++){
      myFile.write((uint8_t *)buffer, DATASIZE);
      //Serial.print("write over");
      myFile.flush();
    }
  }else{
    Serial.println("file open fail");
  }
  myFile.close();
  newTime = millis();
  
  newTime = newTime - lastTime;

  Serial.print("write data into SD card use: ");
  Serial.print(newTime);
  Serial.println(" ms");
  Serial.println("test over!");
}

void loop() {
  // put your main code here, to run repeatedly:

}

四、总结

目前来说达到的速度不是很让我满意,虽然够用,但是应该还有不小的提升空间,在后续会继续探索。

如果你有任何疑问欢迎到评论区留言,我会尽力回复。

如果对我所介绍的内容有任何改进的建议也欢迎告诉我!如果本文对你有帮助的话,不妨点个赞。欢迎留言讨论问题,一起讨论问题、解决问题。

另外,本账号所有文章内容均为原创,转载请标明出处。

相关推荐
promising-w4 分钟前
【蓝桥杯单片机】客观题
单片机·蓝桥杯
waicsdn_haha30 分钟前
Eclipse IDE 2025-03 最新版安装教程(官方下载+环境配置详解)
java·linux·开发语言·ide·windows·fpga开发·eclipse
小殷学长1 小时前
【单片机毕业设计14-基于stm32c8t6的智能宠物养护舱系统设计】
stm32·单片机·课程设计
charlie1145141911 小时前
从启动说起到单片机点灯发生了什么上——库层次
单片机·嵌入式硬件·arm汇编·初始化
W说编程2 小时前
在嵌入式Linux中实现高并发TCP服务器:从select到epoll的演进与实战
linux·服务器·c语言·嵌入式硬件·tcp/ip
美好的事情总会发生3 小时前
GMII(Gigabit Media Independent Interface)详解
linux·嵌入式硬件·硬件工程
坚定信念,勇往无前3 小时前
解决idea一个非常坑的问题
java·ide·intellij-idea
土井塔克树14123 小时前
VSCODE 终端执行PNPM 命令出错
ide·vscode·编辑器
咖啡虫13 小时前
使用快捷键高效管理 VSCode:提升工作效率,告别鼠标操作
ide·vscode·计算机外设
【云轩】14 小时前
【零基础实战】STM32控制DRV8833电机驱动详解
stm32·单片机·嵌入式硬件