Понедельник, 08 апреля 2013 05:17

Работа с SD/MMC картой. Featured

Written by
Rate this item
(0 votes)

 alt  В данной статье рассмотрим один из способов  применение в своих устройствах SD (Secure Digital Memory Card) далее SDC и MMC карт (Multi Media Card),  которые на сегодняшний день являются самыми популярными картами памяти для различных устройств как в промышленности, так и в быту.

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

 

 

 

С SD/MMC картой можно работать обращаясь к данным непосредственно по адресу сектора без применения файловой системы, что в некоторых случаях упрощает разработку устройства. Именно этот способ мы и рассмотрим далее...

 

    Подключение к микроконтроллеру.

    В качестве примера возьмем карту SD/MMC максимальной емкостью до 2 ГБ,  у меня под рукой оказалась  microSD ( отличается от старшего брата  в основном только меньшими размерами ) на нее и будем ориентироваться.   Карты    могут работать в двух режимах обмена данными - это MMC протокол и SPI. Нас интересует   SPI,  он  наиболее предпочтительный для нашей задачи.  Протокол SPI  позволяет вести обмен данными на высокой скорости и задействовав при этом минимальное количество  выводов микроконтроллера. Кроме этого практически все микроконтроллеры имеют на своем борту аппаратный модуль SPI и задача сопряжения устройства с картой  легко реализуется.

Подключение к МК SD, microSD карт.

alt

Подключение к МK MMC карты.

   . alt

 

  Работоспособность карты сохраняется при питании  от 2 до 3,6 вольт, соответственно удобно применить микроконтроллер (далее МК)  с таким же питанием или  по крайней мере в этом диапазоне, к примеру 3,3 вольта (PIC18F25k20). Если МК применен с 5 вольтовым питанием необходимо согласовать уровни  сигналов.

  Все MMC/SDC имеет в своем составе встроенный микроконтроллер управляющий   flash-памятью (чтения, записи и др.)  при помощи специальных команд. Ниже в таблице показан набор основных команд при работе с картой. Желтым цветом выделены команды при работе с SDC картами.

Набор основных команд.

alt

  Кадр команды имеет фиксированную длину 6 байт. Байты передаются последовательно, начиная с  номера индекса команды CMD(0-64), потом  4 байт аргумента  и 1 байта контрольной суммы (CRC).

  Проверка CRC в режиме SPI не является обязательной, но само поле  должно быть заполнено для целостности кадра. Исключение составляет команда CMD0, где CRC должно иметь правильное значение, т.к. режим SPI до получение этой команды еще не активирован. На рисунке № 1 показан формат передачи команды и получения ответа от карты.

 Более подробно по командам можно прочитать в спецификации от MMCA и SDCA.

Рис.№1 

alt

   Как видно из рисунка после передачи кадра команды необходимо продолжать чтение байтов (Ncr) от microSD  до получения ответа (R1), при этом уровень CS должен быть активным "0".

   В зависимости от индекса команды ответ может быть не только R1 (см. набор основных команд ) на CMD58 ответ R3 (R1 и завершающее 32-битное значение OCR), а некоторым командам нужно больше времени NCR и они ответ будет R1b. Это ответ R1, за которым идет флаг занятости (сигнал на линии "DO" удерживается картой в низком уровне, пока продолжается внутренний процесс). Контроллер хоста должен ждать окончания процесса, пока "DO" не перейдет в состояние высокого уровня (т.е. дождаться  0xFF). А так же R2 при запросе состояния регистра STATUS.

Ответ R1 содержит 1 байт, его структуру можно посмотреть в таблице ниже.  Ответ R2 состоит из двух байт, первый байт R1 и второй R2 (см. таблицу  структуры R2). А ответ R3 соответственно из 5 байт.

alt

    Ответ R1 при значении  0х00  означает успешное завершение команды, иначе будет установлен соответствующий флаг.

Структура ответа R1.

alt

Структура  ответа R2.

alt

Инициализации  в  режиме SPI.

   После сброса и подачи питания карта по умалчиванию устанавливается в режим работы по протоколу MMC (Serial Peripheral Interface), для перевода в режим SPI необходимо сделать следующее:

  1. После достижения питания  2.2 В, подождать не менее миллисекунды,  установить на линиях DI и CS высокий уровень и выдать около  80 импульсов на вывод  CLK. После такой процедуры   карта будет готова  принять родную команду.
  2. Послать команду CMD0 (программный сброс). Карта должна ответить (R1) с установленным битом ожидания (0x01).
  3. Послать команду CMD1 (для начала инициализации карты). Ждать ответа 0х00 для подтверждения завершения процесса инициализации.

   Напомню, что команда CMD0 должна содержать корректное  поле CRC.  Рассчитывать нет смысла, так как  аргументов в этой команде нет, по этому оно постоянно и имеет значение 0х95. Когда карта войдет в режим SPI, функция CRC будет отключена  и  не будет проверяться. Опция CRC может быть снова включена командой CMD59.

  В результате команда CMD0 будет выглядеть так: 0х40,0х00,0х00,0х00,0х00,0х95.

  • индекс команды - 0х40.
  • аргумент- 0х00,0х00,0х00,0х00.
  • CRC-0х95.

  Что касается 80 импульсов, то их можно сформировать передавая  по SPI  значение 0хFF 10 раз подряд  при установленных высоких уровнях на линиях DI и CS.

  После простоя  более 5 мс карта памяти  переходит в энергосберегающий режим, и способна принимать только команды CMD0, CMD1 и CMD58.   По этому процесс инициализации  (CMD1) необходимо практически каждый раз повторять при чтении/записи блока данных или делать проверку состояния карты.

   Для SDC-карт  в случае отклонения команды CMD1  рекомендуется использовать команду ACMD41.

  Сам процесс инициализации может занять относительно длительное время (в зависимости от объема карты) и может достигать  сотен миллисекунд.

Чтение и запись блока данных.

   По умолчанию в режиме SPI   обмен между микроконтроллером и картой ведется блоками по 512 байт, по этому для записи даже одного байта придется сначала прочитать весь блок и изменив байт перезаписать обратно. Размер блока может быть изменен в регистре CSD карты памяти.

   Воизбежания   ошибки адресации  при выполнении команд чтения/записи необходимо что бы адрес указывался  четко  начала сектора. Для этого можно сбрасывать бит "0"  3 байта адреса сектора, т.е. делать его четным, а младший всегда должен иметь значение 0х00.

Чтение  блока данных.

   Алгоритм чтения блока данных следующий:

  • Если простой карты был   более 5 мс передаем команду CMD1 (ответ R1).
  • После подтверждения инициализации  передаем команду CMD17 (ответ R1), с адресом необходимого сектора.
  • Передаем 0xFF до получения стартового байта 0xFE .
  • Принимаем блок данных (по умалчиванию 512 байт)  и 2 байта CRC.

  Блок  данных может быть меньше 512 байт при изменении длины блока командой CMD16.

  Значение CRC не обязательно, но  процедура принятия (передача 0хFF от МК) необходима.

Чтение блока.

alt

 

 

 

  Запись  блока данных.

Алгоритм записи блока данных следующий:

  • Если простой карты был   более 5 мс передаем команду CMD1 (ответ R1).
  • После подтверждения инициализации  передаем команду CMD24 (ответ R1), с адресом необходимого сектора.
  • Передаем  стартовый байт 0xFE .
  • Передаем блок данных (по умалчиванию 512 байт)  и 2 байта CRC.
  • Получаем байт подтверждения записи.
  • Ждем окончания записи (изменения байта 0х00).

  Блок  данных может быть меньше 512 байт при изменении длины блока командой CMD16.

  Значение CRC не обязательно, но  процедура передачи любыми значениями  необходима.

  Оценку  простоя можно программно и не делать, а сразу  давать команду инициализации. При программной  реализации столкнулся с некорректной записью, почему то все байты были записаны в сектор со сдвигом влево.  Проблему удалось решить, только передавая стартовый бит  (0xFЕ) два раза.

Запись блока.

alt

Байт подтверждения при записи блока данных.

alt

Запись/чтение нескольких блоков подряд.

При помощи команд  CMD18, CMD25  можно прочитать/записать несколько блоков подряд или так называемое многоблочное чтение/запись. Если не было задано количество блоков, то процесс чтения/записи можно остановить командами CMD12 при чтении , а так же  передачей маркера "Stop Tran"  при записи соответственно.

Практическое применение.

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

  • Год берется последние две цифры - это соответствует первому (главному) байту адреса сектора карты памяти.
  • Месяц,  две цифры - это соответствует второму, старшему байту адреса сектора карты памяти.
  • День, две цифры умножаются на 2 (во избежание наезда вне границы сектора) - это третий, средний байт адреса сектора карты памяти.
  • Младший, четвертый  байт соответственно всегда "0".

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

Кому надо   скину  фрагмент кода на ассемблере для 18 пиков.

Вопросы можно задать на форуме…..

Read 12761 times Last modified on Среда, 03 сентября 2014 11:00

Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru