STM32: Подключение SD Memory Card к микроконтроллеру по SPI интерфейсу.
Понадобилось подключить SD Memory Card к микроконтроллеру по SPI интерфейсу и поднять FatFs.
Данная тема не нова, многие описывают как подключить, но никто не измерил скорость обмена.
Микроконтроллер китаец очень похожий на STM32.
В используемом микроконтроллере нет SDIO интерфейса, но есть SPI.
И пока плата с микроконтроллером в пути можно потренироваться на STM32.
Под рукой был кит STM32F4 Discovery на основе STM32F407, на нем и будет происходить отладка.
Заодно стало интересно посмотреть какая получиться скорость чтения записи по SPI с учетом разных
частот тактирования ядра STM32.
Как то в 2005 году мне довелось подымать SDCARD+SPI+файловую систему для самодельного MP3
плеера на основе AVR с аппаратным декодером MP3.
Тогда скорость чтения составила в районе ~10-15 кб/с.
Также у меня есть проект sdcard логера на основе STM32F103 + SDIO.
Данная реализация успешно применяется во многих проектах.
Есть вариант реализации для STM32H750+SDIO. Но это все на основе интерфейса SDIO.
Интерфейс SDIO сложнее SPI, SDIO в STM32 у каждого семейства немного разный,
и приходится каждый раз перерабатывать исходники и это не быстро...
Подготовка стенда.
К киту были дополнительно куплены две платы, плата со слотом под SDCARD
и преобразователь USB-to-UART(на основе CH340) для консольной отладки.
Обе платы были припаяны непосредственно к киту, чтобы можно было использовать в виде единой
конструкции, без риска постоянно отваливающихся провода.
Подключения плат к киту:
Консоль UART2 (115200 8N1).
UART2 TX - PA2
UART2 RX - PA3
SDCARD SPI.
SPI2 CLK - PB13
SPI2 MISO - PB14
SPI2 MOSI - PB15
SPI2 CS - PB12 (программное управление)
Далее был собран проект под IAR ARM 7.80.1, были подтянуты исходники файловой системы последней
версии (FatFs v 0.15а) и произведен запуск с отладкой.
Результата работы и отладочная информация выводятся в консоль UART2 (115200 8N1).
В качестве низкоуровневых функций обмена по SPI были взяты исходники из примера FatFs под STM32
в которых были два варианта обмена для SPI 8 бит(8-бит за раз) и SPI 16 бит(16-бит за раз).
В режиме SPI 8 бит работает, а в SPI 16 бит не работает т.к. есть нюанс, который заключается в лишнем
подтягивающем резисторе на линии CLK.
На плате sdcard есть подтягивающие резисторы на линиях CLK, MISO, MOSI, на линии CS подтяжки нет,
а также пара керамических конденсаторов на линиях питания.
Почему не работает для SPI 16 бит ?
Принцип работы перехода с SPI 8->16 бит (и обратно) следующий:
Когда SPI настроен, то удерживает линию SPI CLK в "0".
Для перехода в SPI 16 необходимо выключить SPI путем сброса бита SPE в регистре SPI CR1.
Затем устанавливается бит DFF (SPI 16 битный обмен) в "1" и включается SPI, установкой бита SPE в "1".
В момент ВЫКЛЮЧЕНИЕ SPI (путем сброса бита SPE), SPI контроллер отпускает линию CLK и
т.к. она подтянута к питанию она становится = "1".
В результате SDCARD воспринимает данный переход линии CLK 0->1 как один тактовый сигнал,
что приводит к поломке обмена.
Далее когда SPI снова включается, CLK снова становиться = "0", но один SPI CLK прошел !!!
Поэтому необходимо удалить подтягивающий резистор с линии SPI CLK.
А снятый резистор можно перенести на линию CS чтобы та не висела в воздухе в момент подачи питания до инициализации GPIO STM32.
Будьте внимательны и проверяйте все что можете проверить...
Тест скорости записи-чтения.
Суть теста следующая:
На карте создается файл заданного размера, и измеряется время потраченное на запись в файл.
Тест чтение подобный образом, производится чтение только что созданного файла с измерением времени
потраченного на полное чтение файла.
Тесты проводились при работе ядра в двух режимах с тактированием от HSI (встроенный генератор на 16 Мгц) и
HSE (внешний кварц 8 МГц) + PLL(168 МГц).
HSI=16MHz -> SYSCLK=16 MHZ, SPI CLK=8MHz.
HSE=8MHZ -> SYSCLK=168 MHZ, SPI CLK=21MHz.
SD карта Apacer 16 Gb 2 class (что было под рукой).
SPI 8 бит | SPI 16 бит | |||
CPU/SPI (MГц) |
Запись (байт/с) |
Чтение (байт/с) |
Запись (байт/с) |
Чтение (байт/с) |
16/8 | 118260 | 205216 | 124830 | 213995 |
168/21 | 163840 | 419430 | 166440 | 436906 |
В итоге:
Даже на 16 МГц скорость обмена вполне приличная и может оказаться для большинства задач вполне
достаточной и подымать SDIO интерфейс не обязательно.
За исключение случаев когда нужно обеспечить максимальную теоретическую скорость работы с картой.
Проект занимает:
IAR ELF Linker V7.80.1.11864/W32 for ARM
Copyright 2007-2016 IAR Systems AB.
20 004 bytes of readonly code memory
2 183 bytes of readonly data memory
5 814 bytes of readwrite data memory
Проект может уместиться в микроконтроллер с объемом FLASH памяти 32 Кб.
Исходники проекта на GitHub.
Москва 2025 год.