Перейти к содержанию
    

AVR и SD(mini SD) память

Нужно связать AVR c SD карточкой памяти (внешняя память для устройства на AVR). Кто нить может подсказать где подробно можно почитать про SD карточки - протокол связи, распиновка разьёма, потребляемый ток и т.д. Вобщем что есть по этой теме. В поисковиках искал подходящего ничего не нашёл. Хотябы пример устройства на AVR с SD карточкой (схема и подробное описание).

Заранее благодарен. Илья. :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эх. ДОРОГОЙ! Искать лучше надо было. Ибо всё уже обсуждалось 1000 раз. не SD так MMC, разницы нет если работаешь по SPI. В качетве информации могу подкинуть (см аттач)

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

 

ЗЫ. У меня так и не получилось. на CMD0 и CMD1 отвечает, а сектора не отдаёт.

sdcard_appnote_foust.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Старые версии стандартов MMC v.3.1 (2003г.) и SD MMC (2001г.)

можно взять отсюда:

http://www.bbww.net/SoftDown.asp?ID=8087&lbID=0

там архив примерно 2.7мб.

По этим документам проверял работу с карточками 128, 256 и 512мб.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может ты в курсе почему MMC/SD 16Mb не хочет отдавать свой CID и прочее что отдаётся через read-buffer? На команду приходит 0 ответ, а 254 байт не приходет, символизирующий начала передачи буфера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может ты в курсе почему MMC/SD 16Mb не хочет отдавать свой CID и прочее что отдаётся через read-buffer?

 

Я только начал разбираться с карточками, поэтому читать CID не пробовал. Возможно CID надо читать

аналогично CSD (см. раздел 7.8 стандарта MultiMediaCard System Specification Version 3.31, ссылку

на который я давал раньше)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я ж сказал что буферы ваще не читаются, не только CID

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может не правильно инициализируешь карточку?

 

Вот вариант инициализации и работы с карточкой:

1. Настраиваем контроллер SPI

2. Устанавливаем CS=1 и передаем восемь байт 0xFF

3. Устанавливаем CS=0 и передаем CMD0 c аргументом 0 и CRC=0x95

4. Ждем ответа от карточки (посылаем в карточку 0xFF, пока не получим байт не равный 0xFF)

5. Если таймаут, увеличиваем счетчик попыток и если он меньше 3,

переходим к п.2. Если счетчик попыток = 3, вываливаемся с ошибкой.

 

6. Устанавливаем CS=0 и передаем CMD1 c аргументом 0 и CRC=0

7. Ждем ответа от карточки (посылаем в карточку 0xFF, пока не получим байт не равный 0xFF)

8. Устанавливаем CS=1

9. Если таймаут или ответ <> 0, увеличиваем счетчик попыток и если он меньше 3,

переходим к п.6. Если было три попытки выходим по ошибке. Если ответ = 0, карточка готова к работе

 

Читаем CSD

 

10. Устанавливаем CS=0 и передаем CMD9 c аргументом 0 и CRC=0

11. Ждем ответа от карточки (посылаем в карточку 0xFF, пока не получим байт не равный 0xFF)

12. При таймауте или при ответе <> 0, уст. CS=1 и переходим на обработку ошибки (п. 6)

13. Ждем от карточки токена SINGLE_BLOCK_READ (0xFE) (посылаем в карточку 0xFF, пока не получим байт не равный 0xFE)

14. При таймауте уст. CS=1 и переходим на обработку ошибки (п. 6)

15. Принимаем 16 байт CSD

16. Принимаем CRC (даже если не анализируем, т.к. карточка ждет 16 тактовых импульсов)

17. Устанавливаем CS=1 и выполняем анализ CSD.

 

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

 

18. Устанавливаем CS=0 и передаем CMD17 c адресом блока данных (адрес должен быть кратен 512) и CRC=0

19. Ждем ответа от карточки (посылаем в карточку 0xFF, пока не получим байт не равный 0xFF)

20. При таймауте или при ответе <> 0, уст. CS=1 и переходим на обработку ошибки (п. 6)

21. Ждем от карточки токена SINGLE_BLOCK_READ (0xFE) (посылаем в карточку 0xFF, пока не получим байт не равный 0xFE)

22. При таймауте или получении ответа <> 0xFE, уст. CS=1 и переходим на обработку ошибки (п. 6)

23. Принимаем 512 байт данных

24. Принимаем CRC (даже если не анализируем, т.к. карточка ждет 16 тактовых импульсов)

25. Устанавливаем CS=1 и разбираемся с прочитанными данными

 

Скорость обмена и длительность таймаутов определяется значениями в CSD, пока он не прочитан, можно установитьс запасом - 200мс. Скорость обмена должна быть в начале работы не более 400 кбит.

 

В интернет доступны примеры для AVR, например

http://hubbard.engr.scu.edu/embedded/avr/avrlib

www.ghielectronics.com

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сделал всё как предложено выше.

в результате такая штука:

- карточка отвечает 0 на CMD1 не всегда, но отвечает.

- читаем блок (операции предусматривающие SINGLE_BLOCK_READ)

- приходится снова переводить в CMD1 иначе следующая команда не вернёт ответа отличного от 0xFF в результате "подвисание" или ошибка.

- любая операция чтения блока возвращает 1; И никак не хочет 0;

 

SPI:

SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //Enable SPI, SPI in Master Mode    
SPSR = (0<<SPI2X);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как долго ты ждешь ответа после CMD1 и что возвращает карточка?

 

Т.к. ты не описывал схему включения, задам несколько вопросов:

- Какой используется кристалл и какая тактовая частота, с какого порта управляется CS?

- Установлен ли керамический блокировочный конденсатор (около 0.1 мкф) по питанию карточки в непосредственной от неё близости?

- Напряжение питания процессора и карточки в пределах 2.8 - 3.6В?

- Если процессор и карточка питаются от разных напряжений, как сделаны преобразователи уровней сигналов?

 

Для чего устанавливаешь бит SPI2X в SPSR?

 

Приведи фрагмент кода (желательно на С), где выполняется обращение к каротчке начиная от установки CS= 0 до выдачи байта в карточку.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После снятия CS нужно передать пустой байт, иначе следующая команда может

не выполниться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как долго ты ждешь ответа после CMD1 и что возвращает карточка?

unsigned char CMD[] = {0x41,0x00,0x00,0x00,0x00,0xFF};
Timeout = 0;

while (Write_Command_MMC(CMD)!=0x00)
{
    if (Timeout++ > 100)
    {
        return(2); //Error (Return Code2)
    }
}

Т.к. ты не описывал схему включения, задам несколько вопросов:

- Какой используется кристалл и какая тактовая частота, с какого порта управляется CS?

Внешний :) 16Mhz, PB0

- Установлен ли керамический блокировочный конденсатор (около 0.1 мкф) по питанию карточки в непосредственной от неё близости?

да. припаян прям к ней между землёй и питанием (земли 2 - замкнуты)

- Напряжение питания процессора и карточки в пределах 2.8 - 3.6В?

3.1 - 3.2 у карточки и 5.1 у процессора.

- Если процессор и карточка питаются от разных напряжений, как сделаны преобразователи уровней сигналов?

Между карточкой и процессором резисторный делитель 450 и 640 Ом. Пробовал на микрухах типа 155ЛП9, там вообще ответов нет.

Для чего устанавливаешь бит SPI2X в SPSR?

А кто сказал что я устанавливаю? (0<<SPI2X) вообщето даёт 0, просто во время тестов 0 менял на 1 и получал 2x - для простоты.

Приведи фрагмент кода (желательно на С), где выполняется обращение к каротчке начиная от установки CS= 0 до выдачи байта в карточку.

unsigned char Write_Command_MMC (unsigned char *CMD)
{
    unsigned char tmp = 0xff;
    unsigned char Timeout = 0;

    MMC_Disable();

    Write_Byte_MMC(0xFF);

    MMC_Enable();

#ifdef DEBUG
    printf("\nWRITE: ");
#endif
    for (unsigned char a = 0;a<0x06;a++)
    {
#ifdef DEBUG
        printf("0x%02x ",*CMD);
#endif
        Write_Byte_MMC(*CMD++);
    }
#ifdef DEBUG
    printf("\nREAD: ");
#endif

    //Wartet auf ein g№ltige Antwort von der MMC/SD-Karte
    while (tmp == 0xff)    
    {
        tmp = Read_Byte_MMC();
#ifdef DEBUG
        printf("0x%02x ",tmp);
#endif
        if (Timeout++ > 100)
        {
            break; //Abbruch da die MMC/SD-Karte nicht Antwortet
        }
    }
#ifdef DEBUG
    printf("\n");
#endif
    return(tmp);
}

unsigned char Read_Byte_MMC (void)
{
    unsigned char Byte = 0;
    SPDR = 0xff;
    loop_until_bit_is_set(SPSR, SPIF);
    Byte = SPDR;
}

void Write_Byte_MMC (unsigned char Byte)
{
    SPDR = Byte; 
    loop_until_bit_is_set(SPSR, SPIF);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

unsigned char Read_Byte_MMC (void)

{

unsigned char Byte = 0;

SPDR = 0xff;

loop_until_bit_is_set(SPSR, SPIF);

Byte = SPDR;

}

 

Тут функция ничего не возвращает (нет return Byte;)

 

Кроме этого как сделано преобразование уровня сигнала MISO? Если подключен напрямую, то его уровень будет на грани, что может вызывать сбои.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно куда он делся, но у меня он есть :)

А вот то что на пряму то верно, у меня напрямую. Будут предложения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В моем устройстве карточка и процессор питаются от 3.3В. Посмотри такой вариант, хотя медленно и кривовато:

 

http://www.deviltronic.de/jpgs/mmc_optimal.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...