Підключення sd карти до мікроконтролера

В одній з минулих статей, ми виводили картинку на дисплей з sd картки, але в ній були втрачені деякі моменти, перший - підключення самої картки, другий - була розглянута лише частина функцій бібліотекиPetit FatFs, давайте зупинимося на цих моментах докладніше.

Спілкування з карткою можливе за одним із двох інтерфейсів,SPIабоSD.

функції

покажчик

покажчик

карти

Треба сказати, що інтерфейс SD може працювати в однобітному і чотирибітному режимах.

Схема підключення картки по SPI стандартна і виглядає наступним чином, висновки картки, що не використовуються, потрібно за допомогою резистора 10К підтягнути до живлення.

підключення

Але в аматорських конструкціях часто нехтують резисторами, що підтягують, спрощуючи схему підключення.

Треба відзначити, що при підключенні по SPI картка дуже вимоглива до напруги живлення і невелика просадка напруги живлення призводить до непрацездатності картки, це перевірено на особистому досвіді, з приводу SD інтерфейсу сказати нічого, ще не пробував. Це все писав до того, що з харчування обов'язково ставити конденсатори. Що стосується дроселя, він має бути розрахований на струм до 100мА, але ставити його необов'язково.

На схемах, зображених вище видно, що з роботи картці необхідно 3.3 вольта, відповідно, лініях передачі напруга має виходити за діапазон 0 – 3.3 вольт і виникає питання, що робити якщо МК живиться від 5 вольт? Ответ простий , Треба узгодити лінії передачі даних, а зробити це можна за допомогою звичайного резистивного дільника.

підключення

карти

З підключенням розібралися, тепер розглянемо як користуватися бібліотекоюPetit FatFs, яка призначена для 8-бітових мікроконтролерів з малим розміром пам'яті.

Бібліотека складається з 5 файлів:integer.h- заголовний файл, в якому описані основні типи даних.

diskio.h- заголовний файл, в якому оголошено прототипи низькорівневих функцій для роботи з диском та статусні коди, які вони повертають.

diskio.c- у цьому файлі мають бути реалізовані низькорівневі функції, спочатку там "заглушки".

pffсonf.h- конфігураційний файл.

pff.h- заголовний файл, в якому оголошено прототипи функцій взаємодії з файловою системою диска.

pff.c- файл містить реалізації функцій взаємодії з файлової системою диска.

Видно, що для того, щоб бібліотека запрацювала, необхідно реалізувати низькорівневі функції. Але якщо йдеться про AVR або PIC, для них на сайті можна завантажити приклад роботи з бібліотекою, в якому є файлmmc, в ньому вже реалізовані низькорівневі функції. Також необхідно встановити конфігурацію бібліотеки у файлі pff.h і написати функції необхідні для роботи SPI.

Функції Petit FatFs.

FRESULT pf_mount (FATFS*)— функція монтує/демонтує диск. Цю функцію необхідно викликати до початку роботи з диском, якщо викликати функцію з нульовим покажчиком диск демонтується. Функція може бути викликана будь-якої миті часу.

ПараметриFATFS* fs— вказівник на об'єкт типу FATFS, опис цієї структури можна переглянути у файлі pff.h. Нам треба лише оголосити змінну такого типу.

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_NOT_READY— пристрій не може бути ініціалізованийFR_DISK_ERR— виниклапомилка під час читання з дискаFR_NO_FILESYSTEM— на диску немає правильного розділу FAT

Параметриconst char * path- покажчик на рядок, що вказує шлях до файлу. Шлях треба вказувати повністю щодо кореневої директорії, поділяючи директорії слешем.

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_NO_FILE— файл не знайденийFR_DISK_ERR— помилка дискаFR_NOT_ENABLED— диск не було змонтовано

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_DISK_ERR— помилка дискаFR_NOT_OPENED— файл не був відкритийFR_NOT_ENABLED— диск не був змонтований

FRESULT pf_write(const void* buff, WORD btw, WORD* bw)— функція дозволяє записувати дані у відкритий файл. Для того, щоб функція працювала у файлі pffconf.h треба записати#define _USE_WRITE 1

Параметри:void* buff— покажчик на буфер, який хочемо записати, нульове значення фіналізує записWORD btw— кількість байт, які хочемо записатиWORD* bw— покажчик на змінну, що зберігає кількість байт, які вдалося записати. Аналізуючи, цю змінну можна дізнатися, чи було досягнуто кінець файлу.

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_DISK_ERR— помилка дискаFR_NOT_OPENED— файл не був відкритийFR_NOT_ENABLED— диск не був змонтований

Через те, що бібліотека розрахована на мікроконтролери з малим об'ємом пам'яті, ця функція має ряд обмежень:

  • не можна створювати нові файли, а записувати можна тільки в існуючі
  • не можна збільшувати розмір файлу
  • не можнаоновити тимчасову мітку
  • операцію запису можна розпочати/зупинити лише на межі сектора
  • файловий атрибут "тільки для читання" не може заборонити запис

Для того щоб зрозуміти передостанній пункт, треба знати, що пам'ять картки розбита на блоки (сектори) по 512 байт і запис можна почати тільки з початку сектора. Таким чином якщо ми хочемо записати 1000 байт, то перший сектор запишеться повністю, а в другий запишеться тільки 488 байт, а 24 байти, що залишилися, заповняться нулями.

Для запису у відкритий файл слід виконати такі дії:

  • встановити покажчик на кордон сектора, якщо встановити не на кордон, то покажчик буде округлений до нижньої межі сектора
  • викликати функцію запису потрібну кількість разів
  • фіналізувати запис, викликавши функцію з нульовим покажчиком

Для того, щоб навести приклад роботи функції запису, необхідно розглянути ще одну функцію.

FRESULT pf_lseek(DWORD offset)- встановлює покажчик читання/запису у відкритому файлі. Встановлювати покажчик можна абсолютним або відносним зміщенням, для абсолютного усунення необхідно передати в функцію число

для відносного, передати значення покажчика на поточну позиціюfs.fptrта величину зміщення

Для того, щоб функція працювала у файлі pffconf.h треба записати#define _USE_LSEEK 1

Параметри:DWORD offset- кількість байт, на які потрібно змістити покажчик.

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_DISK_ERR— помилка дискаFR_NOT_OPENED— файл не був відкритий

Записати дані у файл можна в такий спосіб.

Також залишаю тут шматокреально працюючого коду, в якому використовуються всі описані вище функції.

FRESULT pf_opendir(DIR* dp, const char * path)— функція відкриває існуючу директорію та створює покажчик на об'єкт типу DIR, який буде використовуватися для отримання списку файлів відкритої директорії. Для того щоб функція працювала в файлі pffconf.h треба записати#define _USE_DIR 1

Параметри:DIR *dp— покажчик змінної типу DIR.

const char * path— покажчик на рядок, що містить шлях до директорії, директорії поділяються слешем

Значення, що повертаються:FR_OK (0)— повертається у разі успішного виконання функціїFR_NO_PATH— не вдалося знайти шляхFR_NOT_READY— не вдалося ініціалізувати дискFR_DISK_ERR— помилка дискаFR_NOT_ENABLED— диск не було змонтовано

FRESULT pf_readdir(DIR* dp, FILINFO* fno)- функцію дозволяє прочитати вміст директорії. Для цього потрібно відкрити директорію за допомогою функції pf_opendir() та викликати pf_readdir(). Кожний раз при викликі функція повертатиме назву об'єкта (папки/файлу), що лежить у зазначеній директорії. Коли вона пройдеться всіма об'єктами, поверне нульовий рядок в елементі масиву fno.fname[]. Для того щоб функція працювала у файлі pffconf.h треба записати#define _USE_DIR 1

Параметри:DIR *dp— покажчик на змінну типу DIR, яка має бути попередньо оголошена

FILINFO *fno— вказівник на змінну типу FILINFO, яка має бути попередньо оголошена.

Значення, що повертаються:FR_OK- успішне завершення функціїFR_DISK_ERR- помилка дискаFR_NOT_OPENED- не відкрита директорія