Как настроить составное USB-устройство на микроконтроллере STM32. Какие классы USB-устройств можно использовать в STM32. Как реализовать собственный класс USB-устройства для STM32. Как отлаживать и тестировать USB-устройство на базе STM32.
Основы USB Device для микроконтроллеров STM32
USB (Universal Serial Bus) — это стандартный интерфейс подключения периферийных устройств к компьютеру. Многие микроконтроллеры семейства STM32 имеют встроенный USB-интерфейс, позволяющий реализовать различные USB-устройства.
Основные особенности USB Device в STM32:
- Поддержка Full Speed (12 Мбит/с) и High Speed (480 Мбит/с) режимов
- Реализация стандартных классов USB-устройств: HID, CDC, MSC и др.
- Возможность создания собственных классов устройств
- Поддержка составных устройств с несколькими интерфейсами
- Встроенные библиотеки USB Device от STMicroelectronics
Для разработки USB-устройства на STM32 потребуется:
- Микроконтроллер STM32 с USB-интерфейсом
- Среда разработки (например, STM32CubeIDE)
- Библиотеки USB Device от ST
- Программатор-отладчик ST-LINK
Настройка проекта USB Device в STM32CubeIDE
Рассмотрим основные шаги по созданию проекта USB-устройства в STM32CubeIDE:

- Создайте новый проект и выберите целевой микроконтроллер
- В настройках RCC включите внешний высокоскоростной генератор (HSE)
- В разделе Connectivity включите USB OTG и выберите режим Device
- В Middleware активируйте USB_DEVICE и выберите нужный класс устройства
- Настройте тактирование для обеспечения 48 МГц для USB
- Сгенерируйте код проекта
После этого базовая конфигурация USB-устройства будет готова. Теперь можно приступать к программированию функционала устройства.
Реализация стандартных классов USB-устройств
STM32 поддерживает следующие стандартные классы USB-устройств:
- HID (Human Interface Device) — для клавиатур, мышей и т.п.
- CDC (Communication Device Class) — для эмуляции последовательного порта
- MSC (Mass Storage Class) — для USB-накопителей
- Audio — для звуковых устройств
- DFU (Device Firmware Upgrade) — для обновления прошивки
Рассмотрим реализацию CDC устройства для эмуляции виртуального COM-порта:
- В CubeMX выберите класс CDC
- В usbd_cdc_if.c реализуйте функции приема и передачи данных:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { // Обработка принятых данных CDC_Transmit_FS(Buf, *Len); // Эхо return (USBD_OK); } static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) { switch(cmd) { case CDC_SEND_ENCAPSULATED_COMMAND: break; case CDC_GET_ENCAPSULATED_RESPONSE: break; case CDC_SET_COMM_FEATURE: break; case CDC_GET_COMM_FEATURE: break; case CDC_CLEAR_COMM_FEATURE: break; case CDC_SET_LINE_CODING: break; case CDC_GET_LINE_CODING: break; case CDC_SET_CONTROL_LINE_STATE: break; case CDC_SEND_BREAK: break; } return (USBD_OK); }
После этого устройство будет определяться как виртуальный COM-порт и позволит обмениваться данными с ПК.

Создание пользовательского класса USB-устройства
Для реализации собственного класса USB-устройства потребуется:
- Определить дескрипторы устройства, конфигурации, интерфейсов
- Реализовать функции инициализации, деинициализации устройства
- Обработать стандартные USB-запросы
- Реализовать функции приема/передачи данных
Пример определения дескриптора устройства:
__ALIGN_BEGIN static uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, // Размер дескриптора
USB_DESC_TYPE_DEVICE, // Тип дескриптора
0x00, 0x02, // Версия USB
0xFF, // Класс устройства
0x00, // Подкласс устройства
0x00, // Протокол устройства
USB_MAX_EP0_SIZE, // Максимальный размер пакета EP0
LOBYTE(USBD_VID), // Vendor ID
HIBYTE(USBD_VID),
LOBYTE(USBD_PID), // Product ID
HIBYTE(USBD_PID),
0x00, 0x02, // Номер версии устройства
USBD_IDX_MFC_STR, // Индекс строки производителя
USBD_IDX_PRODUCT_STR, // Индекс строки продукта
USBD_IDX_SERIAL_STR, // Индекс серийного номера
USBD_MAX_NUM_CONFIGURATION // Количество конфигураций
};
Базовые функции для реализации класса устройства:

static uint8_t USBD_MyClass_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_MyClass_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_MyClass_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_MyClass_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_MyClass_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
Отладка и тестирование USB-устройства
Для отладки USB-устройства на STM32 можно использовать следующие инструменты:
- Анализатор протокола USB (например, USBlyzer)
- Встроенные средства отладки IDE (точки останова, просмотр переменных)
- Осциллограф для анализа сигналов на линиях D+ и D-
- Логирование через UART или SWO
Основные шаги тестирования:
- Проверка корректности перечисления устройства в системе
- Тестирование стандартных USB-запросов
- Проверка передачи данных в обоих направлениях
- Стресс-тестирование на больших объемах данных
- Проверка энергопотребления в различных режимах
Для тестирования можно использовать специальные утилиты или написать собственное ПО верхнего уровня.

Особенности реализации составных USB-устройств
Составное USB-устройство позволяет объединить несколько функций в одном физическом устройстве. Например, можно реализовать одновременно HID-мышь и виртуальный COM-порт.
Для создания составного устройства необходимо:
- Определить несколько интерфейсов в дескрипторе конфигурации
- Реализовать обработчики для каждого класса устройства
- Корректно обрабатывать запросы к разным интерфейсам
Пример структуры составного HID+CDC устройства:
typedef struct _USBD_CDC_HID_Itf { USBD_CDC_Itf_TypeDef CDC; USBD_HID_Itf_TypeDef HID; } USBD_CDC_HID_Itf_TypeDef; static USBD_CDC_HID_Itf_TypeDef USBD_Interface_fops_FS = { CDC_Init_FS, CDC_DeInit_FS, CDC_Control_FS, CDC_Receive_FS, HID_Init_FS, HID_DeInit_FS, HID_OutEvent_FS };
При реализации составного устройства важно корректно распределять ресурсы между интерфейсами и обеспечивать их независимую работу.
Заключение
Разработка USB-устройств на базе микроконтроллеров STM32 открывает широкие возможности для создания различных периферийных устройств. Ключевые моменты:

- Использование готовых библиотек USB Device от ST значительно упрощает разработку
- Поддержка стандартных классов позволяет быстро реализовать типовые устройства
- Возможность создания пользовательских классов обеспечивает гибкость
- Составные устройства расширяют функциональность
- Важно уделять внимание отладке и тестированию USB-устройств
При грамотном подходе STM32 позволяет создавать надежные и функциональные USB-устройства различного назначения.
USB HID интерфейс для STM32 в STM32IDE / Своими руками (DIY) / iXBT Live
Ряд микроконтроллеров STM32 имеют на борту USB интерфейс для связи с компьютерами. Как правило, удобнее всего использовать предоставляемый компаний ST Microelectronics драйвер класса CDC (Communication Device Class ). Он позволяет использовать на стороне компьютера UART через USB и не требует установки драйверов. Со стороны STM32 при этом требуется только поменять операции вывода данных, остальное делается самостоятельно. Причём скорость такого соединения может быть практически любой, поддерживаемой компьютером.
Однако ряд разработок, особенно, когда приходишь в другую компанию, где используется HID Class (Human Interface Device), в случае разработки новой версии устройства требуется поддерживать ранее выбранный интерфейс. Что, собственно, и случилось. Примеры проектов от самой ST, которые они дают при загрузке STM32 Cube MX и IDE, как обычно, дали только минимальное понимание, но не раскрыли, что и как надо делать. Я когда-то разбирался с USB, даже писал собственный драйвер, но это было так давно… Остались только общие воспоминания. Посему пришлось искать дополнительную информацию, чтобы получить стартовую точку.
Первое найденное было видеороликом на youtube в стиле HID за 5 минут 🙂 Автор даёт доступ к своему коду на GitHub. Всё, типа круто, красиво, просто вставляйте к себе и всё будет чудесно. Судя по отзывам под роликом, некоторым этого хватило. Изучив исходники понял, что минимального прозрения не наступило, да и уровень полученной информации мал для того, чтобы решить поставленную задачу. Но закомство с этим материалом было явно полезным. Решение вопроса с использованием кубика (STM32Cube MX) мне лично импонирует больше, чем другие подходы, поскольку позволяет отвлечься от ряда низкоуровневых операций и генерация проекта всегда происходит в одном стиле. Соответственно, изучение этого примера показало, на какие файлы надо обратить внимание, где и что надо поменять или добавить, какие функции использовать для получения и отправки данных именно для нашей выбранной среды программирования.
Следующий поиск оказался весьма удачным. Хабр — известный сайт, на котором можно найти много полезного по разной электронной тематике. Нашлась там и статья STM32 и USB-HID — это просто. Я не являюсь постоянным клиентом Хабра и не знаю автора этой статьи RaJa, но на мой взгляд это очень хорошая статья, описывающая основные положения работы HID интерфейся. Без её прочтения читать дальше здесь бессмысленно, поскольку далее будут, в основном, комментарии для адаптации кода к среде разработки STM32IDE/STM32CubeMX + Atollic TrueStudio. (Далее STM32IDE). Да и столь популярный в 2014 году и реально очень неплохой проект EmBlocks, увы, умер.
Первое, что необходимо решить — как тестировать вновь создаваемое устройство. Лет… дцать назад я использовал для этого анализатор и синтезатор трафика USB — очень полезные, но дорогие игрушки 🙂 Сейчас у меня такой возможности нет, да и должен же быть более простой путь. Тем более для простого стандартного интерфейса без написания собственного драйвера. Авторы обоих рассмотренных выше проектов пошли самы простым для них путём — написание простой программы на известных им языках. Но автор статьи на Хабре сделал очень правильный шаг — он написал свой проект, совместимый с программой ST HID Demonstrator (ссылка есть в статье), позволяющей поуправлять нашим устройством, как графически, так и послать свои данные и посмотреть, что пришло от нашего устройства. Фактически программа может использоваться и в дальнейшем для отладки будущей программы на выбранном микроконтроллере.
Своё ознакомление с проектом для HID я осуществлял с платой STM32L476 Discovery. Плата, вообще говоря, может быть любой, где USB интерфейс микроконтроллера физически подключён к отдельному разъёму USB. Есть у меня и Nucleo 32 с STM32L4, но там один разъём USB тспользуется и для программирования/отладки, и для связи с хостом, что добавляет интриги в интерфейс и может служить источником дополнительных непоняток. Оно нам надо?
Итак, комментарии и дополнения к статье по привязке HID к STM32IDE примерно по тем же шагам, как и в хабровской статье.
Структура проекта
В STM32IDE структура всех проектов задаётся при генерации проекта из среды назначения функциональности пинов и пользователю о том заботиться не надо. В частности, в кубике (что отдельном STM32Cube MX, что в встроенном в STM32IDE) активируем USB, как Device, и добавляем Middleware USB Custom HID.
Рис.1 Выбор USB интерфейсаРис.2 Выбор и первичная настройка MiddlewareНадо заметить, что несмотря на установку размера буфера в 64 байта, эта величина не вносится по #define. Видимо баг текущей версии кубика. Далее покажем, где надо пофиксить. Указанный резмер дескриптора равный 79 — это значение для данного конретного стартового проектаЗаходим в Clock Configuration. Вполне вероятно, что могут быть проблемы с системными частотами, которые маркируются малиновым цветом.
Рис. 3 Возможные проблемы по установке частотЕсли так, нажимаем Resolve Clock Issues и, скорее всего, всё будет настроено на максимальные частоты. Главное — USB Clock будет выставлен на 48 МГц. Надо заметить, что в семействе STM32L4 генератор на 48МГц имеет автоподстройку по SOF (Start Of Frame), что позволяет создавать USB устройства без внешнего кварца/генератора. Если, конечно, остальной дизайн допускает использование некварцованных генераторов. Для других семейств не проверял, поскольку для моего текущего проекта был выбран именно L4. Только надо отметить, что при использовании USB есть некоторая минимальная частота работы микроконтроллера. Я делал прикидку для другого проекта, где надо общаться с хостом и при этом потреблять минимум тока. Задачи простые, не требуют большой скорости и я хотел запустить МК на 8МГц. Оказалось, что меньше 14МГц при подключении USB ставить не могу, RCC не позволяет. Пришлось остановиться на следующем круглом значении 16МГц.
Собственно, настройка аппаратной части USB и выбор файлов, отвечающих за базовую функциональность этого интерфейса на на этом закончены. Вся остальная периферия, находящаяся на выбранной плате настраивается автоматически при её выборе на старте проекта. Сохраняем, генерим проект и переходим к «программированию» в сравнении с описанным на Хабре проектом.
Это страшное слово Descriptor
Стандартные массивы данных для передачи информации хосту, с чем он будет иметь дело. Для интереса можно посмотреть дескрипторы устройства и конфигурации. Сейчас их можно оставить такими, как получились, но в дальнейшем они наверняка потребуют редактирования. Впрочем, не исключено, что они будут генериться по тем параметрам, что ставятся в кубике. Что не может не радовать. А вот Report Descriptor стоит изучить получше — это фактически основное, что придётся в дальнейшем править ручками. Не знаю, откуда RaJa взял его дескрипторы, в нашём случае они генерируются кубиком и располагаются в следующих файлах проекта:
Дескриптор от Raja | Дескриптор от ST | Файл в проекте |
RHID_DeviceDescriptor | USBD_FS_DeviceDesc | usbd_desc.![]() |
RHID_ConfigDescriptor | USBD_CUSTOM_HID_CfgFSDesc | usbd_customhid.c |
RHID_ReportDescriptor | CUSTOM_HID_ReportDesc_FS | usbd_custom_hid_if.c |
Поскольку для простоты сейчас будем работать только с ST HID Demonstrator, то не мудрствуя лукаво я просто скопировал содержимое RHID_ReportDescriptor в соответствующее место моего проекта. Только подставил свои константы на место длины. Надо отметить, что надо точно посчитать количество байтов в этом дескрипторе (в этом проекте 79) и убедиться, что именно это значение стоит в Class Parameters. Не больше и не меньше. Иначе хост не опознает подключённое устройство. Проверено 🙂
Далее заходим в файл usbd_customhid.h и меняем значения CUSTOM_HID_EPIN_SIZE и CUSTOM_HID_EPOUT_SIZE на 0x40U. Честно говоря, немного напрягает то, что ST не даёт альтернатив смене значения по умолчанию 2 на другое значение и далее в коде с использованием этих констант стоит комментарий, что не более 2х байт. Но, с другой стороны, это было рекомендовано в первом найденном описании и, вообще говоря, установка такого значения выглядит достаточно логично. Иначе в чём отличие CustomHID от обычного? Проблема в том, что при регенерации проекта из кубика, что на этапе первичного кода происходит довольно часто, это значение не сохраняется и его надо восстанавливать ручками. Для этого я себе в main вывел строку warning, чтобы не забывать проверить эти константы. Возможно я ошибаюсь, и в дальнейшем всё окажется проще. Но в такой конфигурации работает 🙂
Цикл обмена (пишем/читаем)
Для выдачи данных на хост всё достаточно аналогично описанию на Хабре. Только название функции другое: USBD_CUSTOM_HID_SendReport(). Все остальные реомендации из той статьи подходят по полной программе.
А вот чтение здесь интереснее, чем на Хабре. И на самом деле несколько проще. Обработка принятого массива происходит в usbd_custom_hid_if.c / static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state).
В этом тестовом проекте я не заморачивался с обработкой входных параметров и следуя своей обычной практике минимальности времени обработки прерываний, просто копирую полученные данные в заранее определённый массив и устанавливаю флаг готовности данных от USB
Ну, а собственно «сбор данных» (нажатие кнопок джойстика) и реакция на полученные от хоста данные в этом прото проекте делаю внутри бесконечного цикла в main.c Всё просто 🙂 В этом прото проекте нет разделения реакции на SET_FEATURE и SET_REPORT, с этим надо будет разобраться далее, в реальном проекте. Компилируем, запускаем, подключаем к хосту и там должен появиться новый CustomHID от STMicroelectronics.
Звпускаем на хосте USB HID Demonstrator. На плате, с которой я запускал этот проект, не имеет органов для работы с Variable Inputs/Outputs, поэтому в разделе Graphic customization были убраны соответствующие назначениями, оставлено 5 кнопок и назначены ID, определённые в проекте: 1, 2 для Output report (входные данные для ST) и 4 для Input Report (выход от ST).
Моей задачей для этого проекта было управлять парой светодиодов на плате, что стало работать сразу, как эта программа обнаружила подключенную плату, и включать «лампочки» этой платы при нажатии различных кнопок джойстика на плате, а вот здесь сразу не получилось. При указанных настройках все пять лампочек одновременно зажигались при нажатии на центр джойстика. Остальные кнопки не отображались. При этом, если перейти на Input/Otput transfer, то данные были вполне ожидаемы. Т.е. сам интерфейс работает, но отображение в программе на хосте не отвечает моим запросам. Слава богу ST предоставляетс исходники, а в соседнем кубике сидит программист нашей группы, пишущий в том числе и софт для компьютеров. В общем, он подправил одну функцию и сгенерил исполняемую программу. Всё стало работать, как хотелось. Конечно, можно было бы на каждую кнопку создать свой report с уникальным номером, что исходно и предусмотрено. В этом случае было бы достаточно посылать по одному байту для каждой кнопки, но мой проект предусматривает многобайтный отчёт. Исходник подправленной функции и подправленный исполняемый файл можно скачать по ссылке ниже.
На этом, пожалуй, всё. Если у Вас есть такая же плата 32L476GDISCOVERY, то для начала можно просто скачать мой прото проект, адаптированный для него демонстратор и исходник изменённой функции по этой ссылке. Исходный USB HID Demonstrator скачивается с сайта STM, инсталлируется и его исполняемый файл заменяется моим. Импортируете в STM32IDE мой проект, компилируете и должны получить работающую базу для своих проектов. Если у Вас другая плата, то адаптируете «сбор информации» и включение светодиодов под свою плату.
Для дальнейшей работы обязательно прочтите указанную статью RaJa с Хабра. Она даст понимание того, что и как должно быть сделано для других проектов с USB HID интерфейсом. А ещё лучше начать с неё 🙂
И при выборе класса устройства для Вашего проекта надо учитывать следующее: минимальный период опроса HID устройств — 1ms. И если я правильно помню, это скорее пожелание системе от внешнего устройства. В стандартном HID устройстве за один кадр (frame) передаётся только два байта, т.е. скорость обмена не более 2 кбайт/с. В Custom HID на
Full Speed (12 мбит/с) объём данных отчёта (report) — не более 64 байт, т.е. скорость обмена с Вашим HID не более 64 кбайт/с. Для High Speed (480 мбит/с) — максимальный объём данных 512 байт (512 кбайт/с). Не будь у меня ограничения совместимости с предыдущим софтом, используемым в компании, использовал хотя бы CDC.
У меня изучение статей и адаптация под мои хотелки заняло три дня. Описание заняло больше 🙂 Надеюсь, что у тех, кто воспользуется этой статьёй, аналогичный процесс займёт не более одного дня. Комментируйте, спрашивайте. Что смогу — отвечу. Что не смогу, вместе поищем решение.
Примеры работы с USB Device для STM32F4-Discovery / STM32 / Сообщество EasyElectronics.ru
Поскольку в нашем сообществе совсем мало статей про работу с STM32F4-Discovery, то я решил выложить несколько примеров работы с USB в STM32F4. Все примеры написаны в IAR.
По каким-то причинам ST не выложили документацию на работу с USB в контроллерах STM32F4. Сами библиотеки для работы с USB пришлось взять из примеров для Discovery. Насколько я понял позже, при работе с этими библиотеками можно использовать документацию UM1021 (библиотека USB для STM32F105/7 and STM32F2xx).
Все нижеописанные примеры, как мне кажется, достаточно хорошо показывают некоторые режимы работы USB в STM32F4-Discovery, и при этом к ней не требуется подключать какую-либо внешнюю периферию.
В примерах к Discovery работа в режиме «USB Device» показана в примере Demonstration (он прошивается в Discovery при изготовлении). Пример достаточно навороченный, USB в нем используется для эмуляции мыши в системе.
Разбираться с USB я начал именно с него. Для того, чтобы было проще разобраться в его работе, я выкинул из него часть кода, и оставил только код для работы в режиме «HID Mouse».
При включении производится инициализация периферии платы и USB, после чего весь код выполняется только в прерываниях. В данном случае все просто — в обработчике прерывания SysTick_Handler() опрашивается кнопка на плате, и если она нажата, то вызывается функция USBD_HID_SendReport, которая передает данные о перемещении курсора. Данные всегда одинаковы(константы), так что при нажатии кнопки на Discovery, курсор начинает ползти вверх.
Других примеров для работы в режиме «USB Device» к Discovery не прилагалось, не смотря на то, что в библиотеке USB были файлы для работы и в режиме CDC, и Audio Out.
mcu.cz/comment-n2848.html
mcu.cz/comment-n2800.html
Правда, описание там на чешском и используется там TrueSTUDIO, так что решил на базе найденного написать свои примеры, правда, код остался практически тот же.
Сначала «USB Custom HID». В примерах такой класс отсутствовал, и я взял его из чешского примера.
Принцип работы такой же, как и в примере от ST для «STM32F10x and STM32L1xx».
Посылая на контроллер репорт из одного байта, можно управлять светодиодом, соответствующему номеру репорта.
Обработка приема данных идет в файле «usbd_hid_core.c» в функции USBD_HID_DataOut.
При нажатии кнопки на Discovery происходит прерывание, на компьютер отправляется репорт из одного байта с описанием состояния кнопки.
Дальше захотелось реализовать режим CDC — эмуляция COM-порта. Разработчики из ST выложили класс для CDC, но примера для работы с ним не было. Все нужные исходники опять же есть у чехов, правда в их коде я нашел ошибки, делающие проект неработоспособным.
Так же у них при нажатии кнопки в виртуальный COM-порт просто передается символ «A», я пошел немного дальше, и прикрутил printf. При работе программы в виртуальный порт каждую секунду передается строка «Hello, World!».
При передаче символов S и A в порт с компьютера, на плате зажигается и гаснет один из светодиодов.
Для работы в данном режиме, на компьютер нужно установить драйвер от ST: Vitual COM Driver
Поскольку в примерах к Discovery был класс для работы в режиме «Audio Device», я решил сделать из Discovery внешнюю звуковую карту — работающую на воспроизведение. В интернете нечего похожего не нашел, однако уже готовый такой пример есть у ST в библиотеке USB для STM32F105/7 and STM32F2xx. Все исходники там мало отличались, вся разница в основном только в используемом драйвере внешнего звукового чипа CS43L22. Драйвер там достаточно навороченный, позволяет передавать звук на чип через I2S и DAC контроллера, данные могут передаваться по прерываниям от I2S и при помощи DMA.
После того как проект был скомпилирован и прошит, возникла проблема — звук воспроизводился, но качество было просто отвратительным. После того, как я подключил осциллограф и запустил на компьютере генератор синусоидальных сигналов, я обнаружил что форма сигнала на выходе аудио-чипа явно искажена — четверть всего времени воспроизведения сигнал отсутствовал. Позже, после отладки и написания другого проекта, предназначенного только для воспроизведения звука, я обнаружил, что подобные искажения появляются, если функцию воспроизведения звука вызывать через равные промежутки времени — например из прерывания таймера, причем период работы таймера может быть значительно больше времени воспроизведения звука. Аудиоданные при этом передавались через DMA в модуль I2S(этот режим используется в примере от ST). Судя по всему, проблема явно связана с какими-то особенностями аудио чипа.
Для того, чтобы получить более приличный звук, я использовал DAC контроллера(аудио чип работает усилителем), звук при этом стал более-менее сносным, но одноканальным(воспроизводится только левый канал). Получить стерео звук можно только в режиме I2S. Я попробовал передавать звук по прерываниям от I2S — и искажения пропали. Правда, при воспроизведении данные от USB могут приходить в момент, когда звук еще воспроизводится, и иногда, насколько я понял, часть звуковых данных попадает в другой канал. Проявляется это как тихие щелчки, слышно их только в том случае, если звук в каналах различается.
Из-за вышеуказанных проблем, мой драйвер отличается от того, что выложен в примерах от ST. В данный момент можно переключать метод воспроизведения — через I2S и через DAC. Это можно сделать, изменив строчку
«__IO uint32_t CurrAudioInterface = AUDIO_INTERFACE_I2S;» в файле аудиодрайвера «stm32f4_discovery_audio_codec.c»
на «__IO uint32_t CurrAudioInterface = AUDIO_INTERFACE_DAC;»
Исходные файлы:
www.dropbox.com/s/pr201jqkweubb2e/my_proj.zip?dl=0
STM32 как USB-устройство
В этой статье давайте создадим USB-устройство с использованием микроконтроллера STM32. USB — очень популярный способ связи, и мы почти каждый день используем такое устройство, которое работает с USB. Теперь давайте сделаем наше собственное устройство.
Отказ от ответственности: Электричество всегда опасно. Для работы с электричеством необходимы определенные навыки. Делайте работу на свой страх и риск. Автор не будет нести ответственность за любое неправильное использование или вредоносное действие или любую ошибку, которую вы сделаете. Содержание этого веб-сайта является уникальным и защищено авторским правом. Пожалуйста, не делайте никаких бессмысленных действий, копируя и заявляя, что это ваше. Большинство статей, опубликованных здесь, хранятся в открытом доступе, чтобы помочь вам. Берите знания бесплатно и пользуйтесь ими, но если вам интересно, вы можете купить готовые ресурсы, предлагаемые здесь. Если вам нужна помощь или руководство, не стесняйтесь комментировать ниже, автор постарается вам помочь. Также в статье могут быть аффилированные ссылки. Что никак не повлияет на вас в любом случае, но позволит автору с некоторой комиссией. Поэтому, пожалуйста, не принимайте это иначе. Спасибо.
Содержание
Рекламные объявления
USB-связь:
USB является наиболее популярным и повседневным коммуникационным протоколом среди всех протоколов. В то же время кабели связи легко найти. Вот почему этот протокол в основном практикуется. Существуют различные типы портов USB.
Чтобы узнать больше о USB, пожалуйста, посетите эту ссылку Wiki.
В любом случае, идем дальше. Здесь для STM мы будем использовать STM32CubeMx 9.Компилятор 0008. Соберите флешку ST_link для загрузки прошивки в MCU.
Часть конфигурации:
Откройте STM32CubeMx и создайте новый проект. Выберите микросхему, которую хотите использовать. Затем настройте ИС.
Сначала: Настройте RCC (кварцевый осциллятор). Выберите кристаллический/керамический резонатор
Настройка SYS. Выберите отладку по последовательному проводу, если хотите. (Необязательный).
Настройка USB из подключения: выберите устройство (FS).
Наконец, настройте USB_Device из промежуточного программного обеспечения. Выберите Класс устройства связи.
Теперь перейдите в настройки часов и настройте часы. Вы можете нажать кнопку «Решить проблему с часами», чтобы выполнить автоматический выбор.
После этого этапа сохраните консоль, указав имя для генерации кода с помощью STM32cubeMx. Затем. открыть проект.
Кодирующая часть:
Во-первых, вы можете поместить простой переключатель в цикл while. Не забудьте поместить это в раздел пользовательского кода.
Затем перейдите в usbd_cdc_if.c и поставьте вот такие буферы. Не забудьте объявить буфер вверху внутри пользовательской функции.
А теперь внутри CDC_Receive_FS() просто отредактируйте следующее изображение. И это сделано.
Все готово. Теперь создайте проект. Затем загрузите на целевой MCU.
Вы можете проверить другие мои статьи:
- Обнаружение USB-порта или устройств в Pi
- Отправка SMS с Raspberry Pi с помощью модуля GSM
- Подключение к Raspberry Pi со своего ноутбука/рабочего стола с помощью VNC Viewer
- Чтение канала ThingSpeak с помощью ESP8266 и Arduino
- Создание контроллера заряда солнечной батареи MPPT с синхронным понижающим преобразователем
Тестирование:
До тестирования:
В моем случае я страдал от драйвера USB в диспетчере устройств моего ПК. Попробуйте установить драйвера, если у вас не получилось с первой попытки.
В моем случае устройство сработало отлично. Я надеюсь, что это руководство поможет вам создать собственное USB-устройство с помощью STM32. Спасибо.
Для профессионального дизайна или помощи:
Чат в WhatsApp
Не забудьте подписаться на следующее обновление.
Также дайте мне знать, что вы хотите получить в качестве следующей статьи, комментарий ниже!
Нравится:
Нравится Загрузка…
Виртуальный COM-порт USB STM32 (VCP). Эта статья представляет собой руководство о том, как… | by Pasindu_Sandima
Эта статья представляет собой руководство по настройке периферийного USB-устройства микроконтроллеров STM32 в качестве виртуального COM-порта с использованием класса устройств связи USB.
Я использую плату STM32F4 Discovery с микроконтроллером STM32F407VG и встроенным портом micro USB. Я использую STM32 Cube Framework, библиотеки HAL и промежуточное ПО для USB-устройств для этого приложения
Сначала откройте STM32 CubeIDE, запустите новый проект STM32 и выберите нужный микроконтроллер. Здесь я выберу микроконтроллер STM32F407VG.
Выбор микроконтроллераЗатем в перспективе STM32 CubeMX включите HSE (высокоскоростной внешний) тактовый сигнал и выберите керамический/кристаллический резонатор (это зависит от вашей макетной платы. Если на вашей плате есть обходной источник тактового сигнала, выберите этот параметр) в Настройки RCC раздела Ядро системы.
Выбор источника тактового сигнала HSEЗатем выберите USB_OTG_FS в разделе подключения и выберите режим «Только устройство».
Выбор режима только USB-устройства Наконец, выберите USB_DEVICE в разделе промежуточного программного обеспечения и выберите класс для FS IP в качестве класса коммуникационного устройства (Virtual Port Com).
Затем сохраните файл CubeMX (.ioc), чтобы сгенерировать код. Теперь все периферийные устройства включены для связи USB через VCP. Но так как стек HAL USB занимает много памяти, необходимо изменить минимальный размер кучи. Это можно изменить, открыв файл сценария компоновщика STM32F407VGTX_FLASH.ld и изменив строку 59.до _Min_Heap_Size = 0x600;
.
Теперь, когда код сгенерирован, давайте создадим простую функцию эха, используя USB CDC. Сначала откройте файл usbd_cdc_if.c.
Иерархия файловПерейдите к функции CDC_Receive_FS и отредактируйте функцию следующим образом.
Теперь соберите проект и загрузите программу на устройство с помощью встроенного ST-Link. Затем соедините плату и ПК, используя порт micro-USB на другом конце платы.
источник ( визуальный gdb ) Откройте предпочтительный последовательный монитор (здесь я использую приложение Tera Term) и выберите COM-порт виртуального COM-порта ST-microelectronics с помощью диспетчера устройств в Windows. Теперь вы можете нажимать клавиши на терминале, и эти клавиши будут отображаться на устройстве.
Если COM-порт не обнаружен,
1. Установить драйвера виртуального COM-порта от ST.
2. Попробуйте переподключить USB-кабель и перезагрузить устройство.
Если у вас нет других последовательных мониторов, вы все равно можете использовать встроенный последовательный монитор Arduino IDE. Выберите порт в меню инструментов и откройте последовательный монитор. Введите сообщение в монитор последовательного порта и нажмите «Отправить». Затем устройство повторит введенное вами сообщение.
Чтобы управлять встроенным светодиодом с помощью виртуального COM-порта, сначала снова откройте файл CubeMX (.ioc), чтобы сгенерировать код для светодиода. В перспективе CubeMX выберите контакт для светодиода (это PD13 для оранжевого светодиода платы обнаружения F4) и установите его как GPIO_Output. Теперь сохраните файл, чтобы снова сгенерировать код.