Arduino案例实操 -- Arduino SD卡读写(Mega2560)

写这篇博客的主要原因是踩坑了,而且还是官方的坑,网上能找到的有营养的资源少, 在这记录顺便分享一下。(Mega2560 以下简称 2560)


SD卡官方例程库

用过Arduino的人都基本知道Arduino IDE有针对SD卡文件操作的相关的库,即SD库,默认已经安装在IDE中,可以在示例中打开SD库的demo
在这里插入图片描述
SD库ReadWrite示例代码如下,这看起来好像也没什么毛病,通过SPI总线对SD卡进行操作

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

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}


但是上传到2560就是一直串口打印 Initializing SD card...initialization failed! 复位几次也是一样的串口打印
在这里插入图片描述

于是乎我注意到了最上面的例程介绍

/*
  SD card read/write

  This example shows how to read and write data to and from an SD card file
  The circuit:
   SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

  created   Nov 2010
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

*/

其中标明了示例的SPI引脚为 MOSI - pin 11,MISO - pin 12,CLK - pin 13,CS - pin 4 ,其中片选脚CS备注是连接SD卡片选脚,注释的SPI引脚明显是UNO的SPI,然后接了UNO,确实,对SD卡的读写成功
在这里插入图片描述
示例中没有对SPI引脚做定义的地方,只有开头注释说明了连接的SPI对应引脚,所以我找到库函数定义去了,将SPI库和SD库看了个遍,依旧没能找到引脚定义的地方,奇了怪了这是!!

强行在2560上进行示例测试
  • 第一种方法 - 无视注释,直接用2560的SPI引脚对SD卡进行读写操作,2560 对应SPI引脚如下
#define PIN_SPI_SS    (53)
#define PIN_SPI_MOSI  (51)
#define PIN_SPI_MISO  (50)
#define PIN_SPI_SCK   (52)

程序运行得到的结果是 Initializing SD card...initialization failed! !!!

  • 第二种方法 - 2560按照注释上的SPI引脚去连接
MOSI - pin 11
MISO - pin 12
CLK  - pin 13
CS   - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

结果同样的 Initializing SD card...initialization failed! !!!

。。。。。。

正确解决方法

所幸的是博主在某些相似问题的评论中搜刮到别人的解决经验,简直不要太简单 -_-
只需要将SD库demo中的UNO片选引脚改为2560的片选引脚(Setup函数中的SD卡检测函数中)

//UNO的SPI片选引脚为Pin 4
if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
}

改为

//Mega 2560的SPI片选引脚为Pin 53
if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    while (1);
}

SPI引脚不需要在代码中声明引脚,因为默认是用每块Arduino控制板的硬件SPI,所以硬件接线上也是连的2560硬件SPI引脚

#define PIN_SPI_SS    (53)
#define PIN_SPI_MOSI  (51)
#define PIN_SPI_MISO  (50)
#define PIN_SPI_SCK   (52)

SD库demo串口打印,瞬间有种春暖花开的感觉 ~ 。~

在这里插入图片描述

总结
  1. 使用2560读写SD卡只需连接硬件SPI引脚,修改demo中 SD.begin(CS_Pin) 的片选引脚即可正常运行demo,如要使用到其他SD卡操作函数例如SD卡内容擦除等请自行阅读SD库函数
  2. 根据2560的SD库调试经验可知,在同样拥有硬件SPI引脚的Arduino控制板上,只需要正确连接其引脚跟修改程序中的片选引脚,同样适用于其他的Arduino控制板,简而言之,博文中的方法不止局限于UNO和2560
  3. 或许该方法同样使用于Arduino Core for ESP8266中ESP8266对SD卡的读写等操作了,这属于题外话了,博主尚未去尝试,但你们有兴趣的就do it !
  • 11
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
当你使用 Arduino操作 Mega2560 的寄存器时,你可以通过以下步骤进行: 1. 引入相应的头文件:在你的 Arduino 代码中,首先需要引入相关的头文件。对于 Mega2560,你需要包含 "avr/io.h" 和 "avr/interrupt.h" 这两个头文件。 2. 定义寄存器常量:根据 Mega2560 数据手册,你可以找到寄存器的地址和位定义。将这些地址和位定义作为常量进行定义,以便在代码中使用。 3. 设置寄存器的值:通过将特定的值写入寄存器,可以配置和控制硬件。使用赋值操作符(=)将所需的值写入相应的寄存器。 4. 读取寄存器的值:通过读取寄存器的值,可以获取硬件的状态或数据。使用寄存器名称即可读取其当前值。 下面是一个简单的示例代码,演示了如何操作 Mega2560 的寄存器来控制一个 LED 灯: ```c #include <avr/io.h> // 定义寄存器地址和位定义 #define LED_PIN 13 #define LED_DDR DDRB #define LED_PORT PORTB void setup() { // 设置LED引脚为输出 LED_DDR |= (1 << LED_PIN); } void loop() { // 点亮LED LED_PORT |= (1 << LED_PIN); delay(1000); // 关闭LED LED_PORT &= ~(1 << LED_PIN); delay(1000); } ``` 在上面的代码中,我们通过设置 `LED_DDR` 寄存器的第 5 位为 1,将 LED 引脚(13 号引脚)设置为输出模式。然后,在 `loop()` 函数中,我们使用位操作符将 `LED_PORT` 寄存器的第 5 位设置为 1 或 0,以点亮或关闭 LED。 请注意,直接操作寄存器需要对硬件有一定的了解,并且需要谨慎操作,以免影响其他功能或引起不可预期的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GenCoder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值