Микроконтроллер – работаем с SD картой без файловой системы

  •  
    microcontroller_sd
     
    В данном посте, я расскажу как работать с SD картой без файловой системы. Я покажу как:

     

    Как проводить инициализацию SD карты?

    Как писать данные на SD карту?

    Как читать данные с SD карты?

    Как читать регистры SD карты (на примере регистра CID)?

     

     

    В качестве контроллера я буду использовать ATmega328P (или Arduino UNO) и SD карту «старого образца», т.е. до 2 гигбайт (не SDHC и SDXC)  Поехали…

     

     

    Откуда я беру информацию?

     

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

    На сайте, в левой колонки перейдите в раздел Downloads -> Simplifed Specifications, соглашаетесь и жмете «I Accept» и качаете «Physical Layer Simplified Specification».

    В результате вы скачаете pdf документ — спецификацию на SD карты, в ней все подробным образом раскачано какие бывают карты и как с ними работать.

     

    Информацию для данного поста я черпал из данной спецификации, форумов и личного опыта.

     

     

    Кратко о SD карте

     

    SD карта (или Secure Digital Memory Card — безопасная цифровая карта памяти) представляет собой микроконтроллер и микросхему FLASH памяти.

     

    SD карта может работать в двух режимах

    • режим SD (свой родной протокол обмена данными)
    • режим SPI (в качестве интерфейса SD карта использует — SPI)

    Мы будем рассматривать работу с картой в режиме SPI. Что это за интерфейс и как с ним работать вы можете прочесть в посте «интерфейс SPI».

    С точки зрения интерфейса SPI, SD карта имеет следующие разъемы:

     

    SD_card_connectors

    Где

    DO — разъем для получения данных с SD карты

    DI — разъем для передачи данных SD карты

    SCLK — разъем для синхроимпульсов

    CS — разъем «выбор ведомого»

    Vss — земля

    Vdd — разъем питания, от 2.7 до 3.6 В.

     

    P.S. Повторюсь, карта работает при питание от 2.7 до 3.6 В, потреблению по току не более 100 мА. Входные данные и тактовый сигнал, также должен быть в этом диапазоне.

     

    Как подключить SD карту? (отдельный пост)
    Где я могу проверить данный код, если у меня нет ATmega328P?

     

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

     

    Разбираемся далее…

     

     

    Как общаются с SD картами?

     

     

    Взгляд из далека…

     

    С помощью интерфейса SPI на SD карту посылают кадр-команду, которая имеет длину 6 байт, т.е. 6 пакетов SPI. В результате переданной команды, SD карта через некоторое время (которое может длиться от 0 до 8 байт или от 0-ля до 8-ми пакетов SPI) возвращает ответ. Ответ может быть как отчет об ошибках так и отчет о удачной полученной команды.

    После переданной команды, SD карте можно передавать данные для записи или получать считанные данные. Данные передаются всегда блоками по 512 байт (или по 512 пакетов SPI). Послать или получить 1-ин байт данных нам не удаться, мы манипулируем только 512-и байтными блоками данных. Опять-же, если вам нужно изменить несколько байтов  на SD карте, то для начала вы должны прочесть 512 байтный блок, изменить нужные байт, далее его записать обратно, иначе ни как.

     

     

    Погрузимся по глубже…

     

    Я уже не раз повторял команды… команды записи/чтения, давайте разберемся какие бывают команды?

    Приведу некоторые, наиболее часто используемые, полных список вы можете найти в спецификации на SD карты

     (картинка кликабельна)

    commands_SD

     

    Команда имеет следующую структуру:

    structure_command_SD

     

    Сначала идет 01, далее индекс команды, который соответствует порядковому номеру команды, т.е. CMD0, CMD1, CMD2, CMD3 и т.п. На этом кончился первый байт команды, далее идет 4-е байтовый аргумент. Последний байт это контрольная сумма по алгоритму CRC.

     

     

    Как проводить инициализацию SD карты?

     

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

     

    1. После подключения карты к питанию нужно дождаться пока питающие напряжение на карте не достигнет рабочего, обычно для этого надо подождать несколько миллисекунд.

    2. Далее  нужно проинициализировать SPI в режиме 0-ль (что это за режим? вы можете прочесть в «интерфейс SPI«)

    3. Далее, нужно установить на контактах карты CS и DI (для контролера это выход MOSI и любой тот выход которые вы используете как CS на контролере) логическую единицу и подать на контакт CLK — 74 синхроимпульса (для контролера это выход SCK), можно и больше, главное, чтоб не меньше. После чего CS нужно установить в нулевой уровень

     

    Как это делается?

    Установить логическую единицу на выход контролера CS проблем быть не должно, а вот как установить логическую единицу на MOSI и подать 74-е синхроимпульса может немного озадачить. Обычно это делается так: в теле цикла в регистр данных SPI записывают значение 0xFF, условие цикла должно соответствовать не менее 10 итерациям. Далее на CS устанавливают логический ноль.

     

    Пример «фрагмент кода для Arduino»:

     

    Почему именно 10 итераций?

    Дело в том, что за 10 итераций будет сгенерировано 8*10=80 синхроимпульсов, а нам нужно не менее 74. При 9-и итерациях будет сгенерировано 9*8=72 синхроимпульса, что есть меньше 74. Мы просто взяли один из наименьших вариантов, хотя работать будет при любом количестве больше чем 10-и итераций.

     

    Физически, это процесс выглядит так:

    (к сожалению у меня нет реального осциллографа, поэтому я продемонстрирую процесс инициализации с помощью виртуального осциллографа САПР Proteus)

    diafram_initialization_SD

     

    На диаграмме нас интересует только SCK,  MOSI и CS  Как видно на CS мы устанавливаем логическую единицу, а на SCK и MOSI видно что мы посылаем 10 пакетов с значением 0xFF (другими словам посылаем не менее 74-е синхроимпульса с единицами на MOSI)

     

    4. Далее, нужно подать команду CMD0 с пустым аргументом и соответствующим CRC равным 0x95 для программного сброса, SD карта должна вернуть байт ответа с значением 0x01. Это означает, что карта перешла в режим SPI, она находится в состояние покоя и готова к процессу инициализации.

     

    Еще раз, SD карте мы посылаем следующие SPI пакеты

    0х40 0х00 0х00 0х00 0х00 0х95

     

    Через некоторое время SD карта возвращает ответ:

    0х01

     

    Пример «фрагмент кода для Arduino»:

     

    Физически, это процесс выглядит так:

    diafram_initialization_SD_2

     

    как видно ответ SD карты приходит на втором пакете, увеличим развертку на этом фрагменте….

     

    diafram_initialization_SD_3

     

    Видно, что SD карта отвечает 0x01 (8-ой бит равен единицы).

     

    5. В состояние покоя, карта может принимать только CMD0, CMD1, CMD58. Для запуска инициализации нужно узнать что за версия карты: v.1 или v.2 (более современные версии 3.0 и более мы рассматривать не будем), т.к. процесс инициализации для них разный.

    Узнать версию, мы можем с помощью команды CMD8. Наша последовательность действий: посылаем команду CMD8, далее шлем 0xFF до тех пор, пока не получим ответ 0x01 или 0x04. Ответ 0x01 скажет нам, что карта версии v.2 и выше, а 0x04 -«com are error», что карта «старая», т.е. v.1.

    Пример «фрагмент кода для Arduino»:

     
    Результат мы запишем в переменную status_, далее в зависимости от её значения мы будем проводить инициализацию тем или иным образом.

    Если карта v.1, то для инициализации нам нужно подать CMD1 с пустым аргументом и любым CRC (т.к. карта уже перешла в режим SPI, а находясь в нем, CRC код не проверяется, включить проверку можно с помощью команды CMD59). Постоянно посылаем карте команду CMD1 с пустым аргументом и любым CRC, до тех пор пока не получим байт ответа с значением 0x00, что означает инициализация завершена.

     

    Пример «фрагмент кода для Arduino»:

     

    Физически, это процесс выглядит так:

    diafram_initialization_SD_4

     

     

    Если карта v.2, то шлем команду ACMD41 (это CMD55 + CMD41). Шлем CMD55 с пустым аргументом и любым CRC, далее шлем 0xFF до тех пор, пока не получим ответ 0x01. После чего, шлем команду CMD41 с пустым аргументом и любым CRC, далее шлем 0xFF два раза, на второй раз смотрим ответ, если он равен 0x00, то значит карта инициализирована успешно.

     

    Пример “фрагмент кода для Arduino”:

     

     
    После инициализации нужно выставить логическую единицу на CS
     

     

    Приведу результирующий код на Arduino — «инициализация SD карты»

     

    Где я могу проверить данный код, если у меня нет ATmega328P?

     

    Все, инициализация завершена, теперь можно передавать и считать данные с SD карты. Но учтите, простой карты после инициализации должен быть не более 5 мс, иначе вам нужно заново подать команду инициализация SD карты, т.е. CMD1 или ACMD41 в зависимости от версии.

     

     

    Как писать данные на SD карту?

     

    Писать данные можно по одному блоку и сразу множество блоков.

    Один блок данных по умолчанию равен 512 байт (т.е. данные будут помещаться в 512 пакетов SPI). Размер блока можно изменить с помощью команды CMD16, но это подходит только для SD карт «старого образца» до 4 Гб с одноименным поколением – «SD» (так и пишется на наклейки)

     

    В большинство современных SD карт, т.е. поколения SDHC, SDXC (см. наклейку на карте) данная функция не поддерживается и один блок памяти неизменно равен 512 байт.

     

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

     

     

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

     

    Для записи данных по одному блоку, используется команда CMD24, в качестве её аргумента используется:

     

    -Для «старых» карт поколения «SD» (до 4 Гб)  используется адрес необходимого сектора. Адресуются сектора в SD побайтно, т.е. размер одного сектора – один байт. Но т.к. данные в SD карту пишутся не побайтно, а блоками, с размером 512 байт, то адрес сектора фактически означает – адрес первого байта блока.

     

    -Для «современных» карт, т.е. SDHC, SDXC в качестве аргумент используется номер 512 байтного блока. Блоки нумеруются с нуля.

     

    В данном посте мы будем рассматривать как писать данные в SD карты «старого образца» (поколение SD, их размер не выше 4 Гб).

     

    Пример для ясности, мы хотим записать данные в первый блок (размер блока по умолчанию 512 байт), адрес блока — 0х0000. Теперь мы хотим записать данные во второй блок, который идет вслед первого стык в стык, адрес блока – 0x0000+0x200=0x0200. Откуда я взял 0x200? Это число 512 вшестнадцатиричной системе исчисления. Тогда адрес третьего блока 0x0200+0x200=0x0400, и т.д.

     

    Так как записать блок данных? Алгоритм работы:

     

    1. Выставляем на CS логический ноль (после инициализации была выставлена единица)

     

    2. Далее отправим карте команду CMD24 с аргументом – адрес сектора с которого мы будем писать наш блок данных. CRC код у нас произвольный, т.к. в режиме SPI карта его не учитывает.

    Пример, нам нужно записать блок данных, начиная с первого сектора SD карты. Мы отправляем карте CMD24 c адресом 0x0000 и произвольным CRC.

    Т.е. мы посылаем SD карте следующие SPI пакеты.

    0х58 0х00 0х00 0х00 0х00 0х00 (CRC как 0x00 выбран произвольно)

     

    Ожидаем байт ответа,  что команда принята удачно, мы должны получить значение

    0x00

     

    Пример “фрагмент кода для Arduino”

     

     

    P.S. Первый, второй, третий байт адреса и т.п. я нумеровал с лева, т.е. если вас интересует адрес 0x200, то аргумент будет

    SPI.transfer(0x00); //первый байт пустого аргумента

    SPI.transfer(0x00); //второй байт пустого аргумента

    SPI.transfer(0x02); //третий байт пустого аргумента

    SPI.transfer(0x00); //четвертый байт пустого аргумента

    Т.е. 0x00000200

     

    3. Далее ожидание в один байт и передаем пакет данных.

    Пакет данных имеет следующую структуру

    SPI_SD_packet

    Перед блоком данных должна стоять метка. Метки бывают следующих типов:

    SPI_SD_mark

    Для нашего случая (запись блока данных, т.е. CMD24) подходит метка 11111110, т.е. 0xFE. В качестве CRC, мы будем использовать произвольное число 0x00, т.к. в режиме SPI карта не учитывает CRC.

     

    Например нам нужно записать блок данных, состоящий из 512-ть 0xAB, для этого на SD карту мы посылаем следующие SPI пакеты:

    Пошлем один байт, для ожидания

    0xFF

     

    Далее посылаем пакет данных

    0xFE 0xAB ..510 раз.. 0xAB 0x00 0x00

     

    Пример “фрагмент кода для Arduino”

     

     

    4. Ожидаем байт приема данных и окончания записи.

     

    Байт приема данных должен придти сразу после окончания пакета данных, он имеет следующую структуру

    SPI_SD_return

    Если данные приняты, байт приема данных должен иметь вид 00000101 или 0x05.

     

    Пример ожидания байта о приеме данных на Arduino

     

    Окончание записи данных занимает некоторое время. Пока микросхема SD карты занята записью данных, на выходе карты мы получаем 0xFF. Наша задача подавать 0xFF на карту и ожидать пока она не закончит запись, т.е. пока мы на выходе не получим 0x00. После чего можно отправлять новую команду с новыми данными, начиная с пункта 1.

     

    Пример ожидания окончания записи данных на Arduino

     

    5. Выставляем логическую единицу на CS

     

    Итак выложу полный код записи данных по блокам на Arduino

     

     

    Где я могу проверить данный код, если у меня нет ATmega328P?

     

     

     

    Как читать данные с SD карты?

     

    Читать данные можно аналогично как и писать: по одному блоку или сразу множество блоков.

    Повторю, один блок данных по умолчанию равен 512 байт (т.е. данные будут помещаться в 512 пакетов SPI). Размер блока можно изменить с помощью команды CMD16, но это подходит только для SD карт «старого образца» до 4 Гб с одноименным поколением – «SD» (так и пишется на наклейки)

     

    В большинство современных SD карт, т.е. поколения SDHC, SDXC (см. наклейку на карте) данная функция не поддерживается и один блок памяти неизменно равен 512 байт.

     

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

     

     

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

     

    Чтение как и запись происходит по аналогии, но я на всякий случай опишу также подробно (для тех кто попал сюда по ссылке с начало поста)

     

    Для чтения данных по блокам, используется команда CMD17, в качестве её аргумента используется:

     

    -Для «старых» карт поколения «SD» (до 4 Гб) в качестве аргумента используется адрес необходимого сектора. Адресуются сектора в SD побайтно, т.е. размер одного сектора – один байт. Но т.к. данные в SD карту считываются не побайтно, а блоками, с размером 512 байт, то адрес сектора фактически означает – адрес первого байта блока.

     

    -Для «современных» карт, т.е. SDHC, SDXC в качестве аргумент используется номер 512 байтного блока. Блоки нумеруются с нуля.

    В данном посте мы будем рассматривать как писать данные в SD карты «старого образца» (поколение SD, их размер не выше 4 Гб).

     

    Пример для ясности, мы хотим прочитать первый блок (размер блока по умолчанию 512 байт), адрес блока — 0х0000. Далее, мы хотим прочитать данные второго блока, который идет вслед первого стык в стык, адрес блока – 0x0000+0x200=0x0200. Откуда я взял 0x200? Это число 512 в шестнадцатиричной системе исчисления. Тогда адрес третьего блока 0x0200+0x200=0x0400, и т.д.

     

    Так как считать блок данных? Алгоритм работы:

     

    1. Первым делом выставляем на CS логический ноль

     

    2. Далее отправим карте команду CMD17 с аргументом – адрес сектора с которого начинается считываемый блок данных. CRC код у нас произвольный, т.к. в режиме SPI карта его не учитывает.

    Пример, нам нужно прочесть блок данных, начинающийся с первого сектора SD карты. Мы отправляем карте CMD17 c адресом 0x0000 и произвольным CRC.

    Т.е. мы посылаем SD карте следующие SPI пакеты.

    0х51 0х00 0х00 0х00 0х00 0х00 (CRC как 0x00 выбран произвольно)

     

    Ожидаем байт ответа, что команда принята удачно, мы должны получить значение

    0x00

     

    Пример “фрагмент кода для Arduino”

     

     

    P.S. Первый, второй, третий байт адреса и т.п. я нумеровал с лева, т.е. если вас интересует например адрес 0x200, то аргумент будет

    SPI.transfer(0x00); //первый байт пустого аргумента

    SPI.transfer(0x00); //второй байт пустого аргумента

    SPI.transfer(0x02); //третий байт пустого аргумента

    SPI.transfer(0x00); //четвертый байт пустого аргумента

    Т.е. 0x00000200

     

    3. Далее ожидание начала пакета данных и прием данных

    Пакет данных имеет следующую структуру

    SPI_SD_packet

     

    Перед блоком данных должна стоять метка. Метки бывают следующих типов:

    SPI_SD_mark

     

    Для нашего случая (чтение блока данных, т.е. CMD17) подходит метка 11111110, т.е. 0xFE. В качестве CRC, мы будем использовать произвольное число 0x00, т.к. в режиме SPI карта не учитывает CRC.

     

    Т.е. под ожиданием начала пакета данных, подразумевается ожидание метки 11111110 или 0xFE.

     

    Пример мы отправили команду CMD17 и нам нужно принять пакет данных:

     

    После чего, нам нужно еще подождать 2-а байта, это CRC код, мы его не проверяем, но принять обязаны.

     

    P.S. Если при чтение произошла ошибка, то вместо пакета данных мы получим маркер ошибки:

    SPI_SD_mark_error

     

     

    4. Выставляем логическую единицу на CS

     

     

    Итак, выложу полный код в котором мы сначала запишем блок данных в SD карту, а потом прочтем его. Код для Arduino

     

     

    Где я могу проверить данный код, если у меня нет ATmega328P?

     

     

     

    Как читать регистры SD карты?

     

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

     

    Наиболее интересные регистры:

     

    —Регистр CID (Card identification data): содержит данные, по которым можно идентифицировать карту памяти (серийный номер, ID производителя, дату изготовления и т.д.)
    —Регистр CSD (Card-specific data): содержит всевозможную информацию о карте памяти (от размера сектора карты памяти до потребления в режиме чтения/записи).
    —Регистр OCR (Operation Conditions Register): содержит напряжения питания карты памяти, тип питания карты памяти, статус процесса инициализации карты

     

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

     

    Я приведу пример как прочесть регистр CID.

     

     

    Читаем CID

     

    Для того, что бы прочесть регистр CID, карте необходимо послать команду CMD10. В результате чего, SD карта вернет пакет данных с размером 16 байт. Определить начало пакета мы можем по метке 0xFE.

     

    Не буду разжевывать, здесь все по аналогии с «чтением данных по блокам». Приведу сразу полный код чтения CID на Arduino

     

     

    Где я могу проверить данный код, если у меня нет ATmega328P?

     

     

    Структура CID регистра следующая

     

    CID_Registror

     

     

    Расшифровать данные регистра можно на сайте http://goughlui.com/static/cidecode.htm

     

     

    У меня нет железа, на чем я могу попробовать данные исходные коды?

     

    Проверить приведенные здесь исходные коды вы можете в программе Proteus. Для этого вам необходимо скомпилировать нужный вам исходный код(в среде разработки Arduino вам нужно нажать на кнопку «Проверить», в результате компилируется исходный код и в папке «C:\Users\Admin\Local Settings\Temp\buildXXXXXXXX.tmp» создается бинарный файл «имя_скетча.cpp.elf»).

    Далее указать контроллеру бинарный файл прошивки (два раза кликните на контроллер ATmega328P и в «Program File» укажите бинарный файл прошивки). Для SD карты необходимо указать файл образ, вы можете использовать «sample_sd.mmc» (лежит в корне проекта). Для запуска моделирования нажмите на значок «Play» в левом нижнем углу.

    Proteus

     

    В проекте к ножкам MISO, MOSI, SCL и 6-ой ноге в качестве CS микроконтроллера ATmega328P подключена SD карта с именем М1. Также к этим же ножкам  подключен «SPI анализатор» и осциллограф для удобной отладки приложений. В качестве вывода информации вы можете использовать последовательный порт (UART), для вывода виртуальный терминал «1».

     
    Ссылка на проект
    В архиве Arduino_STAND.DSN — файл проекта, sample_sd.mmc — образ SD карты, Write_Read_SD.elf — тестовый бинарник по исх. кодам «записи и чтения блока с SD карты», папка empty_sample_sd_card с чистым sample_sd.mmc, ведь после первого запуска текущий образ SD карты будет заполнен данными «АВ».
     

     




    Буду признателен если вы поделитесь данным постом

  • Комментарии
    1. Слава пишет:

      Автор, а как с вами связаться?

    2. admin пишет:

      Добрый день Слава, я вам ответил на почтовый ящик.

    3. AlStorm Prime пишет:

      Спасибо за отличную заметку, которая привела меня в мир SD карт =)
      Хотя и делал я это на stm32f3, основная идея, логика и последовательность изложены так, что проблем при портировании не возникло.
      Так же хочу оставить несколько своих заметок:
      1.Запись блока, строка
      while (SPI.transfer(0xFF)!=0x05); //ожидание сигнала о принятия команды
      Первый мой «затык» случился тут. Посмотрев на те ответы, что получал я и полистав документацию (7.3.3 Control Tokens -> 7.3.3.1 Data Response Token) могу утверждать, что ожидать ответа 0x05 в этом месте не совсем правильно. Дело в том, что ответ же там 8 бит, а анализировать нужно только 5 младших в то время как 3 старших не определены. К примеру, та карта с которой работал я в этот момент выдавала ответ 0xE5. Что вполне вписывается в спецификацию, но не работает с предложенным кодом.
      2.Запись блока, следующая строка
      while (SPI.transfer(0xFF)!=0x00); //ожидание сигнала о окончания записи данных
      Больше похожа на опечатку и должна выглядеть как
      while (SPI.transfer(0xFF)==0x00);
      Так как в первом случае, получив первый же ответ bussy token 0x00 код выпрыгивал из ожидания и переходил к отправке следующих команд. А карта оставалась не готовой.
      3. Касательно ограничения карты в 5 мс после инициализации. Возможно это специфика конкретной карты? или другого интерфейса… но в SPI и с моей картой я могу инициализировать её 1 раз в начале кода, а производить запись/чтение хоть на следующий день. Да и в спецификации я таких ограничений (в разделе SPI) я не обнаружил.

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

      Еще раз — спасибо!

    4. admin пишет:

      Спасибо вам за комментарий!

      Здоровая критика очень полезна для меня. Обязательно обращу внимание на свои ошибки.

    5. р6п90 пишет:

      krome chana kakie eshe sushestvyut biblioteki?

    6. admin пишет:

      p6n90, я не понял вопроса =)

    7. Валерий пишет:

      Добрый день!
      Спасибо! Очень интересно.

      В качестве вывода информации можно использовать монитор Arduino в таком виде вместо digitalWrite(4, HIGH); :

      for (int i=0; i<16; i++)
      block16[i]=SPI.transfer(0xFF);
      for (int i=0; i<16; i++)
      Serial.println(block16[i]);

      //сдвинем еще на два байта, это CRC
      SPI.transfer(0xFF);
      SPI.transfer(0xFF);

      А как понять где серийный номер, ID производителя, дата изготовления?

      Изменить значения регистра CID можно?
      Если можно напишите как.

    8. admin пишет:

      Добрый день Валерий!

      1. CID регистр имеет длину 128 бит, структура регистра описана в конце поста, там же дан сайт для расшифровки CID

      http://goughlui.com/static/cidecode.htm

      2. Насколько я знаю изменять CID нельзя.

    9. Валерий пишет:

      Мне нужно изменить в csd register C_SIZE.
      Размер с 16ГБ на 10ГБ.
      Пока не получается.
      Читаю весь SCD, а записать по CMD27 не получается.

    10. Валерий пишет:

      Разбить партишен не подходит.
      Нужно записать в регистр другое значение.

    11. Антон пишет:

      Напишу может кому-то еще будет полезно. В статье описываеться запись/чтение данных с карт «старого образца». В случае с SDHC и SDXC не нужно выщитывать никаких смещений в байтах, а передавать значения сразу в секторах.

    12. Арм пишет:

      Здравствуйте!
      Вот бы еще код для тех кто не знает CI)))
      может случайно для asm. код завалялся у вас?)

    13. admin пишет:

      Уважаемый Арм, к сожалению ассемблерного кода нет)



    Ваш комментарий


    Ответ в цифрах

     
    © s-engineer.ru, 2012-2017 | Все права защищены