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 год.