Информация в современном мире вышла на первый план, переоценить ее значение почти невозможно. А уж ее сохранение - одна из главных задач, которая стоит перед многими компаниями. Что же делать, если ваш крохотный микроконтроллер иногда бывает не подключен к интернету? Как сохранить информацию о том, что же он тогда делал?
Логично же, подключить к SD карте и сохранять на нее.
В прошлых частях неоднократно упоминалось, что STM32CubeMX может бережно изменять программный код, не затирая ваши правки. Сейчас мы воспользуемся этой "фишкой".
Инициализация SDIO
Откроем ранее сохраненный проект и включим поддержку SDIO.
Включение поддержки, активизирует несколько пинов стандарта SDIO.
Описание, как соотносятся конкретные пины со стандартом SD можно найти здесь. Ниже также привожу выдержку из этого описания.
Напряжение питания можно подавать в 3.3 Вольта, которые доступны на плате.
Продолжаем читать Даташит.
Пины D0, D1, D2, D3 и CMD требуют для себя push-pull драйверы. Необходимо для этих пинов включить pull-up,так как у меня нет подтяжки.
На этом настройка SDIO окончена
Проблема тактирования
После инициализации SDIO в STM32CubeMX возникает проблема в тактировании. Единственный способ решения, который я нашел - это переключение источника тактирования.
Включение FATFS
Теперь включим поддержку файловой системы.
Единственный параметр, который я изменил: увеличил значение MAX_SS до 4096.
Один из непонятных моментов -- это вкладка Platform settings, оставил значения по умолчанию. Посмотрим как это отразится в дальнейшем.
Генерация кода
Настало время нажать кнопку "Генерировать"!
Открываем проект в STM32CubeIDE, ничего не должно пропасть, а должно добавиться новое:
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_SDMMC1_SD_Init(void);
Сразу компилируем и... Лично я получил ошибки, так как Куб скопировал все файлы, но не прописал настройки в проект. Пришлось вручную указывать пути.
Код управление SD
Сам код взят из примеров, у меня они загрузились кубок по следующему пути:
STM32Cube\Repository\STM32Cube_FW_F7_V1.15.0\Projects\STM32F722ZE-Nucleo\Applications\FatFS\FatFs_uSD
Исходный код лежит тут: GITHUB
Подключаем плату к компьютеру, запускаем тестовый код и... ничего не получается.
f_mount возвращает FR_OK как и надо, однако f_mkfs возвращает FR_NOT_READY
Что не так, док?
Может не работать:
1. Спаянный мною модуль подключения
2. Связка FATFs SD, сгенерированная HAL
3. Сама uSD карта
Проверяем:
1. Видит ли uSD компьютер? Да, видит
2. Что возвращают функции проверки HAL_SD_init и HAL_SD_GetCardState? Первая возвращает HAL_OK, вторая HAL_SD_CARD_TRANSFER. Что это может значить: карта зависает в режиме передачи данных, на что и реагирует дальнейшая команда f_mkfs.
3. Что вернут эти же функции, если карта не будет установлена? Первая возвращает HAL_OK, вторая ноль. Дополнительно проверяем HAL_SD_GetError, который возвращает HAL_SD_ERROR_CMD_RSP_TIMEOUT. То есть достучаться до карты программа не может.
4. Инициализация? Куб добавил bsp_driver_sd.c, в котором объявлена функция BSP_SD_Init. Как раз в ней, если порыться, есть вызов функции BSP_PlatformIsDetected. И в этой функции обращаются к тому самому пину, заданному по умолчанию. Он никоем образом не связан с нашей картой, поэтому дописываем:
/* USER CODE BEGIN 1 */
/* user code can be inserted here */
status = SD_PRESENT;
/* USER CODE END 1 */
Теперь, работа программы оканчивается fr_disk_err. Какой-то не очень позитивный прогресс...
Ищем помощи у Вселенной в Интернете
Англоязычные товарищи написали, что есть такая ошибка: FATFS настроен работать с DMA, и, если подключать его без DMA, он работать не будет. Что ж подключаем... Однако сейчас разбирать, что такое DMA не будем.
Также там предлагают инициализировать SD перед FATFS, поэтому вписываем:
MX_SDMMC1_SD_Init();
BSP_SD_Init();
HAL_Delay(200);
MX_FATFS_Init();
Дополнительно, заставляем монтировать диск сразу:
res = f_mount(&SDFatFs, (TCHAR const*)SDPath, 1);
Однако все это содержится в "небезопасной" области, поэтому будет затерто. Впрочем, для тестов подойдет.
Странные результаты
f_mkfs, f_write возвращают FR_DISK_ERR.
Теперь f_mount, f_open возвращают FR_OK. Да, файл на карте создается, но в него не записать...
Ну как бы... Продолжение следует
А ларчик открывался просто... Надо было дополнительно включить прерывания SDMMC1
После чего произошла запись на SD карту.
Лайк?