SD vs SdFat. Проблема с библиотекой SdFat
- Войдите на сайт для отправки комментариев
Сб, 17/04/2021 - 13:10
У меня есть ардуинка Due, дисплей на 4" на чипе ST7796 и карта на 8 Гб с системой FAT32. На встроенном слоте на мониторчике карта совсем не запустилась, а на отдельном китайском модуле за 50 руб с библиотекой SD работает нормально. txt читаются редактируются и тд. Но имея цветной дисплей и карту грех не попробовать вывести картинку на экран. Экран работает на UTFT.
Подгрузил UTFT_SdRaw b SdFat взамен SD. Не работает. Запустил пример Sdinfo:
/* * This program attempts to initialize an SD card and analyze its structure. */ #include "SdFat.h" #include "sdios.h" /* Set DISABLE_CS_PIN to disable a second SPI device. For example, with the Ethernet shield, set DISABLE_CS_PIN to 10 to disable the Ethernet controller. */ const int8_t DISABLE_CS_PIN = -1; /* Change the value of SD_CS_PIN if you are using SPI and your hardware does not use the default value, SS. Common values are: Arduino Ethernet shield: pin 4 Sparkfun SD shield: pin 8 Adafruit SD shields and modules: pin 10 */ // SDCARD_SS_PIN is defined for the built-in SD on some boards. #ifndef SDCARD_SS_PIN const uint8_t SD_CS_PIN = 4; #else // SDCARD_SS_PIN const uint8_t SD_CS_PIN = SDCARD_SS_PIN; #endif // SDCARD_SS_PIN // Try to select the best SD card configuration. #if HAS_SDIO_CLASS #define SD_CONFIG SdioConfig(FIFO_SDIO) #elif ENABLE_DEDICATED_SPI #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(16)) #else // HAS_SDIO_CLASS #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(16)) #endif // HAS_SDIO_CLASS //const uint8_t SD_CS_PIN = 4; //------------------------------------------------------------------------------ SdFs sd; cid_t m_cid; csd_t m_csd; uint32_t m_eraseSize; uint32_t m_ocr; static ArduinoOutStream cout(Serial); //------------------------------------------------------------------------------ bool cidDmp() { cout << F("\nManufacturer ID: "); cout << uppercase << showbase << hex << int(m_cid.mid) << dec << endl; cout << F("OEM ID: ") << m_cid.oid[0] << m_cid.oid[1] << endl; cout << F("Product: "); for (uint8_t i = 0; i < 5; i++) { cout << m_cid.pnm[i]; } cout << F("\nVersion: "); cout << int(m_cid.prv_n) << '.' << int(m_cid.prv_m) << endl; cout << F("Serial number: ") << hex << m_cid.psn << dec << endl; cout << F("Manufacturing date: "); cout << int(m_cid.mdt_month) << '/'; cout << (2000 + m_cid.mdt_year_low + 10 * m_cid.mdt_year_high) << endl; cout << endl; return true; } //------------------------------------------------------------------------------ void clearSerialInput() { uint32_t m = micros(); do { if (Serial.read() >= 0) { m = micros(); } } while (micros() - m < 10000); } //------------------------------------------------------------------------------ bool csdDmp() { bool eraseSingleBlock; if (m_csd.v1.csd_ver == 0) { eraseSingleBlock = m_csd.v1.erase_blk_en; m_eraseSize = (m_csd.v1.sector_size_high << 1) | m_csd.v1.sector_size_low; } else if (m_csd.v2.csd_ver == 1) { eraseSingleBlock = m_csd.v2.erase_blk_en; m_eraseSize = (m_csd.v2.sector_size_high << 1) | m_csd.v2.sector_size_low; } else { cout << F("m_csd version error\n"); return false; } m_eraseSize++; cout << F("cardSize: ") << 0.000512 * sdCardCapacity(&m_csd); cout << F(" MB (MB = 1,000,000 bytes)\n"); cout << F("flashEraseSize: ") << int(m_eraseSize) << F(" blocks\n"); cout << F("eraseSingleBlock: "); if (eraseSingleBlock) { cout << F("true\n"); } else { cout << F("false\n"); } return true; } //------------------------------------------------------------------------------ void errorPrint() { if (sd.sdErrorCode()) { cout << F("SD errorCode: ") << hex << showbase; printSdErrorSymbol(&Serial, sd.sdErrorCode()); cout << F(" = ") << int(sd.sdErrorCode()) << endl; cout << F("SD errorData = ") << int(sd.sdErrorData()) << endl; } } //------------------------------------------------------------------------------ bool mbrDmp() { MbrSector_t mbr; bool valid = true; if (!sd.card()->readSector(0, (uint8_t*)&mbr)) { cout << F("\nread MBR failed.\n"); errorPrint(); return false; } cout << F("\nSD Partition Table\n"); cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n"); for (uint8_t ip = 1; ip < 5; ip++) { MbrPart_t *pt = &mbr.part[ip - 1]; if ((pt->boot != 0 && pt->boot != 0X80) || getLe32(pt->relativeSectors) > sdCardCapacity(&m_csd)) { valid = false; } cout << int(ip) << ',' << uppercase << showbase << hex; cout << int(pt->boot) << ','; for (int i = 0; i < 3; i++ ) { cout << int(pt->beginCHS[i]) << ','; } cout << int(pt->type) << ','; for (int i = 0; i < 3; i++ ) { cout << int(pt->endCHS[i]) << ','; } cout << dec << getLe32(pt->relativeSectors) << ','; cout << getLe32(pt->totalSectors) << endl; } if (!valid) { cout << F("\nMBR not valid, assuming Super Floppy format.\n"); } return true; } //------------------------------------------------------------------------------ void dmpVol() { cout << F("\nScanning FAT, please wait.\n"); uint32_t freeClusterCount = sd.freeClusterCount(); if (sd.fatType() <= 32) { cout << F("\nVolume is FAT") << int(sd.fatType()) << endl; } else { cout << F("\nVolume is exFAT\n"); } cout << F("sectorsPerCluster: ") << sd.sectorsPerCluster() << endl; cout << F("clusterCount: ") << sd.clusterCount() << endl; cout << F("freeClusterCount: ") << freeClusterCount << endl; cout << F("fatStartSector: ") << sd.fatStartSector() << endl; cout << F("dataStartSector: ") << sd.dataStartSector() << endl; if (sd.dataStartSector() % m_eraseSize) { cout << F("Data area is not aligned on flash erase boundary!\n"); cout << F("Download and use formatter from www.sdcard.org!\n"); } } //------------------------------------------------------------------------------ void printCardType() { cout << F("\nCard type: "); switch (sd.card()->type()) { case SD_CARD_TYPE_SD1: cout << F("SD1\n"); break; case SD_CARD_TYPE_SD2: cout << F("SD2\n"); break; case SD_CARD_TYPE_SDHC: if (sdCardCapacity(&m_csd) < 70000000) { cout << F("SDHC\n"); } else { cout << F("SDXC\n"); } break; default: cout << F("Unknown\n"); } } //------------------------------------------------------------------------------ void printConfig(SdSpiConfig config) { if (DISABLE_CS_PIN < 0) { cout << F( "\nAssuming the SD is the only SPI device.\n" "Edit DISABLE_CS_PIN to disable an SPI device.\n"); } else { cout << F("\nDisabling SPI device on pin "); cout << int(DISABLE_CS_PIN) << endl; pinMode(DISABLE_CS_PIN, OUTPUT); digitalWrite(DISABLE_CS_PIN, HIGH); } cout << F("\nAssuming the SD chip select pin is: ") << int(config.csPin); cout << F("\nEdit SD_CS_PIN to change the SD chip select pin.\n"); } //------------------------------------------------------------------------------ void printConfig(SdioConfig config) { (void)config; cout << F("Assuming an SDIO interface.\n"); } //----------------------------------------------------------------------------- void setup() { Serial.begin(9600); // Wait for USB Serial while (!Serial) { SysCall::yield(); } cout << F("SdFat version: ") << SD_FAT_VERSION_STR << endl; printConfig(SD_CONFIG); } //------------------------------------------------------------------------------ void loop() { // Read any existing Serial data. clearSerialInput(); // F stores strings in flash to save RAM cout << F("\ntype any character to start\n"); while (!Serial.available()) { SysCall::yield(); } uint32_t t = millis(); if (!sd.cardBegin(SD_CONFIG)) { cout << F( "\nSD initialization failed.\n" "Do not reformat the card!\n" "Is the card correctly inserted?\n" "Is there a wiring/soldering problem?\n"); if (isSpi(SD_CONFIG)) { cout << F( "Is SD_CS_PIN set to the correct value?\n" "Does another SPI device need to be disabled?\n" ); } errorPrint(); return; } t = millis() - t; cout << F("init time: ") << t << " ms" << endl; if (!sd.card()->readCID(&m_cid) || !sd.card()->readCSD(&m_csd) || !sd.card()->readOCR(&m_ocr)) { cout << F("readInfo failed\n"); errorPrint(); return; } printCardType(); cidDmp(); csdDmp(); cout << F("\nOCR: ") << uppercase << showbase; cout << hex << m_ocr << dec << endl; if (!mbrDmp()) { return; } if (!sd.volumeBegin()) { cout << F("\nvolumeBegin failed. Is the card formatted?\n"); errorPrint(); return; } dmpVol(); }
Видит
12:51:26.549 -> init time: 2 ms 12:51:26.549 -> 12:51:26.549 -> Card type: SDHC 12:51:26.549 -> 12:51:26.549 -> Manufacturer ID: 0X9F 12:51:26.596 -> OEM ID: TI 12:51:26.596 -> Product: SPCC 12:51:26.642 -> Version: 0.0 12:51:26.642 -> Serial number: 0XD109BE28 12:51:26.690 -> Manufacturing date: 9/2012 12:51:26.690 -> 12:51:26.690 -> cardSize: 7860.13 MB (MB = 1,000,000 bytes) 12:51:26.734 -> flashEraseSize: 128 blocks 12:51:26.780 -> eraseSingleBlock: true 12:51:26.780 -> 12:51:26.780 -> OCR: 0XC0FF8000 12:51:26.826 -> 12:51:26.826 -> SD Partition Table 12:51:26.826 -> part,boot,bgnCHS[3],type,endCHS[3],start,length 12:51:26.872 -> 1,0X0,0X82,0X3,0X0,0XB,0X9A,0XDF,0XBB,8192,15343616 12:51:26.967 -> 2,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0 12:51:26.967 -> 3,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0 12:51:27.014 -> 4,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0 12:51:27.060 -> 12:51:27.060 -> Scanning FAT, please wait. 12:51:27.574 -> 12:51:27.574 -> Volume is FAT32 12:51:27.621 -> sectorsPerCluster: 64 12:51:27.621 -> clusterCount: 239616 12:51:27.668 -> freeClusterCount: 239575 12:51:27.668 -> fatStartSector: 12638 12:51:27.714 -> dataStartSector: 16384 12:51:27.761 -> 12:51:27.761 -> type any character to start
Запускаю:
/* В качестве примера скопируйте файл «Arduino.raw» входящим в состав библиотеки «UTFT_SdRaw» на SD-карту */ #include <SPI.h> #include "SdFat.h" // расширенная библиотека для работы с SD-картой #include <UTFT.h> // библиотека для работы с дисплеем // библиотека для вывода изображений на дисплеей с SD-карты #include <UTFT_SdRaw.h> // пин ChipSelect к которому подключена SD-карта #define SD_CHIP_SELECT 4 // создаём объект работы с SD-картой SdFat sd; // создаём объект класса UTFT // и передаём идентификатор модели дисплея и номера управляющих пинов UTFT myGLCD(ST7796, 38, 39, 40, 41, 42); // объявления встроенного шрифта extern uint8_t BigFont[]; // создаём объект для работы и вывода изображений на дисплей UTFT_SdRaw myFiles(&myGLCD); void setup() { // инициализируем дисплей с вертикальной ориентацией myGLCD.InitLCD(); // очищаем экран myGLCD.fillScr(70,70,70); // выбираем большой шрифт myGLCD.setFont(BigFont); // ждём успешной инициализации SD-карты while (!sd.begin(SD_CHIP_SELECT)) { // устанавливаем красный цвет «чернил» для печати и рисования myGLCD.setColor(VGA_RED); // печатаем строку в указанной строке позиции myGLCD.print("SD Card failed!", CENTER, 100); delay(1000); } // устанавливаем зелённый цвет «чернил» для печати и рисования myGLCD.setColor(VGA_GREEN); // печатаем строку в указанной строке позиции myGLCD.print("SD Card initialised", CENTER, 100); // ждём 1 секунду delay(1000); // выводим изображение с SD-карты на дисплей myFiles.load(0, 0, 480, 320, "Tiger.raw"); } void loop() { }
Итог "SD Card failed!"
sd.begin всегда возвращается с False
При этом библиотека SD инициализирует без проблем, но картинку не выводит
* В качестве примера скопируйте файл «Arduino.raw» входящим в состав библиотеки «UTFT_SdRaw» на SD-карту */ #include <SPI.h> #include <SD.h> // расширенная библиотека для работы с SD-картой #include <UTFT.h> // библиотека для работы с дисплеем // библиотека для вывода изображений на дисплеей с SD-карты #include <UTFT_SdRaw.h> // пин ChipSelect к которому подключена SD-карта #define SD_CHIP_SELECT 4 // создаём объект работы с SD-картой // создаём объект класса UTFT // и передаём идентификатор модели дисплея и номера управляющих пинов UTFT myGLCD(ST7796, 38, 39, 40, 41, 42); // объявления встроенного шрифта extern uint8_t BigFont[]; // создаём объект для работы и вывода изображений на дисплей UTFT_SdRaw myFiles(&myGLCD); void setup() { // инициализируем дисплей с вертикальной ориентацией myGLCD.InitLCD(); // очищаем экран myGLCD.fillScr(70,70,70); // выбираем большой шрифт myGLCD.setFont(BigFont); // ждём успешной инициализации SD-карты while (!SD.begin(SD_CHIP_SELECT)) { // устанавливаем красный цвет «чернил» для печати и рисования myGLCD.setColor(VGA_RED); // печатаем строку в указанной строке позиции myGLCD.print("SD Card failed!", CENTER, 100); delay(1000); } // устанавливаем зелённый цвет «чернил» для печати и рисования myGLCD.setColor(VGA_GREEN); // печатаем строку в указанной строке позиции myGLCD.print("SD Card initialised", CENTER, 100); // ждём 1 секунду delay(1000); // выводим изображение с SD-карты на дисплей myFiles.load(0, 0, 480, 320, "Tiger.RAW"); } void loop() { }
В чем может быть проблема?
Точно не знаю, но по-моему для UTFT требуется конвертация картинки
Да, я конвертировал в RAW. Но почему SdFat не хочет инициализировать SD?