Для работы с виртуальным COM-портом на микроконтроллерах семейства ST потребуется активировать соответствующий режим в HAL. В CubeMX выберите Device Mode → Communication Device Class, затем включите VCP в настройках промежуточного слоя.
Библиотека HAL автоматически генерирует шаблон кода, но требует ручной доработки. Проверьте обработчики прерываний CDC_Receive_FS и CDC_Transmit_FS – данные должны копироваться в буфер без задержек. Для буферизации используйте кольцевые структуры размером не менее 512 байт.
Скорость обмена зависит от конфигурации дескрипторов. В файле usbd_cdc.h измените параметр CDC_DATA_FS_MAX_PACKET_SIZE на 64 байта. Если требуется высокая пропускная способность, добавьте поддержку пакетных транзакций через USB_OTG_FS.
Ошибки часто возникают из-за некорректных дескрипторов. Убедитесь, что в usbd_desc.c указаны верные значения для idVendor и idProduct. Для отладки подключите логи анализатора протокола – например, Wireshark с фильтром usb.transfer_type == 3.
Подключение виртуального COM-порта к микроконтроллеру
Инициализация периферии
Активируйте тактирование интерфейса в регистре RCC: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE)
. Для работы с буферами выделите 512 байт ОЗУ, выровненные по границе 32 бита. Настройте прерывания с приоритетом не ниже 2.
Конфигурация дескрипторов
Измените массив USB_DeviceDescriptor
, указав VID/PID производителя. В структуре USBD_CDC_ItfTypeDef
пропишите callback-функции: Init
, DeInit
, Control
, Receive
. Для скорости передачи 115200 бод задайте параметры в LineCoding
: 8 бит данных, 1 стоп-бит, без контроля чётности.
Пример обработки входящих данных:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t Len) {
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, Buf);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
HAL_UART_Transmit(&huart1, Buf, Len, 100);
return USBD_OK;
}
Подготовка проекта в STM32CubeIDE для работы с USB CDC
Создайте новый проект в STM32CubeIDE, выбрав микроконтроллер с поддержкой интерфейса для связи через последовательный порт. Например, для серии F4 активируйте модуль USB_OTG_FS в режиме Device_Only.
Конфигурация аппаратного стека
В разделе Middleware включите опцию Communication Device Class. Установите параметры:
- Max Packet Size: 64 байта для Full Speed
- Product String: задайте уникальное имя устройства
- VID/PID: используйте стандартные значения или зарегистрированные идентификаторы
Генерация кода и настройка прерываний
После генерации кода проверьте файл usbd_conf.c. Убедитесь, что обработчики прерываний корректно подключены. Для передачи данных добавьте вызовы:
CDC_Transmit_FS(buffer, length);
Включите обработку событий в главном цикле, используя HAL_PCD_IRQHandler.
Работа с дескрипторами и передача данных через виртуальный COM-порт
Для корректного взаимодействия с хостом требуется правильно заполнить дескрипторы. В структуре USBD_DescriptorsTypeDef укажите класс 0x02 (CDC) и подкласс 0x02 (Abstract Control Model). В конфигурационном дескрипторе задайте две конечные точки: одна для управления (0x81), другая для передачи данных (0x82). Размер пакета – 64 байта для Full Speed.
Пример дескриптора интерфейса:
0x09, // Длина дескриптора
0x04, // Тип: интерфейс
0x00, // Номер интерфейса
0x00, // Альтернативная настройка
0x02, // Количество конечных точек
0x02, // Класс: Communications
0x02, // Подкласс: ACM
0x01, // Протокол: AT-команды
0x00 // Индекс строки
Для обработки входящих данных используйте коллбэк CDC_Receive_FS. Буфер должен быть выровнен по 4 байта и иметь размер, кратный максимальному пакету. После успешного приема отправьте подтверждение:
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
При передаче проверяйте флаг TxState. Если линия занята, дождитесь освобождения или реализуйте очередь. Для отправки данных вызовите CDC_Transmit_FS с указанием длины пакета. Максимальная длина одной передачи – 512 байт для Full Speed.
Ошибки таймаута часто возникают при неправильной настройке скорости порта на хосте. Убедитесь, что параметры (115200 8N1) совпадают с заданными в коде.