Восстановление данных с монолитных SD и MicroSD карт. Подключение SD карты к микроконтроллеру Распиновка microsd разъема

Как видно из рисунка после передачи кадра команды необходимо продолжать чтение байтов (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 байт.


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

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


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


Инициализации в режиме 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.

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

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

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

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

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


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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

Вопросы можно задать на ..

Как известно, карты памяти SD совместимы с интерфейсом SPI, поэтому их легко можно подключить к микроконтроллеру и наладить с ними обмен данными. Адаптеры для карт типа microSD также являются доступными, из такого адаптера мы можем изготовить слот для карты microSD для нашего макета. На фотографиях ниже показан внешний вид изготовленного адаптера для подключения к макетной плате.

В проект изначально использовалась карта памяти microSD объемом 1 ГБайт. Микроконтроллер - ATmega8 или ATmega32, работающий на частоте 8 МГц от внутреннего RC осциллятора. Кроме того, для подключения макета к персональному компьютеру для мониторинга данных использовался интерфейс RS-232. Для преобразования логических уровней интерфейса используется микросхема MAX232 . Для питания схемы необходим стабилизированный источник питания 3.3 В (микросхема MAX232 рассчитана на напряжение питания 5 В, однако, как показала практика, сохраняет работоспособность при 3.3 В). Подключение карты памяти по 7-проводной схеме, согласно распиновке (см. рис).

Принципиальная схема для микроконтроллера ATmega8.

Подтягивающие резисторы R1, R2 номиналом 51 кОм интерфейса SPI придают лучшую стабильность при работе с различными картами. Стабилитроны D1, D2 предназначены для защиты карты памяти при работе внутрисхемного программатора (ISP). Выводы микросхемы MAX232 VCC и GND на схемах не указаны, но их необходимо подкличить к соответствующим точкам схемы.

Принципиальная схема для микроконтроллера ATmega32

Принципиальная схема для микроконтроллера ATmega32 (добавлены часы реального времени на микросхеме DS1307)

Как вы заметили, питание последнего варианта устройства осуществляется от источника 12 В, а на плате установлены два регулятора напряжения 5.0 В (LM7805) и 3.3 В (LM1117-3.3). Для питания интерфейса SD карты используется 3.3 В, вся остальная часть схемы питается от источника 5.0 В. Микросхема часов реального времени DS1307 в стандартном включении и подключена к интерфейсу I2C микроконтроллера.

Сперва был изучен «сырой» формат передачи данных, на примере операций чтения любого блока данных, чтения и записи нескольких блоков данных, стирания нескольких блоков, записи данных в любой блок памяти SD. Устройство, собранное на макетной плате, подключалось к компьютеру по интерфейсу RS-232. Для отображения прочитанных данных с карты памяти, а также для ввода и записи данных на карту используется программа HyperTerminal (или аналогичная) на компьютере.

После удачной реализации обмена данными без спецификации, карта памяти была отформатирована (FAT32) в операционной системе Windows XP, затем на карту были записаны несколько текстовых файлов, директорий и другие типы файлов (в корневую директорию карты). После этого были написаны подпрограммы и функции по работе с файловой системой FAT32 для чтения файлов, для получения списка файлов на карте памяти (с использованием HiperTerminal), для получения информации о полном и свободном объеме памяти.

Вид окна программы HiperTerminal с функциями по работе с картой памяти SD:

Пользователю предлагаются свыше 10 опций по работе с картой памяти (для варианта с часами).

Опции 0 - 4 - это низкоуровневые функции. Gосле использования опций 0 - 3 Вам необходимо переформатировать карту перед использованием FAT32 подпрограмм.
Опции 5 - 9 - относятся к файловой системе FAT32. На данный момент поддерживаются только короткие имена файлов (8 Байт - имя файла, 3 Байта - расширение файла). Если будут записаны файлы с длинными именами, то они будут отображены в терминальной программе в коротком формате. Для тестирования этих опций не забудьте отформатировать карту в файловой системе FAT32, записать несколько директорий и текстовых файлов.

Описание опций:

0 - Erase Blocks - стирание выбранного количества блоков начиная с указанного.
1 - Write Single Block - запись данных в блок с определенным адресом. Данные вводятся с клавиатуры в программе Hiperterminal;
2 - Read Single Block - чтение данных с блока с определенным адресом. Прочитанные данные отображаются в окне терминальной программы;
3 - Writing multiple blocks - запись нескольких блоков, начиная с определенного адреса;
4 - Reading multiple blocks - чтение нескольких блоков, начиная с определенного адреса.

Примечание. Здесь функции работы с несколькими блоками (опции 3 и 4) отключены из-за нехватки памяти микроконтроллера ATmega8, поскольку эти функции не нужны для тестирования файловой системы FAT32. Для включения этих опций необходимо удалить макрос в файле SD_routines.h (#define FAT_TESTING_ONLY). И, если Вы используете ATmega8, на время тестирования опций 3 и 4 библиотека FAT32 может быть удалена с целью освобождения памяти микроконтроллера.

5 - Get File List - отображает список доступных директорий и файлов с занимаемым ими объемом памяти (в корневой директории карты);
6 - Read File - чтение указанного файла и отображение содержимого в окне терминальной программы;
7 - Create File - создать/добавить файл с указанным именем;
8 - Delete File - удалить все файлы файл с указанным именем;
9 - Read SD Memory Capacity - информация о полном и свободном объеме карты памяти (используется FSinfo сектор SD карты).

В терминальной программе последовательный порт настраивается на скорость обмена 19200 бод, без контроля потока и без проверки четности.

Для версии с часами реального времени (DS1307) на микроконтроллере ATmega32 свойства создаваемых или обновляемых файлов привязываются к дате и времени (дата создания/изменения), эти свойства прописываются в файловой таблице и могут быть проверены с помощью компьютера, а также часы могут быть полезны при сборе данных. В меню опций в терминальной программе добавлены три опции.

Обновлено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. После чего начнем записывать данные (температуру и влажность) в текстовый файл, своеобразную базу данных. Пока на этом все. Всем пока.

В устройствах на микроконтроллерах для хранения больших объемов данных используется внешняя память. Если требуется хранить единицы мегабайт, то подойдут микросхемы последовательной флэш памяти. Однако для больших объемов (десятки -сотни мегабайт) обычно применяются какие-нибудь карты памяти. В настоящий момент наибольшее распространение получили 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-х битном режимах.

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

Сколько себя помню всегда любил читать, но на дворе 21 век и порой необходимую литературу можно найти только в интернете. Да и читать электронные книги можно на электронном устройстве типа планшет, компьютер или ридер. В итоге получилось небольшое устройство, которое может читать текстовые файлы с SD или microSD карты и выводить их содержимое на экран.

Мозгом устройства служит микроконтроллер Atmega32 работающий на частоте 8МГц. МК тактируется от внешнего кварца на 8МГц, в качестве экрана устройства я применил небольшой ЖК индикатор WH1604A на контроллере HD44780 разрешением 4 строки по 16 знакомест каждая. Кнопки использовал обычные тактовые, что касается SD карты для её подключения к микроконтроллеру я использовал резисторные делители чтобы согласовать логические уровни.

Принципиальная схема устройства:

На схеме распиновка верна только для SD карты или SD адаптера, для подключения других карт пользуйтесь их распиновкой!

Устройство поддерживает SD, miniSD и microSD карты памяти размером до 4ГБ отформатированные в файловой системе FAT, FAT16. Следует помнить что устройство не поддерживает каталоги поэтому все файлы нужно записывать только в корень флешки. Текстовые файлы должны быть в обычном txt формате и без форматирования, имена файлов должны быть не длинее 8 знаков (не считая расширения).

При включении устройства на дисплее появится заставка:

Если SD карта не установлена в устройство, неправильно подключена, или ещё чего то появится следующие сообщение:

Если же всё в порядке, то появится главное меню:

Пользуясь кнопками вы можете войти в пункт "Обзор файлов" где можете выбрать нужный вам для прочтения файл.

В пункте "Настройки" вы можете выбрать с каким расширением файлы отображать в "Обзоре файлов".

И в последнем пункте "О системе..." вы можете почитать информацию об устройстве, его авторе и т.д.

Прошивку для устройства я писал в среде BASCOM-AVR с использованием библиотеки AVRDOS, прошивка занимает всего 30% программной памяти микроконтроллера поэтому есть место для творчества. Внутри устройство собрано на двух печатных платах: на одной расположен МК с обвесом, на другой разъём под SD карту и согласующие цепочки логических уровней.

Вот фото устройства внутри:

Для питания я использовал Ni-Cd аккумулятор на 4.8В, 600мАч. После прошивки микроконтроллера необходимо установить следующие фьюз-биты:

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
U1 МК AVR 8-бит

ATmega32

1 В блокнот
D1, D2 Выпрямительный диод

1N4001

2 В блокнот
С1, С2 Конденсатор 22 пФ 2 В блокнот
С3 Электролитический конденсатор 100 мкФ 1 В блокнот
С4 Конденсатор 100 нФ 1 В блокнот
R1 Резистор

10 кОм

1 В блокнот
R2-R4 Резистор

4.7 кОм

3 В блокнот
R5-R7 Резистор

1 кОм

3 В блокнот
LCD1 LCD-дисплей LM014L 1 В блокнот
X1 Кварц 8 МГц 1 В блокнот
Кнопка 4 В блокнот
Выключатель 1

Похожие статьи

  • Три способа подключения «Мобильного банка» от Сбербанка

    Мобильный банк — такой же важный инструмент управления своими деньгами, как и сервис Сбербанк онлайн. Тем более, второй без первого практически не работает! Пакет «Эконом» берет с клиента 15 рублей за проверку последней операции на карте и...

  • Что такое яндекс директ и как он работает

    Как известно, Яндекс Директ является весьма популярным сервисом, основная функция которого заключается в построении взаимодействия между рекламодателями, а также теми, кто желает разместить на своих ресурсах рекламные объявления. Если вы...

  • Управление ставками Яндекс

    В этой статье вы узнаете, что такое Яндекс Директ и как он работает в интернете. Также я дам советы и кейсы, которые помогут вам повысить эффективность и увеличить прибыль от контекстной рекламы. Для владельцев сайтов — это...

  • Планшет самсунг стал долго заряжаться

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

  • LTE — что это такое в телефоне, как пользоваться Какой лучше 4g или lte

    В Украине скоро заработает связь нового поколения. Мы уже , как определить совместимость смартфона с 4G, а также о семи нюансах работы технологии в Украине. Теперь редакция объясняет, в чем разница между 4G и LTE. #1. Что такое 4G? 4G -...

  • Можно ли заряжать телефон (смартфон) от компьютера через USB-порт?

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