Создание MIDI-устройства на STM32F072

Ключевые тезисы

  • Используется дешёвый микроконтроллер STM32F072C8T6 со встроенным USB, работающим от внутреннего генератора.
  • Цель — создать кастомное USB-MIDI устройство, которое будет проигрывать мелодию на компьютере.
  • Для разработки применяется самодельная плата, китайский программатор ST-Link и среда STM32CubeIDE.
  • Класс USB-устройства меняется с HID (Human Interface Device) на MIDI с помощью файлов из открытого проекта.
  • В результате создаётся рабочее MIDI-устройство, проигрывающее простую мелодию через виртуальный инструмент в DAW (например, Reaper).

Аппаратная часть

Выбор контроллера и платы

  • Основной чип — STM32F072C8T6. Его ключевое преимущество — встроенный USB-модуль, работающий без внешнего кварца, только от внутреннего тактового генератора на 48 МГц.
  • Чип припаян на универсальную макетную плату. Обвязка включает:
    • Кнопку сброса (Reset)
    • Светодиод на выводе PA0
    • Стабилизатор напряжения 3.3В для питания от USB
    • Разъём SWD для программирования
  • Для программатора используется доработанный китайский клон ST-Link. Доработка заключается в переключении вывода сброса с режима для STM8 на режим для STM32.

Что такое MIDI?

MIDI-протокол — это цифровой протокол для обмена музыкальными командами, а не аудиосигналом.

  • Устройство не издаёт звук само, а отправляет команды (нажатие ноты, изменение параметра) на компьютер или синтезатор.
  • Исторически использовались 5-пиновые DIN-разъёмы, но сейчас распространён USB-MIDI класс, который позволяет передавать MIDI-сигналы через стандартный USB-порт.
  • Это открывает возможности для создания нестандартных MID-контроллеров (например, управляемых ультразвуковым датчиком расстояния).

Настройка проекта в STM32CubeIDE

  1. Создание проекта: В STM32CubeMX выбирается микроконтроллер STM32F072C8T6.
  2. Конфигурация пинов: Пин PA0 настраивается как GPIO_Output для светодиода.
  3. Включение USB: В разделе Connectivity активируется модуль USB в режиме Device (FS).
  4. Выбор класса USB: В настройках Middleware первоначально выбирается класс USB Device (HID), как наиболее универсальный и простой для последующей модификации.
  5. Настройка тактирования: Частота ядра и USB-модуля выставляется на 48 МГц.
  6. Генерация кода: Проект генерируется для инструментария STM32CubeIDE.

Преобразование HID в MIDI-устройство

Поскольку в стандартном стеке STM32 нет класса MIDI, используется готовое решение:

  1. Загрузка файлов MIDI-стека: С GitHub скачивается проект "MIDI Box STM32". Из него берутся два файла: usbd_midi.c и usbd_midi.h.
  2. Интеграция файлов: Файлы помещаются в папки проекта, соответствующие классу HID (Middlewares/ST/STM32_USB_Device_Library/Class/HID/), чтобы не менять настройки путей компиляции.
  3. Модификация кода: В автосгенерированных файлах вносятся правки для замены класса HID на MIDI:
    • В usb_device.c: Заменяются включение (#include) и имя класса в объявлении дескриптора с HID на MIDI.
    • В usbd_conf.c: Меняется включение файла, а в раздел конфигурации эндпоинтов (между USER CODE BEGIN/END) добавляется строка инициализации для MIDI. Также изменяется имя класса в объявлении переменной USBD_ClassTypeDef.
    • В main.h: Объявляются константы для выбора MIDI-канала (например, канал 1).
  4. Важное замечание: Эти правки в автосгенерированном коде будут потеряны при повторной генерации проекта через CubeMX. Их нужно будет вносить заново.

Написание логики приложения

Чтобы не загромождать автосгенерированный main.c, логика выносится в отдельные файлы:

  1. Создание файлов приложения: В проекте создаются app.c и app.h.
  2. Организация кода: В main.c добавляется #include "app.h" и вызов функции app_run() после инициализации, перед основным циклом. Бесконечный цикл реализуется уже в app.c.
  3. Реализация MIDI-логики:
    • Определяются MIDI-номера нот (например, нота Ля первой октавы = 69).
    • Пишется функция отправки MIDI-события (app_midi_send_event).
    • Создаётся функция проигрывания ноты с заданной длительностью, которая включает/выключает светодиод.
    • Реализуется функция проигрывания куплета песни "В траве сидел кузнечик" (ноты Ми, Ля, Соль-диез) с разными длительностями.
    • В бесконечном цикле app_run() вызывается функция проигрывания мелодии с паузами.

Прошивка и тестирование

  1. Настройка программатора: В конфигурациях запуска (Debug Configurations) CubeIDE выбирается ST-Link, интерфейс SWD и опция Connect under reset.
  2. Прошивка: Проект компилируется и прошивается в контроллер кнопкой Run.
  3. Проверка в системе: После подключения платы к USB, в диспетчере устройств Windows появляется новое устройство в категории "Звуковые, игровые и видеоустройства". Его имя меняется через редактирование строки в коде (USB_Device/app/usbd_desc.c).
  4. Тест в DAW: В музыкальной программе (например, Reaper) в настройках MIDI появляется новый порт с именем устройства. Создав трек с виртуальным инструментом и выбрав этот порт на вход, можно услышать мелодию, проигрываемую микроконтроллером.

Выводы
Проект демонстрирует, как на базе недорогого микроконтроллера STM32F072 можно создать полноценное USB-MIDI устройство. Полученный результат служит основой для разработки собственных MIDI-контроллеров, управляемых любыми датчиками или элементами ввода.