В большинстве проектов с Ардуино необходимо устанавливать вспомогательное хранилище для медиафайлов, будь это видео или аудио. Если возникает необходимость хранить и обрабатывать информацию, а стоковой флеш-памяти плат вам не хватает, то есть несколько решений.

Можно докупить специальную плату, обеспечивающую быстрый доступ к данным, но и стоящую не малых денег. Если же у вас нет желания тратиться, то расширить стоковую память платы можно и с arduino card SD, дабы не было проблем с записью и стиранием стоковых утилит с чипов. Однако далеко не все новички знают, как правильно подключать флешку к чипу и что для этого нужно. Давайте разберёмся во всех нюансах и узнаем, какие подводные камни такого решения вас поджидают.

Что необходимо знать при подключении SD card к Arduino

Прежде чем подсоединять что-либо, следует изучить нюансы, которые будут подстерегать вас на каждом шагу. Первое, с чем вам придётся столкнуться, это вольтаж карт памяти, ведь они рассчитаны на 3.3 В, что является стандартом.

Неудобство заключается в том, что для записи данных необходима и соответствующая сила тока, вплоть до 100 мА, если речь о действительно больших массивах информации. Соответственно, необходимо обеспечить всю систему хорошим источником питания, но основная проблема заключается в том, что карты крайне привередливы. Если вы будете пользоваться резисторами и длинными проводниками, то скорость записи и чтения может упасть в разы ниже средних показателей, поэтому следует обзавестись небольшими коннекторами и убрать, по возможности, всё сопротивление из цепочки для питания логики.

Чтобы не сжечь всю плату, достаточно прикупить преобразователи переменного и постоянного тока, лучше всего подойдут приборы под HEF4050 и 74FHC125 базу.

  1. SPI. Универсален, и подойдёт для любого микроконтроллера, а подключение требует всего четыре пина.
  2. SDIO. Хороший выбор, если необходима высокая скорость передачи информации, но с arduino microsd реализуется крайне тяжело.

Учитывайте и формат карты, он не влияет ровным счётом ни на что, кроме размера вашей конечной поделки. Если необходимо серьёзно урезать габариты, то хорошим выбором станет microSD.

Сама по себе флешка – это небольшой чип со специально выделенными секторами, а соответственно, структур, обязательных к использованию, вы здесь не найдёте. Такой подход удобен для быстрого форматирования и сохранения данных в подходящей файловой системе.

Большинство устройств на сегодняшний день пользуются форматами NTFS, FAT32 и FAT16. Но чем сложнее система, тем больше памяти для работы arduino SD придётся выделить, что чревато последствиями в виде подлагиваний и плохой скорости отклика.

Схема подключения SD card к Arduino

Предварительно отформатировав карту памяти, приступайте к её подключению.

Платы расширений облегчат задачу, ведь они позволят урегулировать напряжение до необходимых нам 3.3 В, а контроллеры уровня преобразуют питание логики в подходящие для флешки.

Плата расширений потребуется под микроконтроллеры до 5 В, учитывайте это при её выборе. Главное достоинство Ардуино – простота, и подключение вспомогательных модулей не стало исключением. Лучшим выбором станет именно структура запуска через hardware SPI пины, дабы не усложнять новичкам жизнь. Нам потребуются 13, 12 и 11 цифровые пины, а также четвёртые, чтобы наладить «chip\slave select» цепь. Под это, зачастую, берётся 10 пин, но если вы знаете, что делаете, можете выбрать и более подходящий.


Обратите внимание на то, что в зависимости от форм-фактора и типа платы Ардуино, точки подключения могут варьироваться. Например, для меги необходимо соединить цепь с 50, 51, 52 и 53 слотом.

В последующие разы вы можете поэкспериментировать с последними пинами на обеих картах, но поначалу лучше выбрать именно те, что указаны выше. Так вы сможете отработать код, избавившись от нежелательных поломок и осечек, что значительно упростит задачу в будущем. Оставшиеся 5 В и GND подсоединяйте к соответствующим портам, здесь никаких особых инструкций нет.

Еще один вариант наглядной схемы:

В конце процедуры необходимо замкнуть CD в заземление, так система не сможет инициализировать карту памяти. Но, в случае необходимости, всегда можно применить резисторы в 10 кОм и вспомогательные порты, однако мы не будем останавливаться на этом пине, так как сейчас он нам не нужен.

Загрузка библиотек и запуск SD card на Arduino

Чтобы подсоединиться к SD карте и свободно передавать на неё данные, потребуется написать немало кода, однако здесь нам поможет встроенная библиотека SD.

Библиотеку по работе с картами памяти можно найти на официальном сайте производителя микроконтроллера: https://www.arduino.cc/en/Reference/SD

Открыв подменю «образцов», найдите заготовку «cardinfo», именно её мы не будем использовать в качестве прописной функции при загрузке информации. Скетч пригодится лишь для проверки, опознаётся ли дополнительная память на устройстве. Проверяйте chipSelect, учитывая, что подключение идёт через 10 пин.

#include const int chipSelect = 4; void setup() { Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. } Serial.print(“Initializing SD card…”); pinMode(10, OUTPUT); //iniot SD card if (!SD.begin(chipSelect)) { Serial.println(“Card failed, or not present”); return; } Serial.println(“card initialized.”); } void loop() { String dataString = “”; // read three sensors and append to the string for (int analogPin = 0; analogPin < 3; analogPin++) { int sensor = analogRead(analogPin); dataString += String(sensor); if (analogPin < 2) { dataString += “,”; } } // open the file. File dataFile = SD.open(“data.txt”, FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println(dataString); dataFile.close(); } // if the file isn’t open else { Serial.println(“error opening data.txt”); } }

Если всё прошло удачно, то на экран выведется информация о типе файловой системы и объёме вашей SD-карты. Если же производитель подсунул вам не лучший продукт, могут возникнуть ошибки. Здесь проще купить новую флешку, чем бороться с ошибками файловой системы, изначально заложенными в девайс.

Когда вы получите отклик от системы, можете начинать подгружать библиотеки и нужные вам файлы. SD-карта полностью работает и подключена, однако не забудьте протестировать несколько типов файловых систем, дабы подобрать оптимальный вариант по скорости и потреблению ресурсов. В каждом конкретном случае эти параметры будут разными, поэтому не бойтесь экспериментировать.

Заключение

SD-карта – необходимый элемент любой системы, в которой вы собираетесь использовать медиафайлы. Это будет хорошим решением как для приборов под «умный дом», так и для самодельных плееров. Однако не забывайте, что качество конечного продукта приравнивается к качеству его худшего компонента, и не стоит экономить на SD-картах.

Михаил Русских

Приводится краткая информация о SD-картах, даются основы принципа работы шины SD, поясняется порядок использования драйвера stm324xg_eval_sdio_sd, предназначенного для упрощения связи микроконтроллеров семейства STM32 с SD-картами

Некоторые встраиваемые системы должны иметь возможность хранения больших объемов информации. Например, регистраторы различных физических величин и параметров (ток, напряжение, температура, географические координаты) должны сохранять полученные с датчиков показания на определенном носителе, который впоследствии можно было бы извлечь из устройства и подключить к компьютеру для просмотра данных в удобном для пользователя виде. Для решения такой задачи наиболее очевидным кажется использование USB флеш-накопителей. Они широко распространены на рынке и позволяют хранить большие объемы информации. Но для некоторых малых встраиваемых систем первостепенным фактором является компактность, и габариты этих накопителей могут оказаться чрезмерными. Кроме того, не все микроконтроллеры оснащены модулем USB, и разработчик системы может довольно долго разбираться с USB-стеком, что может увеличить время работы над проектом. В связи с этим хорошей альтернативой USB является использование SD-карт, которые очень компактны и позволяют обмениваться данными с помощью распространенного интерфейса SPI или специального интерфейса для SD-карт.

Карты памяти SD (Secure Digital) разработаны, в основном, для применения в портативных устройствах. Сегодня на рынке существует большое количество моделей, предоставляемых такими компаниями как SanDisc, и способных записывать с зависящей от класса скоростью данные объемом от 8 МБ до 2 ТБ. SD-карты, в отличие от MMC-карт, помимо обычной области хранения данных имеют специальную защищенную область, которая недоступна обычному пользователю. Для того чтобы устройство смогло прочитать записанную на SD-карту информацию в виде файлов, эта карта должна иметь определенную файловую систему. Наиболее предпочтительной в данном случае является система FAT, поскольку количество циклов записи/чтения для SD-карт ограничено, а системы вроде NTFS и ext являются журналируемыми, то есть предполагающими частые опросы.

Передача и прием данных осуществляется по интерфейсу SPI или по шине SD. На Рисунке 1 показано расположение выводов SD-карт различных типов, а в Таблице 1 представлено функциональное назначение этих выводов.

Таблица 1. Функциональное назначение выводов SD-карт

Интерфейс SPI

Интерфейс SD

Карты SDC

Карты miniSD

Карты microSD

Хотя с помощью SPI организация связи хост-контроллера с картой не вызывает затруднений, все же шина SD предоставляет больше возможностей и позволяет пересылать информацию с большей скоростью за счет наличия четырех линий передачи данных. Поэтому ниже более подробно рассмотрим именно этот способ работы с SD-картой.

Передача данных по шине SD

Связь с SD-картой осуществляется по 6 информационным линиям: 4 линиям данных (DAT0, DAT1, DAT2, DAT3), линии синхронизации (CLK), линии передачи команд (CMD). При подключении к контроллеру линии данных и линия передачи команд должны быть подтянуты к питанию, как показано на Рисунке 2.

Запись и чтение данных выполняются поблочно. Обычно блок состоит из 512 байтов. Передача данных и служебной информации основана на модели взаимодействия «команда-ответ». Перед передачей или приемом данных хост-контроллер должен отправить соответствующую команду по линии CMD. По этой же линии от SD-карты должен прийти ответ, после которого может быть осуществлено требуемое действие. Стандарт SD поддерживает присутствие нескольких ведомых на шине, в таком случае хост-контроллер может посылать команды широковещательно. Команда имеет четкую структуру, состоящую из 48 бит: 1 стартовый бит, 1 бит передачи (установлен в 1), 6 бит для индекса команды, 32 бита для аргумента, 7 бит для контрольной суммы и 1 стоповый бит. Ответ может иметь такую же 48-битную структуру (в этом случае бит передачи установлен в 0) или состоять из 136 битов (т. н. формат длинного ответа): 1 стартовый бит, 1 бит передачи (установлен в 0), 6 зарезервированных битов, 127 битов содержимого регистров CID (Card Identifiction Register) или CSD (Card Specific Data Register) и контрольной суммы, 1 стоповый бит.

В начале работы с картой хост-контроллер перезагружает карту с помощью команд GO_IDLE_STATE (CMD0) и IO_RW_DIRECT (CMD52) . Полный список команд с описанием можно найти в (приложение A). После перезагрузки карта восстановит свои настройки по умолчанию, и ее адрес будет равен RCA = 0x0001. Если к хосту подключено несколько карт, то с помощью команды SET_RELATIVE_ADDR (CMD3) он задает каждой карте собственный адрес. Также в начале работы выполняется проверка поданного на карту напряжения. Напряжение карты должно быть в строго установленном диапазоне от 2.7 до 3.6 В. В связи с этим хост-контроллер с помощью команды SEND_OP_COND (CMD1 или ACMD41 ) обязан узнать текущее напряжение на карте и прекратить с ней работу, если оно не входит в требуемый диапазон. Таков общий принцип инициализации карты, для выполнения которой, в зависимости от типа карты (MMC, SD, SD I/O), могут использоваться другие команды и выполняться дополнительные шаги, поэтому при реализации низкоуровневого интерфейса нужно внимательно прочитать документацию на карту и изучить команды CMD.

Во время записи хост передает карте один или несколько блоков, используя команду WRITE_BLOCK (CMD24) или WRITE_MULTIPLE_BLOCK (CMD25) , соответственно, при этом в конце каждого блока хост записывает контрольную сумму. Карта, запись данных для которой разрешена, всегда будет в состоянии принять блок(и), но если контрольная сумма не совпадет, то карта сообщит об ошибке и не запишет текущий блок в свою память, а в случае пакетной передачи следующие блоки будут проигнорированы.

Передать информацию хосту, то есть выполнить чтение, также можно одним блоком с помощью команды READ_SINGLE_BLOCK (CMD17) или пакетом из нескольких блоков с помощью команды READ_MULTIPLE_BLOCK (CMD18) . В случае пакетной передачи хост может прервать чтение в любое время, отправив команду STOP_TRANSMISSION (CMD12) . Если в ходе передачи нескольких блоков внутренний контроллер карты зафиксирует ошибку, то он остановит передачу данных хост-контроллеру, но оставит карту в режиме передачи данных. В таком случае хосту придется принудительно завершить чтение с помощью команды CMD12 , при этом в ответе на эту команду карта сообщит об ошибке чтения.

Организация правильной работы шины SD является достаточно трудоемким процессом, поскольку помимо общих ситуаций, описанных выше, необходимо предусматривать различные нюансы в поведении карты и реализовывать дополнительные обработчики ошибок. Поэтому наиболее рациональным решением будет использование специальных библиотек, позволяющих разработчику не вдаваться в подробности передачи данных на аппаратном уровне и существенно сократить время разработки. Одной из таких библиотек, о которой пойдет речь ниже, является библиотека-драйвер stm324xg_eval_sdio_sd для популярных микроконтроллеров , позволяющая существенно упростить работу с модулем SDIO, предназначенным для взаимодействия с SD-картами.

Драйвер stm324xg_eval_sdio_sd

Этот драйвер представляет собой библиотеку функций, с помощью которых можно реализовать высокоуровневый интерфейс для обмена данными с SD-картой. Драйвер поставляется для работы с отладочной платой STM324VG (UtilitiesSTM32_EVALSTM3240_41_G_EVAL), но после изменения функций, связывающих эту библиотеку с низкоуровневым интерфейсом SDIO он может функционировать со многими микроконтроллерами семейства STM32, в составе которых имеется модуль SDIO. Из предыдущего предложения следует, что к проекту должны быть подключены файлы из стандартной библиотеки Standard Peripheral Library , обеспечивающие функционирование модуля SDIO на низком уровне. Например, для микроконтроллеров серии STM32F4xx это будут файлы stm32f4xx_sdio.c и stm32f4xx_sdio.h .

Перед использованием функций драйвера программист должен связать этот драйвер с аппаратной частью, то есть настроить линии модуля SDIO. Для этого ему нужно в основном файле своей программы main.c создать функции SD_LowLevel_Init() (для включения модуля SDIO) и SD_LowLevel_DeInit() (для отключения модуля SDIO), в которых необходимо выполнить конфигурирование этих линий. Если программист желает использовать модуль прямого доступа к памяти для увеличения скорости работы с SD-картой, то ему также нужно будет создать функции SD_LowLevel_DMA_TxConfig() и SD_LowLevel_DMA_RxConfig() , отвечающие за передачу и прием данных с помощью модуля ПДП. В качестве примера инициализации четырех указанных функций можно взять код, имеющийся в файле stm324xg_eval.c из (UtilitiesSTM32_EVALSTM3240_41_G_EVAL).

Теперь рассмотрим основные функции для работы с SD-картой, предоставляемые этим драйвером. Для того, чтобы инициализировать карту, нужно вызвать функцию SD_Init() , которая настраивает модуль SDIO, обращаясь к SD_LowLevel_Init() , проверяет тип SD-карты, получает служебную информацию из регистров CID и CSD, задает скорость передачи данных (по умолчанию 24 МГц) и устанавливает ширину шины (4 бита). Прочитать данные, полученные с карты, можно с помощью функций SD_ReadBlock() (для чтения одного блока) и SD_ReadMultiBlocks() (для чтения нескольких блоков). Чтобы записать данные на карту, используют функции SD_WriteBlock() (для записи одного блока) и SD_WriteMultiBlocks() (для записи нескольких блоков). Эти функции чтения и записи принимают три аргумента: buffer (переменная-буфер, в которую должны помещаться данные для чтения и записи), address (адрес ячейки памяти SD-карты) и block_size (всегда 512, поскольку эти функции работают только с блоками длинной 512 байтов). Для стирания определенной области памяти карты имеется функция SD_Erase() . В качестве аргументов она принимает startaddr и endaddr. В первом указывается адрес ячейки памяти, с которой начнется стирание, а во втором - адрес ячейки, на которой стирание будет завершено.

Передача данных между модулем SDIO и памятью микроконтроллера может осуществляться как обычным путем через центральный процессор, так и через блок прямого доступа к памяти. Для выбора необходимого режима нужно в файле stm324xg_eval_sdio_sd.h раскомментировать либо строчку #define SD_POLLING_MODE (обычный режим), либо строчку #define SD_DMA_MODE (режим ПДП). После любой операции записи или чтения необходимо с помощью функции SD_GetStatus() проверять, завершила ли карта текущую операцию, и готова ли она к приему или отправке новых данных. Если эта функция вернула значение SD_TRANSFER_OK, то передача завершена успешно, возврат SD_TRANSFER_BUSY означает, что канал передачи занят, а возврат SD_TRANSFER_ERROR сообщает об ошибке передачи. Все эти значения определены в структуре SDTransferState , записанной в stm324xg_eval_sdio_sd.h . Если передача информации выполнялась через блок ПДП, то дополнительно нужно проверять, завершил ли контроллер ПДП все операции по пересылке данных. Это делается с помощью функции SD_ReadWaitOperation() . Также стоит отметить, что передача через блок ПДП завершается прерыванием, поэтому программисту необходимо организовать вызов функции SD_ProcessIRQ() в обработчике прерываний модуля SDIO SDIO_IRQHandler() и вызов функции SD_ProcessDMAIRQ() в обработчике прерываний DMA2 DMA2_Streamx_IRQHandler() .

Для лучшего понимания принципа работы драйвера stm324xg_eval_sdio_sd можно воспользоваться рабочим примером из папки SDIOSDIO_uSDCard (ProjectSTM32F4xx_StdPeriph_ExamplesSDIO). С помощью этой тестовой программы можно выполнить стирание определенной области памяти карты, запись данных по определенному адресу, чтение данных по этому же адресу с последующим сравнением отправленной и принятой информации. Идентичность буфера приема и буфера отправки является свидетельством того, что модуль SDIO, шина передачи информации и SD-карта функционируют нормально.

Таким образом, можно сказать, что SD-карты являются достойными конкурентами USB флеш-накопителей, когда речь заходит о проектировании малых встраиваемых систем, требующих хранения больших объемов данных. Передавать информацию с карты и на карту можно с помощью интерфейса SPI или по шине SD, которая разработана для этих целей и обеспечивает высокую скорость передачи. Реализация связи с картой существенно упрощается при использовании специальных драйверов, облегчающих работу с аппаратной частью и предлагающих программистам простые в использовании функции. Но, к сожалению, записанные в произвольном порядке данные не будут восприняты какой-либо операционной системой, например, Windows, поэтому в следующей части будет рассмотрен порядок работы с SD-картой, имеющей файловую систему FAT.

Список источников

В устройствах на микроконтроллерах для хранения больших объемов данных используется внешняя память. Если требуется хранить единицы мегабайт, то подойдут микросхемы последовательной флэш памяти. Однако для больших объемов (десятки -сотни мегабайт) обычно применяются какие-нибудь карты памяти. В настоящий момент наибольшее распространение получили SD и microSD карты, о них я и хотел бы поговорить в серии материалов. В этой статье речь пойдет о подключении SD карт к микроконтроллеру, а в следующих мы будет разбираться как читать или записывать на них данные.

Распиновка SD и microSD карт

SD карты могут работать в двух режимах - SD и SPI . Назначение выводов карт и схема подключения зависит от используемого режима. У 8-и разрядных микроконтроллеров AVR нет аппаратной поддержки SD режима, поэтому карты с ними обычно используются в режиме SPI. В 32-х разрядных микроконтроллерах на ядре ARM, например AT91SAM3, интерфейс для работы с картами в SD режиме есть, поэтому там можно использовать любой режим работы.

Назначение контактов SD карты в SD режиме


Назначение контактов SD карты в SPI режиме

Назначение контактов microSD карты в SD режиме



Назначение контактов microSD карты в SPI режиме



Подключение SD и microSD карт к микроконтроллеру в SPI режиме

Напряжение питания SD карт составляет 2.7 - 3.3 В. Если используемый микроконтроллер запитывается таким же напряжением, то SD можно подключить к микроконтроллеру напрямую. Расово верная схема, составленная путем изучения спецификаций на SD карты и схем различных отладочных плат, показана на рисунке ниже. По такой схеме подключены карты на отладочных платах фирм Olimex и Atmel .

На схеме обозначены именно выводы SD карты, а не разъема.


L1 - феррит или дроссель, рассчитанный на ток >100 мА. Некоторые его ставят, некоторые обходятся без него. А вот чем действительно не стоит пренебрегать, так это полярным конденсатором C2. Потому что при подключении карты происходит бросок тока, напряжение питания "просаживается" и может происходить сброс микроконтроллера.

По поводу подтягивающих резисторов есть некоторая неоднозначность. Поскольку SD карты выпускаются несколькими производителями, на них существует несколько спецификаций. В одних документах четко указана необходимость подтягивающих резисторов (даже для неиспользуемых линий - 8, 9), в других документах этих указаний нет (или я не нашел).

Упрощенный вариант схемы (без подтягивающих резисторов) показан на рисунке ниже. Эта схема проверена на практике и используется в платах фирмы Microelectronika. Также она используется во многих любительских проектах, которые можно найти в сети.



Здесь сигнальные линии SD карты удерживаются в высоком состоянии микроконтроллером, а неиспользуемые линии (8, 9) никуда не подключены. По идее они должны быть подтянуты внутри SD карты. Далее я буду отталкиваться от этой схемы.

Если микроконтроллер запитывается напряжением отличным от напряжения питания SD карты, например 5 В, то нужно согласовать логические уровни . На схеме ниже показан пример согласования уровней карты и микроконтроллера с помощью делителей напряжения. Принцип согласования уровней простой - нужно из 5-и вольт получить 3.0 - 3.2 В.



Линия MISO - DO не содержит делитель напряжения, так как данные по ней передаются от SD карты к микроконтроллеру, но для защиты от дурака можно добавить аналогичный делитель напряжения и туда, на функционировании схемы это не скажется.

Если использовать для согласования уровней буферную микросхему, например CD4050 или 74AHC125, этих недостатков можно избежать. Ниже приведена схема, в которой согласование уровней выполняется с помощью микросхемы 4050. Это микросхема представляет собой 6 неинвертирующих буферов. Неиспользуемые буферы микросхемы "заглушены".

Подключение microSD карт аналогичное, только у них немного отличается нумерация контактов. Приведу только одну схему.



На схемах я рассматривал подключение SD карт к микроконтроллеру напрямую - без разъемов. На практике, конечно, без них не обойтись. Существует несколько типов разъемов и они друг от друга немного отличаются. Как правило, выводы разъемов повторяют выводы SD карты и также содержать несколько дополнительных - два вывода для обнаружения карты в разъеме и два вывода для определения блокировки записи. Электрически эти выводы с SD картой никак не связаны и их можно не подключать. Однако, если они нужны, их можно подключить как обычную тактовую кнопку - один вывод на землю, другой через резистор к плюсу питания. Или вместо внешнего резистора использовать подтягивающий резистор микроконтроллера.

Подключение SD и microSD карт к микроконтроллеру в SD режиме

Ну и для полноты картины приведу схему подключения SD карты в ее родном режиме. Он позволяет производить обмен данными на большей скорости, чем SPI режим. Однако аппаратный интерфейс для работы с картой в SD режиме есть не у всех микроконтроллеров. Например у Atmel`овских ARM микроконтроллеров SAM3/SAM4 он есть.



Шина данных DAT может использоваться в 1 битном или 4-х битном режимах.

Продолжение следует...

SD и microSD карты могут существенно расширить возможности проектов ардуино, работающих с большими объемами данных: регистраторов данных, метеостанций, систем умного дома. Платы arduino оснащены сравнительно небольшой внутренней памятью, всего до 4 килобайт, включая и флэш-память, и EEPROM. Этой памяти не хватит для записи больших объемов данных, тем более, если плата будет постоянно выключаться или выключаться. Подключение SD карты ардуино в качестве внешнего накопителя позволяет многократно увеличить место для хранения любой информации. Съемные накопители SD стоят дешево, легко подключаются и удобны в использовании. О правильном подключении SD карты к Arduino и пойдет речь в статье.

Работа с памятью SD в ардуино не представляет особых трудностей. Самым простым способом является подключение готового модуля и использование стандартной библиотеки. С этого варианта мы и начнем.

Использование готового модуля обладает различными преимуществами. Это довольно простое и удобное средство для работы с большим объемом данных. Он не требует особых навыков в подключении, все разъемы подписаны прямо на плате. За удобство приходится платить, но стоимость модуля относительно не велика, его легко можно найти по доступным ценам в российских и зарубежных интернет-магазинах.

Универсальный модуль представляет собой обыкновенную плату, на которой помещены слот для карты, резисторы и регулятор напряжений. Он обладает следующими техническими характеристиками:

  • Диапазон рабочих напряжений 4,5-5 В;
  • Поддержка SD карты до 2 Гб;
  • Ток 80 мА;
  • Файловая система FAT 16.

Модуль SD-карты реализует такие функции как хранение, чтение и запись информации на карту, которая требуется для нормального функционирования прибора на базе микроконтроллера.


Естественно, у недорогих модулей карт памяти есть и недостатки. Например, самые дешевые и распространенные модели поддерживают только карты до 4Гб и почти все модули позволяют хранить на SD карте файлы объемом до двух гигабайт – это ограничение используемой в большинстве моделей файловой системы FAT.

Еще одним недостатком карт памяти является относительно долгое время записи, однако существуют пути работы с ней, позволяющие увеличить ее скорость работы. Для этого используется механизм кэширования, когда данные сначала копятся в оперативной памяти, а потом сбрасываются за раз на карту памяти.

Платы Arduino для работы с SD

Для работы с SD card существует несколько различных плат:

  • Arduino Ethernet – эта плата оснащена специальным модулем для вывода данных. Для выхода CS используется контакт 4. Для правильной работы нужно применять команду SD.begin(4).
  • Adafruit Micro-SD – это отладочная плата, которая используется при работе с Micro-SD картами.
  • Sparkfun SD – закрепляется сверху Ардуино, для выхода CS использует 8 контакт. В новой версии платы есть соединение с 3.3 В и встроен шестиразрядный инвертор.

Подключение SD и microSD к ардуино

Существует два вида карт – microSD и SD. Они одинаковы по подключению, структуре и программе, различаются же только размером. Перед работой советуется отформатировать карту SD. Обычно новые карты уже отформатированы и готовы к работе, но если используется старая карта, то лучше провести форматирование в файловой системе Arduino. Для проведения процедуры на компьютере должна быть установлена библиотека SD, желательно FAT16. Для форматирования на Windows нужно щелкнуть на иконке карты и нажать “Format”.

Для подключения карты используется 6 контактов, взаимодействие производится по интерфейсу SPI. Она выглядит на плате как разъем на лицевой поверхности с шестью штырями. Чтобы подключить карту, нужны сам контроллер, модуль карты и 6 проводов. Помимо SPI существует режим SDIO, но он сложен в реализации и слабо совместим с Ардуино. SPI легко налаживается для работы со всеми микроконтроллерами, поэтому советуется использовать именно его.

Подключение цифровых выводов производится так: для платы Arduino Nano или Uno контакт MOSI подключается к D11, MISO к D12,SCK к D13, CS к 4, VCC на +5 В,.GND к GND. На плате имеются разъемы для подключения к 3,3 и 5 вольтам. Питание самой карты составляет 3,3 вольт, поэтому проще применять микроконтроллер с таким же питанием, в ином случае нужен преобразователей уровней напряжения. На самых распространенных платах ардуино такой выход есть.

При подключении SD карты нужно учитывать соответствие SPI контактов для разных тип плат Arduino:

Библиотека ардуино для работы с SD и microSD

Для удобства работы с внешними накопителями данных в среде Arduino IDE доступны уже готовые библиотеки. Ничего дополнительно скачивать или устанавливать в большинстве случаев не понадобится.

Для подключения библиотеки в скетче нужно использовать инструкцию include:

#include #include

Библиотека SPI нужна для правильной работы устройств, подключаемых по SPI.

Библиотечные функции нужно для считывания и записи данных на карту. Библиотека может поддерживать SD и SDHC карты.

Имена записываются в формате 8.3, то есть 8 знаков для названия, 3 для расширения. Путь к файлу записывается с помощью слэшей «/».

Встроенные примеры библиотеки SD

В Arduino IDE встроены готовые примеры для быстрого изучение функций бибилотеки:

  • Card Info – это извлечение информации, хранящейся в SD карте. С ее помощью можно узнать, в какую файловую систему отформатирована карта, наличие свободного места, какие данные записаны.
  • Yun Datalogger – позволяет записывать лог-данные с трех сенсоров на карту.
  • Datalogger – регистрирует и созраняет данные, полученные с датчика на карту.
  • Dump File – считывание данные с карты, передает их в серийный порт.
  • Files – создает и удаляет данные. Существует функция file.write(), которая помещает записанные данные в буфер. Перемещение информации на карту происходит при вызове функций flush() или close(), поэтому важно закрывать его после каждого открытия файла, иначе данные будут потеряны.
  • Read Write – записывает и считывает файлы с карты.

Функции библиотеки SD

Ардуино-библиотека SD содержит различные функции, с помощью которыми можно управлять данными. Функции класса SD:

  • begin() – функция инициализирует библиотеку, присваивает контакт для сигнала.
  • exists() – призвана проверить, имеется ли на карте необходимая информация.
  • mkdir() – позволяет создать нужную папку на карте памяти.
  • rmdir() – с помощью этой функции можно удалить папку. Важно, чтобы удаляемая папка была пустой.
  • open() – позволяет открыть файл, который нужен для записи или чтения. Если нужный файл отсутствует на карте, то он будет создан.
  • remove() – удаляет любой файл.

В ответ на все эти функции должно прийти одно из значений – true, в случае удачного завершения операции и false при неудаче.

Создание, редактирование и удаление файлов.

Для работы с файлами в ардуино существует класс File. В него входят функции, которые предназначены для записи и чтения информации с карты:

  • available() – проверяет наличие в файле байт, которые доступны для чтения. В ответ приходит количество места, которое доступно для чтения.
  • close() – закрывает файл, перед эти проверяет, сохранены ли данные на карту.
  • flush() – функция позволяет убедиться, что данные записаны на карту.
  • name() – возвращает указатель на имя.
  • peek() – считывает байты данных, при этом не перемещает указатель на следующий символ.
  • position() – находит текущее положение указателя в файле.
  • print() – выводит данные в отдельный файл.
  • println() – печатает данные в файл до места, где появляется символ перевода каретки и пустая строка.
  • seek() – меняет положение текущей позиции в файле.
  • size() – выводит информацию о размере данных.
  • read() – считывает информацию.
  • write() – производит запись в файл.
  • isDirectory() – с помощью этого метода происходит проверка, является ли файл директорией, то есть каталогом или папкой.
  • openNextFile() – выводит имя последующего файла.
  • rewindDirectory() – возвращает к первому файлу в директории.

Для корректной работы платы нужно проследить, чтобы был сконфигурирован SS выход.

Скетч примера работы с SD библиотекой ардуино

Ниже приведен скетч, демонстрирующий пример работы с модулем карты памяти.

/* Регистратор данных с использованием SD карт Пример сохранения данных с аналоговых портов на SD карте. Данные будут сохраняться в файле в виде набора строк с разделителем полей в виде символа "," Схема подключения: * Аналоговые сенсоры подключаются к аналоговым пинам * Модуль SD карты подключен в SPI по стандартной схеме: ** MOSI - пин 11 ** MISO - пин12 ** CLK - пин 13 ** CS - pin 4 */ #include #include const int PIN_CHIP_SELECT = 4; void setup() { Serial.begin(9600); Serial.print("Initializing SD card..."); // Этот пин обязательно должен быть определен как OUTPUT pinMode(10, OUTPUT); // Пытаемся проинициализировать модуль if (!SD.begin(PIN_CHIP_SELECT)) { Serial.println("Card failed, or not present"); // Если что-то пошло не так, завершаем работу: return; } Serial.println("card initialized."); } void loop() { // Строка с данными, которые мы поместим в файл: String logStringData = ""; // Считываем данные с портов и записываем в строку for (int i = 0; i < 5; i++) { int sensor = analogRead(i); logStringData += String(sensor); if (i < 4) { logStringData += ","; } } // Открываем файл, но помним, что одновременно можно работать только с одним файлом. // Если файла с таким именем не будет, ардуино создаст его. File dataFile = SD.open("datalog.csv", FILE_WRITE); // Если все хорошо, то записываем строку: if (dataFile) { dataFile.println(logStringData); dataFile.close(); // Публикуем в мониторе порта для отладки Serial.println(logStringData); } else { // Сообщаем об ошибке, если все плохо Serial.println("error opening datalog.csv"); } }

Создание файла и выбор названия для arduino SD card

Создание файла – одна из самых распространенных задач, возникающих при работе с SD картами в ардуино. Как мы убедились в предыдущем скетче, для создания файла достаточно просто открыт его. Если мы захотим проверить, есть ли такой файл, можно использовать функцию exists():

  • SD.exists(“datalog.csv”);

Функция возвращает TRUE, если файл существует.

Популярной практикой при создании проектов – регистраторов данных является разбивка больших файлов на более мелкие, которые удобнее обновлять и открывать на компьютере. Например, вместо одного очень большого файла datalog.csv на SD карте можно иметь несколько маленьких, добавляя к концу номер по порядку: datalog01.csv, datalog02.csv и т.д.
Вот пример скетча, который поможет вам выполнить эту работу:

Char filename = "datalog00.CSV"; // Первоначальное название for (uint8_t i = 0; i < 100; i++) { filename = i / 10 + "0"; filename = i % 10 + "0"; if (! SD.exists(filename)) { // Проверяем наличие logfile = SD.open(filename, FILE_WRITE); break; // Дальше продолжать смысла нет } }

Заключение

Как мы с вами убедились, подключить SD карту памяти к Ардуино и использовать ее в проекте не очень сложно. Для этого есть готовые библиотеки в Arduino IDE и самые разнообразные варианты модулей. Приобрести карту памяти можно в любом магазине электроники, они стоят недорого, при этом позволяют существенно расширить потенциал платы Ардуино. С использованием карт памяти можно собирать и сохранять для последующего анализа большие объемы данных. С помощью нашей статьи мы сможете наделить памятью свои исследовательские проекты, создать системы голосового оповещения для умного дома, создать простой wav-проигрыватель и многое другое.

Обновлено18.12.15. Всем привет. Сегодня мы продолжим разработку контроллера сбора данных, а именно сохранение информации непосредственно на карту SD . В прошлой статье была налажена работа термометра. Теперь эту информацию по времени, при подключении в дальнейшем часов реального времени(статья №29 ), мы будем заносить на карту памяти, получив своеобразную базу данных. А также в дальнейшем перенесем эту информацию на ПК (статья №42), в базу данных под управлением MySQL (статья №48), через небольшое приложение на Java (статья №44). Но сперва разберемся что такое SD – карта и как с ней работать. Начнем с краткого обзора истории. Предшественником Flash-памяти является одна из энергонезависимых видов памяти , типа , которая зарекомендовала себя и используется в микроконтроллерах. Flash-память возникла в ходе потребности увеличения емкости и изменения технологии стирания (в случае с памятью EPROM). Поэтому в 1984 году инженер компании Toshiba Фудзио Масуокой изменил технологию стирания, что в свою очередь решил недостатки предшественников Flash-памяти. Хочется добавить, что далее данная память начала делится по внутреннему устройству соединения ячеек в массив и алгоритмами чтения-записи – это NOR- и NAND-технология. А также различие по количеству хранимых битов в элементарной ячейке. Это SLC-устройства (single-levelcell), т.е. однобитовые ячейки различают только два уровня заряда на плавающем затворе. И MLC- устройства (multi–levelcell) — многобитовые ячейки различают больше уровней заряда. Второй тип приборов дешевле и более ёмкий, чем SLC-приборы, однако с большим временем доступа и меньшим максимальным количеством перезаписей (около 10 тыс. и 100 тыс. — SLC).

Вообще устройства технологии NOR — это двумерная матрица проводников, что позволяет получить более быстрый доступ к каждой ячейки памяти, но при этом площадь ячейки считается большой, поэтому данная технология используется для памяти программ микропроцессоров и для хранения небольших вспомогательных данных, сюда же можно включить и специализированные микросхемы начальной загрузки компьютеров
(POST и BIOS), процессоров ЦОС и программируемой логики.Типовые объёмы - от 1 кбайта до 1 Мбайта.
Второй тип устройства — NAND-технология — трехмерный массив имеет малую площадь ячейки, но относительно длительный доступ сразу к большой группе ячеек. Используется для больших объемов памяти. Вот с этой памятью мы и будем работать.
Но перед этим хочется сказать об недостатке. Как и у всего есть свой срок использования, так и у памяти есть ресурс износа. Производители в гонке за емкостью и лидерством на рынке, всегда упускают такой показатель как качество, т.к. он не совместим с высокой ценой. Так возвращаясь к износу хочется отметить что срок хранения информации при использовании MLC-устройств составляет примерно 5 лет, что связанно с накоплением необратимых изменений при изменении заряда. Если брать память NAND c SLC-устройства, то они являются более качественными, и соответственно дорогими. Стоит отметить что срок хранения информации очень во многом зависит от температуры, гамма-радиации и частиц высокой энергии.
Выше было сказано, что недостаток карты это ограниченное количество циклов перезаписей. Когда мы будем использовать файловую систему для управления файлами, то должны знать что такие системы записывают данные в одно место, естественно расходую ресурс выделенной области в итоге вывода ее из строя и соответственно уменьшая емкость. Для этого типа памяти используется NAND-контроллер, который должен равномерно распределять износ. Однако для удешевления устройств контроллер может и не использоваться, а его работу будет выполнять программный NAND-драйвер в операционной системе. После этого открытия, многие компании занялись разработкой своих стандартов портативных карт.

Далее перейдем непосредственно к рассмотрению карты.
Secure Digital Memory Card (SD) - формат карт памяти, разработанный для использования в основном в портативных устройствах. Чтобы разобраться в ее работе мы будем использовать спецификацию, которая описывает данный стандарт и называется SD Specifications ver3.01.
Первое что нам необходимо, так это разобраться как работать с этой картой, как подключить и прочее. Сначала выберем карту. Для экспериментов я взял microSD емкостью 2Гб, стандарт емкости SDSC. Шина карты может работать по двум протоколам SD и SPI. Хочется отметить что данная карта это своего рода модификация карты MMC, где (в карте SD) основное внимание было уделено системе безопасности. Поэтому алгоритм работы по протоколу SPI такой же, ну и конечно же они односторонне совместимы. Т.е мы можем в слот SD карты вставить MMC, но не наоборот.

На рисунке ниже представлена схема подключения карты SD по протоколу SPI .
Данный интерфейс позволяет обмениваться данными на высокой скорости, задействовав при этом минимальное количество выводов микроконтроллера, которые оснащены модулем SPI. С этого момента начнем использовать спецификацию. Первое что нас интересует- выбор режима. Разберемся в тонкостях на рис. ниже из раздела 6.4.1.1 представлена диаграмма напряжения питания и последовательность посылки команды. Здесь четко видно что после включения карты необходимо выждать несколько миллисекунд (1мс + от 0.1 до 35 мс(нарастание)) на стабилизацию. В течении этого времени на CS, MOSI линии должна быть подана 1. Далее происходит задержка инициализации максимум 1 мс, при подаче на вход CLK 74 импульсов (тактов), после чего должна идти команда CMD0. Перейдем к главе 7 где четко описана последовательность действий.

Диаграмма напряжения питания

SPI протокол выбирается после включения питания и подачи команды сброса CMD0. Сама по себе карта SD работает в режиме SD. Вход в режим осуществляется если сигнал SC при подаче команды CMD0 будет 0. При переходе в режим SPI карта ответит форматом R1 (рисунок ниже). Формат ответа представляет собой байт (зависит от команды см. таблицу 7.3 в спецификации) с флагами определяющие состояние карты. Правильные ответы для нас это будет 1 (в случае команды CMD0) и 0 во всех других случаях.
1-й бит – режим ожидания
2-й – ошибка стирания
3- й – неизвестная команда
4-й – ошибка команды
5-й – ошибка в последовательности стирания
6-й –ошибка адреса
7-й – ошибка аргуента

В процессе сброса, карта должна ответить 0×01, что соответствует первому биту.

В спецификации есть четкая последовательность инициализации для SPI. Для чего используется команда CMD8 для проверки рабочего состояния карты, где происходит довольно не простой алгоритм проверки. Далее команда CMD58 для определения типа карты SDSD или SDHC и SDXC. А также команда CMD41 для запуска и проверки инициализации. Довольно не простой процесс инициализации с проверками, но я думаю что для простой записи данных можно использовать более упрощенный процесс. В разделе 7.2.7. говорится, что в режиме ожидания единственно допустимые команды для карточки CMD41, CMD8, CMD58, CMD59 , а также для карт (толстых 2.1мм) памяти SD CMD1, который идентичен команде CMD41. В стандарте эта команда считается запрещенной для инициализации, и используется исключительно для различия карт 1,4мм и 2,1мм.
Пойдем более простым путем и используем команду CMD1. Все выше описанное отобразим в коде в функции инициализации, но перед этим рассмотрим формат команды. Каждая команда или блок данных состоят из восьми битных байтов, которые выравниваются по сигналу CLK. Т.е. каждая команда выравнивается по границе 8 тактов. Сообщения SPI состоят из команды, ответа и данных. Вся связь контролируется микроконтроллером. Все команды имеют длину 6 байт. Передача начинается с первого левого бита.

На рисунке ниже представлен формат команды.


Старт бит – с 0 начинается любая команда. Передаваемый бит – тоже всегда равна 1.
Индекс – непосредственно передаваемая команда.
Аргумент- для каждой команды аргумент указан в таблице спецификации.
CRC – проверка избыточности кода. По умолчанию в режиме SPI она отключена. Поэтому мы ее используем только для команды CMD0, которая посылается до входа в режим и имеет значение CRC 0×95.
Стоп бит - конец передаваемой команды.
Что ж приступим к написанию кода.
Начнем с необходимых 2-х функций: передача и прием байта.
1. Передача байта карте.
void trans_byte_sd (unsigned char data)// передаем массив битов
{
for (unsigned char i=0;i<8;i++) //Перебираем байт
{
if ((data&0×80)==0×00) //Если старший бит = 0
PORTB&=~_BV (PB3); //Выставить MOSI (DI) -0
else
PORTB|=_BV (PB3); //1
data=data<<1; // сдвиг влево
PORTB|=_BV (PB5); //Импульс или строб
asm («nop»); //Пауза в 1 такт
PORTB&=~_BV (PB5);
}
}
2. Прием байта микроконтроллером.
unsigned char receive_byte_sd (void) // Возвращаем ответ
{
unsigned char data = 0; // инициализируем массив
for (unsigned char i=0; i<8; i++)
{
PORTB|=_BV (PB5); //Фронт импульса
data=data<<1; // Сдвигаем влево
if ((PINB&_BV (PB4))!=0×00) // Если состояние пина 1
data=data|0×01;
PORTB&=~_BV (PB5); //0
asm («nop»);
}
return data; // Возвращаем ответ
}

Из выше описанных, основных, функций начнем писать дальнейший код. Далее пропишем функцию передачи команды. Здесь хочется обратить внимания, на то, что Вы можете передавать все 5-ть аргументов: непосредственно саму команду и 4-аргумента отвечающих за адрес ячеек памяти самой карты. Что касается 6-го байта, то CRC при входе в режим SPI отключается (по умолчанию) и значение постоянно равно 0×95, которое используется только для CMD0, когда карта не в режиме. Включить проверку кода можно командой CMD58. Для экспериментов я передаю два аргумента.

3.Передача команды.
unsigned char comand_sd (char CMD, char arg) /*передаем команду и адрес к которому обращаемся и возвращаем ответ*/
{
long int i=0; // переменная для счетчика
unsigned char r1; // ответ карты
trans_byte_sd (CMD); // команда
trans_byte_sd (0×00);
trans_byte_sd (0×00);
trans_byte_sd (arg); // передача адреса
trans_byte_sd (0×00);
trans_byte_sd (0×95); // Передача CRC
/* После передачи команды ждем ответа формата R1.Каждой команде соответствует свой ответ*/
/* Цикл для ожидания получения ответа за определенное время*/
do
{
r1=receive_byte_sd ();
i++;
}while (((r1&0×80)!=0×00)&&(i<0xffff)); /* Как только старший бит байта не равен 0 и i не превышает 65 535 тактов*/
return r1; // Возвращаем ответ
}
4. И нициализация карты.

Теперь мы можем прописать инициализацию карты. Кратко программа описывается следующим образом: первое что необходимо, так это перевести карту в режим SPI. При подаче питания карта устанавливается в режим SD. Для выбора режима SPI на вход CS подается логический 0, в это же время подается команда сброса CMD0 и инициализации CMD1 на вход карты MOSI. Обратим внимание что команда начинается от шестнадцатеричного 0×40, к которому необходимо прибавить номер команды CMD в шестнадцатеричном виде.

unsigned char spi_card_init (void) // функция возвращает ответ
{
unsigned char r1; // переменная для приема ответа
long int i =0; // переменная для счетчика
_delay_ms (10); // небольшая задержка для стабилизации напряж.
PORTB|=_BV (PB1); //CS, устанавливаем 1, при подаче тактов
PORTB|=_BV (PB3); //линия подачи команд — 1 MOSI (DI)
for (unsigned char i=0; i<80;i++) // посылаем более 74 импульса
{
PORTB|=_BV (PB5); //CLK — 1
asm («nop»); //задержка в один такт
PORTB&=~_BV (PB5); //CLK — 0
}
PORTB&=~_BV (PB1); /* условие для входа в режим SPI линия CS должна быть равна 0 */
r1=comand_sd (0×40,0×00); // CMD0=0×40, адрес без разницы
if (r1!=0×01) return 4; //коды ошибок можете ставить любые
trans_byte_sd (0xff); /* посылаем строб, своеобразная пауза перед приемом ответа */
do // цикл приема ответа от карты
{
r1=comand_sd (0×41,0×00); /* посылаем команду инициализации */
trans_byte_sd (0xff); // пауза
i++; // счетчик
}while ((r1!= 0)&&(i<65535)); /*пока не получен ответ 0 и количество циклов не превышает 0xffff */
if (i>=0xffff) return 5; /* возвращаем ошибку если превысило время опроса */
return 0;//Возвращаем 0 в случае успешной инициализации
}

Следующий важный момент, в спецификации пишется, что информация передается блоками, по 512 бит, причем если карта SDSC как в нашем случае, то длину блока можн0 установить от 1 до 512 бит командой CMD16. По умолчанию 512 бит. Далее опишем две функции приема и передачи блоков. В спецификации даны блок-диаграммы, опираясь на которые мы напишем код.

Передача блока информации на карту.

За передачу ЕДИНСТВЕННОГО блока отвечает команда CMD24. После подачи команды, ждем ответ После чего следует стартовый байт, который подготавливает контроллер карты к приему информации, по окончанию карта отвечает байтом о состоянии передачи, который описан в главе 7.3.3.1. Т.е. правильный ответ должен быть= 5. Также ждем освобождения шины для дальнейшей передачи.

Байт отзыва о состоянии передачи.

В разделе 7.3.3.2 описывается формат передаваемого блока
unsigned char receive_block_sd (char* block, char arg) /* передаем массив для записи данных и адрес к которому обращаемся*/
{
long int i = 0;
unsigned char r1;
r1=comand_sd (0X51,arg); //CMD17
if (r1!=0×00) return 5; //Выйти, если ответ не 0×00
trans_byte_sd (0xff);
do //Ждем начала пакета данных
{
r1=receive_byte_sd ();
i++;
}while ((r1!= 0xfe)&&(i<65535));
if (i>=0xffff) return 5;
for (int i=0;i<512;i=i+1) //прием данных
block[i] = receive_byte_sd ();
receive_byte_sd (); //байт CRC
receive_byte_sd (); //байт CRC
return 0;
}

Перед тем как использовать программу, рассмотрим аппаратную часть. Как мы говорили, выше, что карта совместима с микроконтроллером в режиме SPI. Отметим следующие нюансы работы с картой:
1. Сопряжение логических уровней, необходимо при разном напряжении питания SD-карты и микроконтроллера AVR. Можно использовать резистивный делитель напряжения, который является линейным,т.е. напряжение на выходе зависит от напряжения на входе. А можно параллельный параметрический стабилизатор напряжения на стабилитроне, тоже что и первый вариант,только в нижнем плече используется стабилитрон, который является нелинейным делителем, и следит за опорным напряжением за счет своих свойств при повышении входного напряжения уменьшать внутреннее сопротивление,и наоборот.
Я использовал второй вариант. В схеме ниже на сигнальной линии сопротивления являются балластными(токоограничители), на вход делителя поступает напряжение 4,5 – 5 В, а выходное снимается с нижнего плеча делителя. Токоограничители необходимы для защиты карты и другой периферии при сбоях микроконтроллера. При хорошо отлаженном устройстве в них нет необходимости.

Заметьте, что линия MISO не нуждается в согласовании, т.к. работает только в одну сторону от карты к микроконтроллеру.
2. Второй момент, я не использую проверку наличия карты и защиты записи. У кого то есть эти контакты в слотах, у кого то нет.
3. Последний момент- питание. Либо ВЫ питаете 3.3 вольта всю схему, включительно с микроконтроллером, либо ставите делитель на вход схемы, не очень надежно. Либо стабилизатор 3.3 вольта, как я и сделал на микросхеме LP2980 . Важным моментом здесь является электролитический (танталовый) конденсатор, который защищает микроконтроллер от сброса при просадках напряжения.
Ниже представлена программа и результат. Как всегда, я стараюсь использовать одну программу постоянно ее изменяя. Данный код взят из статьи №5 (семисегментный индикатор).

#include
#include
#include
#include
//макросы для работы с индикатором
#define a 128
#define b 32
#define c 8
#define d 2
#define e 1
#define f 64
#define g 16
#define dp 4

// Переменные

char block ={}; //буфер записи/чтения данных на карту
short unsigned int j, k = 0; //в макросе прерывания
unsigned char Slot; // Массив чисел для отображения на индикаторе

//Объявляем функции

void trans_byte_sd (unsigned char data); // функция передачи байта
unsigned char receive_byte_sd (void); //Функция приема байта
unsigned char comand_sd (char,char); // функция передачи команды
unsigned char spi_card_init (void); //Функция инициализации карты памяти
unsigned char receive_block_sd (char* block, char arg); //Функция приема блока
unsigned char trans_block_sd (char* block, char arg); //Функция передачи блока
// Инициализации индикатора
void Slot_init ()
{…………………….};
// Переменные для отображения цифр
char Elem1, Elem2, Elem3;
// Вывод на индикатор
void Display (float i)
{ …………………………... }
int main (void) //начало основой программы
{
DDRB = 0x2A; //0010 1010 – PB1, PB3, PB5
DDRD = 0xff; //все выводы порта — выходы
PORTD = 0×00; //устанавливаем 0
PORTB |= 0хdb; //1101 1011 (PB0,1,3,4,6,7)
Slot_init ();
sei (); // либо SREG |= (1 << 7); разрешить общее прерывание
//инициализация таймера Т0
TIMSK = (1</*Флаг разрешения по переполнению таймера счетчика Т0*/
TCCR0 = (0< //1000000/8 = 125000
unsigned char temp;
int i;
for (i=0;i<512;i=i+1)
block[i]= i; //записываем в буфер
spi_card_init (); //инициализация
trans_block_sd (block,0×04); //отправляем данные карте
//Обнуляем буфер
for (int i=0;i<512;i=i+1)
block[i]=0;
// Считаем данные с карты
receive_block_sd (block, 0×04); ; //Функция приема байта
for (int i=0;i<512;i=i+1)
{
char otv;
otv = block[i];
Display (otv);
_delay_ms (100);
}
//Запишем по адресу в память 0
for (int i=0;i<512;i=i+1)
block[i]=0;
unsigned char comand_sd (char,0×00); //функция передачи команды
trans_block_sd (block,0×04); //отправляем данные карте
}
//Вывод на индикатор
ISR (TIMER0_OVF_vect)
{ ……………. }

Важный момент — это таймауты. Важно следить за временем чтения записи и стирании карты, так как может зависнуть микроконтроллер в режиме ожидания ответа карты. В спецификации четко описаны таймауты карты. Простой карты длится 5 мс, после чего переходит в энергосберегающий режим, в котором допустимы следующие команды CMD0, CMD1, CMD41 и CMD58. Поэтому при превышении лимита простоя передаем CMD1, ответ и дальше работаем с картой.
Внизу представлено два скриншота из программы WinHex , с помощью которой мы можем посмотреть содержимое ячеек памяти. Программа работает следующим образом: Записываем данные в буфер, оправляем карте, обнуляем буфер, считываем данные с карты в буфер и выводим на дисплей тем самым убеждаемся в передачи данных карте. Смотрим содержимое карты, обнуляем буфер, записываем 0 в карту и опять открываем содержимое карты, тем самым убеждаемся в работоспособности программы и схемы. Как всегда незабываем о мелочах, таких как не допайка, не большие трещенки в дорожках и др., что может забрать львинную долю времени. Поэтому если есть под руками осциллограф, то непременно используйте его для наладки. В статье №24 я привел небольшой пример диагностики карты на всех этапах ее работы. мы познакомимся с датчиком влажности и температуры DHT11. После чего начнем записывать данные (температуру и влажность) в текстовый файл, своеобразную базу данных. Пока на этом все. Всем пока.