Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AVR и SD(mini SD) память
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
сэр_Илья
Нужно связать AVR c SD карточкой памяти (внешняя память для устройства на AVR). Кто нить может подсказать где подробно можно почитать про SD карточки - протокол связи, распиновка разьёма, потребляемый ток и т.д. Вобщем что есть по этой теме. В поисковиках искал подходящего ничего не нашёл. Хотябы пример устройства на AVR с SD карточкой (схема и подробное описание).
Заранее благодарен. Илья. sad.gif
Spider
Эх. ДОРОГОЙ! Искать лучше надо было. Ибо всё уже обсуждалось 1000 раз. не SD так MMC, разницы нет если работаешь по SPI. В качетве информации могу подкинуть (см аттач)
Полное описание большое и форум не позволяет его прицепить, хочеш - пиши на мыло.

ЗЫ. У меня так и не получилось. на CMD0 и CMD1 отвечает, а сектора не отдаёт.
R.Gorsky
Старые версии стандартов MMC v.3.1 (2003г.) и SD MMC (2001г.)
можно взять отсюда:
http://www.bbww.net/SoftDown.asp?ID=8087&lbID=0
там архив примерно 2.7мб.
По этим документам проверял работу с карточками 128, 256 и 512мб.
Spider
Может ты в курсе почему MMC/SD 16Mb не хочет отдавать свой CID и прочее что отдаётся через read-buffer? На команду приходит 0 ответ, а 254 байт не приходет, символизирующий начала передачи буфера.
R.Gorsky
Цитата(Alexey Belyaev @ Feb 12 2006, 20:54) *
Может ты в курсе почему MMC/SD 16Mb не хочет отдавать свой CID и прочее что отдаётся через read-buffer?


Я только начал разбираться с карточками, поэтому читать CID не пробовал. Возможно CID надо читать
аналогично CSD (см. раздел 7.8 стандарта MultiMediaCard System Specification Version 3.31, ссылку
на который я давал раньше)
Spider
Я ж сказал что буферы ваще не читаются, не только CID
R.Gorsky
Может не правильно инициализируешь карточку?

Вот вариант инициализации и работы с карточкой:
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
Spider
сделал всё как предложено выше.
в результате такая штука:
- карточка отвечает 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);
R.Gorsky
Как долго ты ждешь ответа после CMD1 и что возвращает карточка?

Т.к. ты не описывал схему включения, задам несколько вопросов:
- Какой используется кристалл и какая тактовая частота, с какого порта управляется CS?
- Установлен ли керамический блокировочный конденсатор (около 0.1 мкф) по питанию карточки в непосредственной от неё близости?
- Напряжение питания процессора и карточки в пределах 2.8 - 3.6В?
- Если процессор и карточка питаются от разных напряжений, как сделаны преобразователи уровней сигналов?

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

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

В принципе нужно сделать цикл, в котором выполняется обращение к карточке, и смотреть с помощью осциллографа временные соотношения между сигналами.
aaarrr
После снятия CS нужно передать пустой байт, иначе следующая команда может
не выполниться.
Spider
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
Как долго ты ждешь ответа после 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)
    }
}

Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
Т.к. ты не описывал схему включения, задам несколько вопросов:
- Какой используется кристалл и какая тактовая частота, с какого порта управляется CS?

Внешний smile.gif 16Mhz, PB0
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
- Установлен ли керамический блокировочный конденсатор (около 0.1 мкф) по питанию карточки в непосредственной от неё близости?

да. припаян прям к ней между землёй и питанием (земли 2 - замкнуты)
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
- Напряжение питания процессора и карточки в пределах 2.8 - 3.6В?

3.1 - 3.2 у карточки и 5.1 у процессора.
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
- Если процессор и карточка питаются от разных напряжений, как сделаны преобразователи уровней сигналов?

Между карточкой и процессором резисторный делитель 450 и 640 Ом. Пробовал на микрухах типа 155ЛП9, там вообще ответов нет.
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
Для чего устанавливаешь бит SPI2X в SPSR?

А кто сказал что я устанавливаю? (0<<SPI2X) вообщето даёт 0, просто во время тестов 0 менял на 1 и получал 2x - для простоты.
Цитата(R.Gorsky @ Feb 15 2006, 20:05) *
Приведи фрагмент кода (желательно на С), где выполняется обращение к каротчке начиная от установки 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);
}
R.Gorsky
Цитата
unsigned char Read_Byte_MMC (void)
{
unsigned char Byte = 0;
SPDR = 0xff;
loop_until_bit_is_set(SPSR, SPIF);
Byte = SPDR;
}


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

Кроме этого как сделано преобразование уровня сигнала MISO? Если подключен напрямую, то его уровень будет на грани, что может вызывать сбои.
Spider
Странно куда он делся, но у меня он есть smile.gif
А вот то что на пряму то верно, у меня напрямую. Будут предложения?
R.Gorsky
В моем устройстве карточка и процессор питаются от 3.3В. Посмотри такой вариант, хотя медленно и кривовато:

http://www.deviltronic.de/jpgs/mmc_optimal.jpg
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.