注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
wo4fisher的个人空间 https://home.eeworld.com.cn/space-uid-296469.html [收藏] [复制] [分享] [RSS]
日志

【得捷Follow me第4期】W5500-EVB-Pico PIO 挂载SD卡并实现文件读写访问

已有 427 次阅读2024-3-2 22:51 |个人分类:W5500-EVB-Pico

 

本节实现功能:通过使用第三方SD库,实现PICO 访问外扩SD卡,并实现读取卡的信息、显示SD卡目录列表、文件读写访问...

1. 准备 下载SD卡扩展库

地址:javascript:; 

概述:This library enables you to use SPI SD cards with RP2040-based boards such as Nano_RP2040_Connect, RASPBERRY_PI_PICO using either RP2040 Arduino-mbed or arduino-pico core. This SD-Fat v2 can support FAT16, FAT32, exFAT file systems. exFAT supports files larger than 4GB by using uint64_t as file offset.

该库主要为RP2040而来,支持FAT16, FAT32, exFAT,同时支持容量大于4GB。

*但是该库内部使用了PICO的spi0,由于W5500连接了SPI0,这里需要做一些改动,使得外扩SD卡连接到SPI1。

2. 创建基础工程,并将下载的库复制到工程的lib文件夹中

/*
  SD card connection
  This example shows how to read an SD Card's CardInfo
               shows how to read and write data to and from an SD card file
  The circuit:
   SD card attached to SPI bus as follows:
   // Arduino-pico core
   ** MISO - pin 12
   ** MOSI - pin 11
   ** CS   - pin 13
   ** SCK  - pin 10
*/
#include <Arduino.h>
#include <SPI.h>
#include <RP2040_SD.h>

#define _RP2040_SD_LOGLEVEL_   1
#define PIN_SD_SS    PIN_SPI1_SS
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
File root;

#define fileName  "example.txt"
File myFile;

uint32_t writeData  = 0xDEADBEEF;
uint32_t readData   = 0;

void printDirectory(File dir, int numTabs)
{
  while (true)
  {
    File entry =  dir.openNextFile();

    if (! entry)
    {
      // no more files
      break;
    }

    for (uint8_t i = 0; i < numTabs; i++)
    {
      Serial.print('\t');
    }

    Serial.print(entry.name());

    if (entry.isDirectory())
    {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    }
    else
    {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }

    entry.close();
  }
}

bool checkFileExist(const char * fileNameInput)
{
  // Check to see if the file exists now
  if (SD.exists(fileNameInput) )
  {
    Serial.print(fileNameInput);
    Serial.println(" exists.");

    return true;
  }
  else
  {
    Serial.print(fileNameInput);
    Serial.println(" doesn't exist.");

    return false;
  }
}

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);

  while (!Serial);

  delay(1000);

#if defined(ARDUINO_ARCH_MBED)
  Serial.print("Starting SD Card CardInfo on MBED ");
#else
  Serial.print("Starting SD Card CardInfo on ");
#endif

  Serial.println(BOARD_NAME);
  Serial.println(RP2040_SD_VERSION);

  Serial.print("Initializing SD card with SS = ");
  Serial.println(PIN_SPI1_SS);
  Serial.print("SCK = ");
  Serial.println(SPI1_SCK);
  Serial.print("MOSI = ");
  Serial.println(SPI1_MOSI);
  Serial.print("MISO = ");
  Serial.println(SPI1_MISO);

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, PIN_SPI1_SS))
  {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");

    while (1);
  }
  else
  {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.println();
  Serial.print("Card type:         ");

  switch (card.type())
  {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;

    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;

    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;

    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card))
  {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");

    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  if (!SD.begin(PIN_SD_SS))
  {
    Serial.println("Initialization failed!");
    return;
  }

  Serial.println("Initialization done.");

  root = SD.open("/");

  printDirectory(root, 0);

  Serial.println("read cardinfo done.");

  checkFileExist(fileName);
  
  // open a new file and immediately close it:
  Serial.print("Creating ");
  Serial.println(fileName);

  myFile = SD.open(fileName, FILE_WRITE);

  if (myFile)
  {
    myFile.write((uint8_t *) &writeData, sizeof(writeData));

    Serial.print("writeData = 0x");
    Serial.println(writeData, HEX);

    myFile.close();
  }
  else
  {
    Serial.print("Error open for writing ");
    Serial.println(fileName);
  }

  myFile = SD.open(fileName, FILE_READ);

  if (myFile)
  {
    myFile.read((uint8_t *) &readData, sizeof(readData));

    Serial.print("readData = 0x");
    Serial.println(readData, HEX);

    myFile.close();
  }
  else
  {
    Serial.print("Error open for reading ");
    Serial.println(fileName);
  }

  checkFileExist(fileName);

  // delete the file:
  Serial.println("Removing example.txt...");
  SD.remove(fileName);

  checkFileExist(fileName);
}

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

第一步:定义全局对象

Sd2Card card;

SdVolume volume;

File root;

第二步:使用card.init()进行SD卡初始化,内部使用了SPI1。

第三步:根据card.type() 输出SD卡类型。

第四步:volume.init(card) SD卡卷的初始化,并打印显示SD卡卷信息。

第五步:再次SD.begin()初始化SD卡,SD.open("/")打开SD卡根目录。

第六步:printDirectory(root, 0);遍历SD卡目录并通过串口打印显示。

第七步:checkFileExist()检测文件是否存在SD卡中,并通过函数SD.open、File.write、File.close、File.read、SD.remove等实现文件打开、增删改查。

 

3. 需要修改的地方

3.1. \.platformio\packages\framework-arduino-mbed\variants\RASPBERRY_PI_PICO\pins_arduino.h

增加:

// SPI1
#define PIN_SPI1_MISO  (12u)
#define PIN_SPI1_MOSI  (11u)
#define PIN_SPI1_SCK   (10u)
#define PIN_SPI1_SS    (13u)

 

修改:#define SPI_HOWMANY     (1) (MBED的库默认仅设置了SPI0 引脚的相关宏定义)

为:

#define SPI_HOWMANY		(2)

增加:

#define SPI1_MISO		(digitalPinToPinName(PIN_SPI1_MISO))
#define SPI1_MOSI		(digitalPinToPinName(PIN_SPI1_MOSI))
#define SPI1_SCK		(digitalPinToPinName(PIN_SPI1_SCK))

 

spi.h和spi.c文件相关内容如下:

spi1在定义的时候已经绑定了对应的引脚

 

 

3.2 RP2040_SD库下 RP2040_SD\src\utility\Sd2Card.cpp

修改 SDCARD_SPI SPI为:

#define SDCARD_SPI SPI1

 

 

 

 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章