0°

将Micro SD卡模块与Arduino连接

每隔一段时间你就会遇到一个想法,你需要为Arduino项目存储大量日志数据和其他信息,例如GPS记录器。大多数情况下,容易想到的EEPROM存储容量有限,并且存在可容纳的数据格式问题。所有这些使得它可能不是最好的做任何类型的数据记录,存储图形或音频。

解决方案是使用每个数码相机和MP3播放器中的有的东西:闪存卡!通常称为SD或micro SD卡。他们将GigaBytes数据打包到一个小于硬币的空间的能力使它们成为我们生活中不可或缺的东西。

现在许多计算机都配有内置SD或micro SD读卡器,因此您可以随时在Arduino项目和计算机之间来回移动数据。

硬件概述

虽然您可以轻松地在手机或计算机中插入micro SD卡并浏览所有文件; 硬件连接微型SD卡与Arduino或类似的开发板并不是那么容易。幸运的是,并非如此。这个项目使用微型SD卡模块,会为您提供很多帮助!

micro SD卡模块包含两个主要组件,无疑可以轻松地将数据记录添加到您的下一个Arduino项目中:

将Micro SD卡模块与Arduino连接
  • 任何标准微型SD卡的工作电压为3.3 V.因此我们无法直接将其连接到使用5V逻辑电路上。实际上,任何超过3.6V的电压都会永久损坏micro SD卡。这就是为什么; 该模块具有板载超低压差稳压器,可将3.3V – 6V的电压转换为~3.3V。
  • 模块上还有一个74LVC125A芯片,可将接口逻辑从3.3V-5V转换为3.3V。这称为逻辑电平转换。这意味着您可以使用该板与Arduino等3.3V和5V微控制器进行交互。

实际上有两种与micro SD卡接口的方式 – SPI模式和SDIO模式。SDIO模式速度更快,可用于手机,数码相机等。但它更复杂,需要签署保密文件。出于这个原因,像我们这样的业余爱好者可能永远不会遇到SDIO模式接口代码。相反,每个SD卡模块都基于“低速和低开销”SPI模式,任何微控制器都可以轻松使用。

Micro SD卡模块引脚

micro SD卡模块连接起来非常简单。它有六个引脚:

将Micro SD卡模块与Arduino连接

VCC引脚为模块供电,应连接到Arduino上的5V引脚。

GND应连接到Arduino的地。

MISO(主机输入从机输出)是Micro SD卡模块的SPI输出。

MOSI(主输出从输入)是Micro SD卡模块的SPI输入。

SCK(串行时钟)引脚接受时钟脉冲,同步Arduino产生的数据传输。

Arduino(主器件)使用SS(从器件选择)引脚来启用和禁用SPI总线上的特定器件。

准备micro SD卡

将micro SD卡插入模块并将其连接到Arduino之前,必须正确格式化卡。对于我们将要讨论的Arduino库,以及几乎所有其他SD库,该卡必须格式化为FAT16或FAT32。

如果你有一张新的SD卡,很可能已经预先格式化了FAT文件系统。但是,您可能会遇到工厂格式化卡的问题,或者如果它是旧卡,则需要重新格式化。无论哪种方式,在使用之前格式化卡片始终是个好主意,即使它是新的!

我们强烈建议您使用官方SD卡格式化程序实用程序 – 由SD协会编写,它解决了许多格式错误带来的问题!下载格式化程序并在您的计算机上运行,​​只需选择正确的驱动器,然后单击格式化。

将Micro SD卡模块与Arduino连接

接线 – 将Micro SD卡模块连接到Arduino

现在您的卡已准备好使用,我们可以连接micro SD分线板!

首先,将micro SD卡模块插入面包板。将模块上的VCC引脚连接到Arduino上的5V和GND引脚接地。现在我们继续使用用于SPI通信的引脚。

由于micro SD卡需要大量数据传输,因此当连接到微控制器上的硬件SPI引脚时,它们将提供最佳性能。使用另一组引脚,硬件SPI引脚比使用“bit-banging”接口代码要快得多。

请注意,每个Arduino板都有不同的SPI引脚,应相应连接。对于诸如UNO / Nano之类的Arduino板,这些引脚是数字13(SCK),12(MISO)和11(MOSI)。您还需要第四个引脚用于“芯片/从器件选择”(SS)线。通常这是引脚10,但你实际上可以使用你喜欢的任何引脚。

如果你有一个Mega,那么针脚是不同的!您将需要使用数字50(MISO),51(MOSI),52(SCK)和53(SS)。

将Micro SD卡模块与Arduino连接

好了!我们现在准备记录一些数据了!

Arduino代码 – 使用CardInfo测试SD卡模块

与SD卡通信需要做一堆工作,但幸运的是,Arduino IDE已经包含一个非常好的SD库,它简化了对SD卡的读写。您可以在示例子菜单中看到它。

接下来,选择CardInfo示例程序。

将Micro SD卡模块与Arduino连接

此程序不会向卡写入任何数据。它只是告诉你它是否设法识别卡,并显示有关它的一些信息。在尝试确定是否支持SD卡时,这非常有用。在尝试任何新卡之前,我们建议您运行此程序一次!

转到程序的开头并确保chipSelect线正确初始化,在我们的例子中,我们使用数字引脚#10,因此将其更改为10!

将Micro SD卡模块与Arduino连接

好的,现在将SD卡插入模块并上传程序。

一旦打开串行监视器,您可能会得到如下内容:

将Micro SD卡模块与Arduino连接

您可能会发现它是乱码,但看到卡类型是SDHC(SD高容量),卷类型是FAT32以及卡的大小约4 GB等是有用的。

如果你有一张坏卡,克隆版本似乎更多,你可能会看到:

将Micro SD卡模块与Arduino连接

该卡主要是响应,但数据都很糟糕。请参阅制造商ID / OEM ID,产品ID为“N / A”。这表明该卡返回了一些SD错误。这基本上是一个糟糕的场景。如果你得到这样的东西,你可以尝试重新格式化,或者如果它仍然散开,你应该扔卡。

最后,尝试取出SD卡并再次运行程序,您将得到以下信息,

将Micro SD卡模块与Arduino连接

看,它甚至无法初始化SD卡。如果出现接线错误或卡永久损坏,也会发生这种情况。

如果接线正确但SD卡格式不正确,您将得到如下内容:

将Micro SD卡模块与Arduino连接

Arduino代码 – 读写数据

考虑到您已成功初始化SD卡,我们将继续进行下一个实验。下面的程序将对从文件中写入和读取数据进行基本演示。在我们开始详细分解之前,先写入尝试程序:

程序首先包括内置的SD库和SPI库,使我们可以通过SPI接口轻松地与SD卡进行通信:

#include <SPI.h>
#include <SD.h>

在包含库之后,接下来我们要做的是声明chipSelect (CS)  SD卡模块的引脚所连接的Arduino引脚。CS引脚是唯一一个没有像任何Arduino数字引脚那样固定的引脚。我们不需要声明其他SPI引脚,因为我们使用的是硬件SPI接口,这些引脚已在SPI库中声明。在声明了引脚后,我们创建了一个对象myFile,稍后将用于将数据存储在SD卡上:

const int chipSelect = 10;
File myFile;

接下来,在以下setup() 部分中:我们启动串行通信以在串行监视器上显示结果。现在,使用该SD.begin() 函数我们将初始化SD卡,如果初始化成功,则“ if ”语句变为true并且字符串“ initialization done.“在串行监视器上打印,否则字符串”initialization failed!“打印出来,程序终止:

Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

接下来,该SD.open() 函数将打开名为“ test.txt ” 的文件。在我们的例子中,由于这样的文件不存在,它将被创建。另一个参数FILE_WRITE  以读写模式打开文件。

myFile = SD.open("test.txt", FILE_WRITE);

打开文件后,我们将在串行监视器上打印“ Writing to test.txt … ”消息,然后使用该myFile.println()  函数将文本“testing 1,2,3”写入文件。之后我们需要使用close() 函数来确保保存写入文件的数据:

  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening test.txt");
  }

现在让我们读取相同的文件来检查写操作是否成功。为此,我们将使用相同的函数SD.open() ,但这次因为文件“ test.txt ”已经创建,该函数将只打开文件。然后使用myFile.read()  我们将从文件中读取的函数并将其打印在串行监视器上。该read()  函数实际上一次只读取一个字符,因此我们需要使用“while”循环和函数myFile.available()  来读取文件中的所有字符。最后我们需要关闭文件:

myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }

由于这只是演示如何读取和写入文件的演示程序,因此没有必要多次运行代码,因此所有代码都放在setup() 只运行一次的函数中,而不是将其放在一个loop() 运行的函数中再来一次。

void loop() 
{
}

现在将代码上传到Arduino后,如果一切正常,串行监视器上将显示以下内容:

将Micro SD卡模块与Arduino连接

如果你重置你的Arduino并让程序再次运行; 写入的新数据将附加到文件中,而不会覆盖以前的数据:

将Micro SD卡模块与Arduino连接

有些事情需要注意

  • 您可以像Serial对象一样使用print()  println()  运行函数来编写字符串,变量等
  • Read()  一次只返回一个字符。它不读取整行或数字!
  • 完成后您必须close()  完成文件以确保永久写入所有数据!这减少了使用的RAM量。

SD库中的其他有用功能

SD  对象一起使用的函数 

您可以使用SD  对象使用一些有用的功能  。其中很少列出如下:

  • 如果您只想检查文件是否存在,请使用exists("filename.txt")  返回true或false的文件。
  • 您可以通过调用remove("unwanted.txt")   小心删除文件!这将真正删除它,并没有“回收站”将其拉出来。
  • 如果mkdir("/mynewdir")  要在某个位置填充文件,可以通过调用handy 来创建子目录。如果它已经存在则没有任何反应,但您可以随时SD.exists()  首先调用。

File  对象一起使用的函数 

此外,您可以使用File  对象的函数很少  :

  • 你可以seek() 在一个文件上。这会将读/写光标移动到新位置。例如,seek(0)  将带您到文件的开头,这可以非常方便!
  • 同样,你可以使用position() 告诉你你在文件中的位置。
  • 如果您想知道文件的大小,请调用size()  以获取文件中的字节数。
  • 目录/文件夹是特殊文件,您可以通过调用确定文件是否是目录 isDirectory()
  • 有了目录后,您可以通过调用开始浏览目录中的所有文件 openNextFile()
  • 您可能最终需要知道文件的名称,例如,如果您 在目录上调用openNextFile()。在这种情况下,调用name()  将返回指向8.3格式字符数组的指针,Serial.print()  如果需要,可以直接返回  。

Micro SD卡模块的已知问题

如果计划在同一SPI总线上使用多个从站,则可能会遇到问题。由于MISO缓冲器的ENABLE引脚13始终接地,因此其他从器件无法与主器件通信,因为信号会相互干扰。当未在公共SPI总线上选择时,从器件实际上需要激活MISO引脚上的高阻态。

因此,要使用其他从属设备以及此模块,您需要进行一些小的更改。首先将缓冲器的引脚13与地断开,然后将其连接到主器件的相应从器件选择引脚,可能需要上拉。这样,当未选择模块时,模块的MISO将变为高阻状态。

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论