| Форум РадиоКот https://radiokot.ru/forum/ |
|
| SDSC карта памяти для STM32F103C8T6 https://radiokot.ru/forum/viewtopic.php?f=59&t=197128 |
Страница 1 из 2 |
| Автор: | Linuxoid91 [ Вт мар 11, 2025 18:57:47 ] |
| Заголовок сообщения: | SDSC карта памяти для STM32F103C8T6 |
Доброго времени суток. Пытаюсь подключить Micro SD карточку на 256 МБ к STM32. Однако, оказалось это весьма не просто. Вообще, основная проблема в том, что карты бывают разных видов в зависимости от ёмкости - SDSC, SDHC, и т.д. К первому типу относятся карты до 2 ГБ (как раз мой случай), и все бы ничего, но большинство разработчиков забили на поддержку таких карт. Вроде есть проекты на другие МК, но портировать их в Cube IDE пока не удалось. Сложное это дело, карты памяти читать... Нашел проект, реализованный на Petit FatFS. Он вроде обещает работу с мелкими карточками, но на STM его нет, а вдумчивое чтение и перенос кода на Cube пока не принесло успехов. Может, есть у кого собранный в Cube рабочий проект чтения карт памяти SDSC для STM32F103C8T6? |
|
| Автор: | HardWareMan [ Вт мар 11, 2025 20:36:29 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Я реализовал свой собственный инит карты по этому чарту: ![]() А потом просто использовал FatFS от Чена, причём в моей версии пришлось исправлять ошибку преобразования адреса в сектор (и наоборот) потому что для XC должен использоваться uint64_t а Чен тогда использовал только uint32_t. Это было 10 лет назад, в современных версиях вроде как это уже пофикшено. |
|
| Автор: | Linuxoid91 [ Ср мар 12, 2025 07:00:46 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Вот где-то на этапе R1 resp все и заканчивается. Возвращает нули, хоть ты тресни Сегодня, в 4-й день моего "приключения на 15 минут" я, все же, решил посмотреть осциллографом сигналы, которые подает код, работающий с картами от 2 гигов. Описаний как инициализировать карту, множество. Вот например. Дословно читаем процесс перевода карты в режим SPI. - Подать единицу на CS. - Подать единицу на MOSI. - Подать 74 или более импульсов на линию CLK. Однако, фактически CS выставляется в 0 в начальный момент времени, и всегда в единице все оставшееся время. То есть, инициализация SPI происходит при выставлении НУЛЯ на CS и ЕДИНИЦЫ во время операций чтения-записи. А в описании все наоборот... Да и по логике работы SPI CS должно быть в нуле во время обращения к устройству, а в SD картах, выходит, все строго наоборот |
|
| Автор: | HardWareMan [ Ср мар 12, 2025 07:18:05 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
А ты скорость понижаешь? Инит карты происходит строго на частоте ниже 400кГц. А ещё, я подаю не 74CLK а 256 байт (т.е. 256*8 CLK). Некоторым картам мало всего лишь 74 такта. СпойлерВот мой код для 030 из этого проекта, для понимания сути, может на что-то натолкнёт:Код: // Константы команд SD карты #define CMD_LENGTH ((uint32_t) 6 ) // Размер команды #define CARD_DATA_TOKEN ((uint8_t) 0xFE ) // Токен начала данных #define CARD_CMD17 ((uint8_t) 0x51 ) // Команда чтения блока #define CARD_CMD24 ((uint8_t) 0x58 ) // Команда записи блока // CMD0: GO_IDLE_STATE static const uint8_t CARD_CMD0[ CMD_LENGTH ] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x95 }; // CMD8: SEND_IF_COND static const uint8_t CARD_CMD8[ CMD_LENGTH ] = { 0x48, 0x00, 0x00, 0x01, 0xAA, 0x87 }; // CMD16: SET_BLOCKLEN static const uint8_t CARD_CMD16[ CMD_LENGTH ] = { 0x50, 0x00, 0x00, 0x02, 0x00, 0xFF }; // ACMD55: APP_CMD static const uint8_t CARD_CMD55[ CMD_LENGTH ] = { 0x77, 0x00, 0x00, 0x00, 0x00, 0xFF }; // CMD58: READ_OCR static const uint8_t CARD_CMD58[ CMD_LENGTH ] = { 0x7A, 0x00, 0x00, 0x00, 0x00, 0xFF }; // ACMD41: APP_SEND_OP_COND static const uint8_t CARD_ACMD41[ CMD_LENGTH ] = { 0x69, 0x40, 0x00, 0x00, 0x00, 0xFF }; // Посылаем команду и ждём окончания передачи void Card_SendCMD(const uint8_t *Buf, uint32_t Size ) { // Локальная переменная uint16_t Data; // Если есть данные while ( Size > 0 ) { // Первым делом формируем данные, с учётом пакинга для оптимизации Data = *(Buf); Buf++; Size--; if ( Size > 0 ) { // Забираем второй байт тоже Data += (*(Buf) * 0x100); Buf++; Size--; } // Данные сформированы, ожидаем готовности буфера передачи while ( (SPI1->SR & SPI_SR_TXE) == 0 ) {} // Передаём данные SPI1->DR = Data; } // Ожидаем опустошения очереди передачи while ( (SPI1->SR & SPI_SR_FTLVL) != 0 ) { Data = SPI1->DR; } // Ждём завершения последней транзакции while ( (SPI1->SR & SPI_SR_BSY) != 0 ) { Data = SPI1->DR; } // Опусташаем буфер приёма while ( (SPI1->SR & SPI_SR_FRLVL) != 0 ) { Data = SPI1->DR; } } // Посылаем байт и ждём ответ uint8_t Card_SPI( uint8_t Data ) { // Локальная переменная uint8_t Res; // Ожидаем готовности передатчика while ( (SPI1->SR & SPI_SR_FTLVL) != 0 ) { } // Посылаем слово *((__IO uint8_t *)&SPI1->DR) = Data; // Ожидаем готовности приёмника while ( (SPI1->SR & SPI_SR_RXNE) == 0 ) { } // Вычитываем Res = *((__IO uint8_t *)&SPI1->DR); // Выход return Res; } // Ожидаем ответ uint8_t Card_WaitResp( uint32_t *OCR, FunctionalState R7, uint8_t Count ) { // Локальная переменная uint8_t Res,Cnt; // Инит переменной *(OCR) = 0xFFFFFFFF; // Поиск первого байта ответа do { // Получаем данные Res = Card_SPI( 0xFF ); // И уменьшаем счётчик Count--; } while ( ((Res & 0xC0) != 0) && (Count > 0) ); // Проверяем, требуется ли догрузка ещё 4х байт? if ( R7 == ENABLE ) { // Догружаем ещё 4 байт (всего 40 бит вместе с Res) for (Cnt = 0; Cnt < 4;Cnt++) { // Готовим место под байт *(OCR) <<= 8; *(OCR) &= 0xFFFFFF00; // Получаем данные *(OCR) += Card_SPI( 0xFF ); } } // Ожидаем как минимум 1 байт с 0xFF while ( Card_SPI( 0xFF ) != 0xFF ) { } // Выход return Res; } // Инициализация карты памяти TCardType Card_Init( void ) { // Локальные переменные TCardType Res; uint32_t Cnt,OCR; uint8_t Dat, Resp; // Отключаем карту CARD_OFF; Res = ctNone; // Настраиваем SPI на медленную скорость PCLK/128: 48/128 = 0,375МГц SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR1 = SPI_CR1_MSTR | SPI_LOW_SPEED; SPI1->CR1 |= SPI_CR1_SPE; // Топчемся на месте HAL_Delay( 1 ); // Посылаем инит 256 байт for (Cnt = 0;Cnt < 256;Cnt++ ) { // Послыаем слово Card_SPI( 0xFF ); } // Начинаем инициализацию карты CARD_ON; // Ожидаем готовности карты do { // Посылаем 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // CMD0: GO_IDLE_STATE Card_SendCMD( &CARD_CMD0[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // Какой ответ получен? if ( Resp == 0x01 ) { // Карта вошла в IDLE_STATE, посылаем CMD8: SEND_IF_COND Card_SendCMD( &CARD_CMD8[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); // Если был дан адекватный респонс if ( Resp != 0x01 ) { // Это ветка SDv1/MMC do { // Посылаем ACMD41: APP_SEND_OP_COND Card_SendCMD( &CARD_ACMD41[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); } while ( Resp == 0x01 ); // Каков был ответ? if ( Resp == 0x00 ) { // Обнаружена карта SD v1 Res = ctSD1; } else { // Это ветка MMC, нам её некуда втыкать Res = ctUnknown; } } else { // Это ветка SDv2 if ( (OCR & 0x0001FF) == 0x0001AA ) { // Это карта SDv2 do { // Посылаем ACMD55: APP_CMD Card_SendCMD( &CARD_CMD55[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // Если ответ правильный if ( Resp == 0x01 ) { // Посылаем ACMD41: APP_SEND_OP_COND Card_SendCMD( &CARD_ACMD41[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); } } while ( Resp == 0x01 ); // Каков был ответ? if ( Resp == 0x00 ) { // Посылаем CMD58: READ_OCR Card_SendCMD( &CARD_CMD58[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); // Каков ответ? if ( Resp == 0x00 ) { // Анализируем OCR if ( (OCR & 0x40000000) == 0x00000000 ) { // Карта обычной ёмкости Res = ctSD2; } else { // Карта повышенной ёмкости Res = ctSD3; } } else { // Эта карта неисправна Res = ctUnknown; } } else { // Эта карта неисправна Res = ctUnknown; } } else { // Эта карта неисправна Res = ctUnknown; } } } else { // Карта ответила неправильно if ( Res != 0xFF ) { Res = ctUnknown; } } // Только для карт обычной ёмкости if ( (Res == ctSD1) || (Res == ctSD2) ) { // Устанавливаем размер блока 512 байт // CMD16: SET_BLOCKLEN Card_SendCMD( &CARD_CMD16[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // Каков ответ? if ( Resp != 0x00 ) { // Эта карта неисправна Res = ctUnknown; } } // Выключаем карту while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // Если карта инициализирована if ( (Res != ctNone) && (Res != ctUnknown) ) { // Настраиваем SPI на быструю скорость PCLK/2: 48/2 = 24МГц SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR1 = SPI_CR1_MSTR; SPI1->CR1 |= SPI_CR1_SPE; } // Выходим return Res; } // Чтение сектора карты памяти без DMA FunctionalState Card_Read( TCardType CardType, uint8_t *Buf, uint32_t *Loaded, uint32_t Addr ) { // Локальные переменные FunctionalState Res; uint8_t Cmd[ 6 ]; uint8_t Dat,Resp; uint32_t Cnt; // Инит Res = DISABLE; // Посмотрим, у нас в буфере уже загружено? if ( *(Loaded) != Addr ) { // Сохраняем новый номер сектора *(Loaded) = Addr; // Корректируем адрес для старых карт if ( (CardType == ctSD1) || (CardType == ctSD2) ) { // У старых карт адрес вместо LBA Addr *= 0x00000200; } // Работаем while ( 1 ) { // Если тип карты неправильный - выходим if ( CardType == ctNone ) { break; } if ( CardType == ctUnknown ) { break; } // Готовим команду на чтение сектора Cmd[ 0 ] = CARD_CMD17; Cmd[ 1 ] = Addr >> 24; Cmd[ 2 ] = Addr >> 16; Cmd[ 3 ] = Addr >> 8; Cmd[ 4 ] = Addr; Cmd[ 5 ] = 0xFF; // Включаем карту CARD_ON; // Ожидаем готовности карты do { // Посылаем 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // Посылаем команду чтения Card_SendCMD( &Cmd[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( (uint32_t *)&Cmd[ 0 ], DISABLE, 128 ); // Анализируем ответ на команду if ( Resp != 0x00 ) { break; } // Ожидаем токен данных Cnt = 2048; do { // Считываем данные Dat = Card_SPI( 0xFF ); // Считаем Cnt--; } while ( (Dat == 0xFF) && (Cnt > 0) ); // Таймаут? if ( Cnt == 0 ) { break; } // Ошибка в токене? if ( Dat != CARD_DATA_TOKEN ) { break; } // Начались данные, загружаем for (Cnt = 0;Cnt < 512;Cnt++) { // Считываем данные *(Buf) = Card_SPI( 0xFF ); Buf++; } // Дочитываем CRC Cmd[ 0 ] = Card_SPI( 0xFF ); Cmd[ 1 ] = Card_SPI( 0xFF ); // Без ошибок Res = ENABLE; // Выход break; } } else { // Без ошибок Res = ENABLE; } // Выключаем карту while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // Если была ошибка, обнулим номер if ( Res == DISABLE ) { *(Loaded) = 0xFFFFFFFF; } // Выход return Res; } // Запись сектора карты памяти без DMA FunctionalState Card_Write( TCardType CardType, uint8_t *Buf, uint32_t *Loaded, uint32_t Addr ) { // Локальные переменные FunctionalState Res; uint8_t Cmd[ 6 ]; uint8_t Dat,Resp; uint32_t Cnt; // Инит Res = DISABLE; // Корректируем адрес для старых карт if ( (CardType == ctSD1) || (CardType == ctSD2) ) { // У старых карт адрес вместо LBA Addr *= 0x00000200; } // Работаем while ( 1 ) { // Если тип карты неправильный - выходим if ( CardType == ctNone ) { break; } if ( CardType == ctUnknown ) { break; } // Готовим команду на чтение сектора Cmd[ 0 ] = CARD_CMD24; Cmd[ 1 ] = Addr >> 24; Cmd[ 2 ] = Addr >> 16; Cmd[ 3 ] = Addr >> 8; Cmd[ 4 ] = Addr; Cmd[ 5 ] = 0xFF; // Включаем карту CARD_ON; // Ожидаем готовности карты do { // Посылаем 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // Посылаем команду чтения Card_SendCMD( &Cmd[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( (uint32_t *)&Cmd[ 0 ], DISABLE, 128 ); // Анализируем ответ на команду if ( Resp != 0x00 ) { break; } // Посылаем токен данных Card_SPI( CARD_DATA_TOKEN ); // Посылаем данные в цикле // Начались данные, загружаем for (Cnt = 0;Cnt < 512;Cnt++) { // Считываем данные Card_SPI( *(Buf) ); Buf++; } // Досылаем CRC Card_SPI( 0xFF ); Card_SPI( 0xFF ); // Без ошибок Res = ENABLE; // Выход break; } // Выключаем карту while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // Успешно? if ( Res == ENABLE ) { // Сохраняем новый номер сектора *(Loaded) = Addr; } else { // Обнуляем *(Loaded) = 0xFFFFFFFF; } // Выход return Res; } |
|
| Автор: | jcxz [ Ср мар 12, 2025 11:26:00 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Описаний как инициализировать карту, множество. Вот например. Имхо - здесь описание лучше: http://elm-chan.org/docs/mmc/mmc_e.htmlОднако, фактически CS выставляется в 0 в начальный момент времени, и всегда в единице все оставшееся время. В смысле? Не понял вашу фразу.То есть, инициализация SPI происходит при выставлении НУЛЯ на CS и ЕДИНИЦЫ во время операций чтения-записи. А в описании все наоборот... Да и по логике работы SPI CS должно быть в нуле во время обращения к устройству, а в SD картах, выходит, все строго наоборот Ничего там не наоборот. Начальные 74+ клока при CS=high - нужны очевидно для завершения возможных незавершённых сдвигов в машине состояний схемы карты. Если предыдущий цикл работы устройства оборвался во время передачи команды (МК неожиданно пересбросился). Вот чтобы вы-flush-ить все буфера и счётчики клоков карты и нужно, до начала работы с картой, при CS=high подать множество циклов.А штатная работа карты - естественно - при CS=low. На вышеприведённой ссылке это видно. Параграф "Cosideration on Multi-slave Configuration". Вот где-то на этапе R1 resp все и заканчивается. Значит что-то не так делаете. Проверку занятости делаете (как описано по ссылке выше)?PS: Реализовывал обмен с картами по этому описанию (давно правда) - работало со всеми картами. В том числе и с имевшейся тогда MMC на 256MB. |
|
| Автор: | Linuxoid91 [ Ср мар 12, 2025 18:03:53 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Нашел таки логический анализатор, и вот что получилось. Да, CS ведет как в описании. Наверное, осциллограф чудит при отображении информации. Сперва карты здорового человека и рабочий проект, который делает тестовые чтение-запись. Переходят в режим SPI без проблем. ![]() А вот карточки на 256 МБ. Уже и 256 единичных байт подал после запуска, и частоту задавил аж до 16 кбит (меньше уже нельзя, так как кварц 8 МГц). Карты здорового человека все еще определяются, но возвращают ошибку при попытке записи. В ответ лишь одиночные импульсы в рандомный момент времени. Похоже, нет у них режима SPI. Надо сказать, что карточки новодельные - продаются на алике упаковками по 5-10 штук. Возможно, поддержку SPI в них не завезли. В нативном режиме, судя по всему, работают нормально, так как прекрасно работают в компе... Такой же результат выдала двухгиговая карточка от Silicon Power
|
|
| Автор: | jcxz [ Ср мар 12, 2025 18:37:06 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Возможно, поддержку SPI в них не завезли. Сомнительно. Думаете - для таких дешёвых станут разрабатывать свой собственный уникальный контроллер? Лишь для того, чтобы выкусить SPI?Наверняка в них использован стандартный контроллер SD. А он ещё с былинных времён поддерживает SPI-режим. |
|
| Автор: | HardWareMan [ Ср мар 12, 2025 21:54:04 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
![]() А что за команда 0xA0 у вас в логе? А вообще, можете поделиться логами в бинарном формате а не картинками, чтобы изучить весь процесс? |
|
| Автор: | Linuxoid91 [ Чт мар 13, 2025 05:16:07 ] | ||
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 | ||
А вообще, можете поделиться логами в бинарном формате а не картинками, чтобы изучить весь процесс? Прикладываю файлы, созданные в PulseView. В бинарниках 4 канала, 1 MSmp/s. Реальная частота шины 140,625 kBit/s В "нормальной" флешке помимо инициализации код произвел чтение-запись
|
|||
| Автор: | HardWareMan [ Чт мар 13, 2025 07:17:36 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Прикладываю файлы, созданные в PulseView. Ааа, это ты забыл указать декодеру /SS. Там нормально 0х40. Вот нормальный лог: ![]() Вот лог курильщика: ![]() Зачем ты продолжаешь долбить после команды? |
|
| Автор: | Linuxoid91 [ Чт мар 13, 2025 13:28:05 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
[uquote="Linuxoid91",url="/forum/viewtopic.php?p=4693129#p4693129"]Зачем ты продолжаешь долбить после команды? Это чей-то скачанный с гитхаба пример. Уже не помню, какой конкретно - я их несколько скачал. Этот инициализирует карту, затем работает уже с FATFS - измеряет емкость, записывает и стирает файл, и т.д. Самое главное, что он выдает результат работы в UART, и сразу видно, что работа программы ведется. Единственное, что поменял в его работе - это увеличил количество стартовых байт с 10 до 255. Дальше код не менял Добавлено after 35 minutes 1 second: В любом случае, курильщик холоден к попыткам связи его через SPI. Вообще, конечно, вряд ли китайцы специально вырезали протокол SPI, просто мне попалась версия с тем самым контроллером, где его нет. Однако, назрела необходимость заказать МК с интерфейсом SDIO, например, STM32F411. Смешно, но Bluepill ждали своего часа более 5 лет, ибо задачи для него достойной не находилось. Нужда пришла откуда не ждали - устройство должно стать мелкосерийным, а значит, старых запасов 8-битных МК не напасешься, а новые стоят неприлично много. Проект, к счастью, не коммерческий |
|
| Автор: | jcxz [ Чт мар 13, 2025 16:56:57 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Вот нормальный лог: Какой же он нормальный, если начинается с команды CMD40?![]() Вы же сами выше приводили блок-схему алгоритма инициализации, из которой видно, что первой должна идти команда CMD0? А до неё ещё должны идти 74+ клоков при CS=high. |
|
| Автор: | Linuxoid91 [ Чт мар 13, 2025 17:54:34 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Какой же он нормальный, если начинается с команды CMD40? Вы же сами выше приводили блок-схему алгоритма инициализации, из которой видно, что первой должна идти команда CMD0? А до неё ещё должны идти 74+ клоков при CS=high. Все команды имеют формат 01хххххх. То есть, сами команды 6-битные, к которым в качестве старших битов дописывается 01. Таким образом, CMD0=0100000 или 0х40 |
|
| Автор: | HardWareMan [ Чт мар 13, 2025 19:09:52 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Какой же он нормальный, если начинается с команды CMD40? "Нормальный" он по классификации ТСа (так подписан файл лога) а не по сути. Все команды имеют формат 01хххххх. То есть, сами команды 6-битные, к которым в качестве старших битов дописывается 01. Таким образом, CMD0=0100000 или 0х40 Я лишь добавлю, что команда CMD40 существует. Её код это 0х68, потому что на интерфейсе ходит HEX а в названиях используется DEC. |
|
| Автор: | Linuxoid91 [ Сб мар 15, 2025 17:40:41 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Покуда придумываю, как бы мне заменить SPI на SDIO, нашел STM32F411 и мертвый DFPlayer в качестве слота Micro SD карты. И обнаружил, что на плеере не распаяны выводы 1,2 и 8 (фото в цвете). То есть, в режиме SDIO оборваны линии DAT1,2,3, а в режиме SPI - линия CS... Выходит, либо SD карточки работают по SPI безо всяких CS, либо по SDIO можно припаять всего один выход данных? Буду пробовать примерно через неделю, не раньше
|
|
| Автор: | HardWareMan [ Сб мар 15, 2025 17:54:40 ] | ||
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 | ||
SDIO может работать в 1, 4 и 8 битном режимах.
|
|||
| Автор: | Linuxoid91 [ Вс мар 16, 2025 14:10:32 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Странно, что SD карты поддерживают 8-битный SDIO. Ведь у Micro SD всего 8 пинов... Теоретически, конечно, можно себе это представить, но сложно |
|
| Автор: | HardWareMan [ Вс мар 16, 2025 15:47:02 ] | ||
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 | ||
Это может быть для MMC предназначено. У них есть 8 бит варианты, в том числе и eMMC, а контроллер SDIO у STM это общий интерфейс для карт памяти.
|
|||
| Автор: | jcxz [ Вс мар 16, 2025 17:42:05 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
SDIO - это просто интерфейс. Не только SD-карты могут по нему подключаться. Есть микросхемы eMMC - они как раз используют 8 бит SDIO. Также встречал WiFi-чипы, подключающиеся по SDIO: TiWi-R2 (хотя в нём всего 4-битный SDIO). https://www.ezurio.com/part/450-0037 |
|
| Автор: | Linuxoid91 [ Сб мар 29, 2025 15:37:35 ] |
| Заголовок сообщения: | Re: SDSC карта памяти для STM32F103C8T6 |
Нашел такую схему организации 1-битного SDIO посредством SPI. Однако, главный вопрос - а не сгорит? Ведь насколько мне известно, SPI не является интерфейсом с открытым коллектором, и в режиме простоя на нем единица... Смущает, правда, название RSPI... Из того, что я понял, его подключение ничем не отличается от SPI, и R в названии - не подтягивающий резистор... Но кажется, все будет работать, если запаять резистор последовательно с сигналом MOSI, а подтяжку к плюсу у D0 убрать... Правда, на STM так, похоже, никто не делал, либо я не нашел. Вообще, необходимость подтягивающих резисторов и двунаправленность больше напоминает интерфейс I2C.
|
|
| Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|






