Микроконтроллер NXP LPC с прошивкой USB-CDC определяется в системе как виртуальный COM-порт (VCOM), и именно сбой на этом этапе — устройство появляется в диспетчере как «Unknown Device» или порт не открывается терминалом — чаще всего останавливает отладку проекта. Проблема почти всегда лежит в одной из трёх областей: дескрипторы USB в прошивке, драйвер на стороне ПК или физическое подключение линий D+/D−.
В этой статье разберём, как работает USB VCOM на чипах семейства LPC (LPC11Uxx, LPC17xx, LPC54xxx и других), какие инструменты NXP предоставляет для реализации CDC-интерфейса, как проверить корректность определения порта в Windows и Linux и что делать, если порт появляется, но данные не передаются.
Что такое VCOM и как он реализован в LPC
VCOM (Virtual COM Port) — это программная эмуляция последовательного порта поверх интерфейса USB. Микроконтроллер регистрируется в операционной системе как устройство класса CDC (Communications Device Class), и ОС создаёт для него стандартный COM-порт, с которым можно работать через любой терминал — PuTTY, Tera Term, minicom.
Преимущество подхода в том, что не требуется отдельный преобразователь USB-UART наподобие FTDI или CH340: чип LPC с аппаратным USB-контроллером сам выполняет эту роль. Скорость обмена при этом не ограничена классическими значениями UART вроде 115200 — реальная пропускная способность определяется USB Full Speed (до 12 Мбит/с) или High Speed, если контроллер его поддерживает.
Со стороны прошивки VCOM реализуется через стек USB-устройства. Для LPC доступны два основных варианта:
- 📦 USB Device Stack в составе MCUXpresso SDK — актуальный вариант для современных семейств, включает пример usb_device_cdc_vcom.
- 📚 Библиотека LPCOpen / usbd_rom — для старших серий LPC11Uxx и LPC17xx, где часть USB-стека зашита в ROM чипа.
- 🔧 Сторонние стеки (например, TinyUSB) — популярны в open-source проектах и поддерживают ряд чипов NXP.
Аппаратные требования и распиновка
Для работы USB-интерфейса микроконтроллеру необходимы корректно подключённые линии D+ и D−, а также стабильное тактирование USB-блока. На многих семействах LPC тактовый сигнал USB формируется из внешнего кварца через PLL — если частота кварца на плате отличается от той, что задана в конфигурации проекта, USB работать не будет вообще, причём без каких-либо явных ошибок в коде.
Обратите внимание на питание линий данных. На части микросхем предусмотрен отдельный вывод питания USB-подсистемы — если он не запитан согласно даташиту конкретной модели, периферия физически не выйдет на связь. Точную схему подключения нужно сверять с reference manual именно вашей модели: распиновка и требования к питанию различаются между семействами.
⚠️ Внимание: на некоторых отладочных платах USB-разъём подключён к отладчику (например, Link2/LPC-Link2), а не к целевому микроконтроллеру. Перед поиском ошибки в прошивке убедитесь по схеме платы, что кабель подключён именно к USB-порту целевого LPC.
При разводке собственной платы держите линии D+ и D− короткими, одинаковой длины и без переходных отверстий рядом с разъёмом — это снижает риск проблем с целостностью сигнала ещё до этапа прошивки.
Запуск примера VCOM из MCUXpresso SDK
Самый быстрый способ получить рабочий VCOM — собрать готовый пример. В MCUXpresso IDE для поддерживаемых плат доступен демонстрационный проект usb_device_cdc_vcom (на некоторых платах — вариант usb_device_cdc_vcom_lite). Он реализует echo-сервер: всё, что вы отправляете в порт, возвращается обратно.
Порядок действий в общем виде выглядит так:
- ⬇️ Скачайте SDK для вашей платы или чипа с портала MCUXpresso и импортируйте его в IDE.
- 📂 Импортируйте пример из раздела USB-примеров SDK.
- 🔨 Соберите проект и прошейте плату через отладчик.
- 🔌 Подключите USB-кабель к порту целевого микроконтроллера и проверьте появление нового COM-порта в системе.
☑️ Проверка перед запуском VCOM
После прошивки откройте терминал на появившемся порту. Скорость в настройках терминала для CDC не критична — параметры передаются формально и не влияют на фактический обмен по USB. Если символы, которые вы вводите, возвращаются обратно, VCOM работает корректно.
Драйверы в Windows и Linux
В современных версиях Windows (начиная с Windows 10) для CDC-устройств используется встроенный драйвер usbser.sys, и отдельная установка обычно не требуется. В старших версиях системы для устройств NXP мог понадобиться INF-файл, который «привязывает» VID/PID устройства к стандартному драйверу. Если устройство определяется с ошибкой, проверьте в диспетчере устройств, какой VID/PID оно сообщает, и совпадает ли он с тем, что задан в дескрипторах прошивки.
В Linux CDC-устройства обычно подхватываются модулем cdc_acm автоматически и появляются как /dev/ttyACM0 (или с другим номером). Проверить события подключения можно командой:
dmesg | tail -20
Если в выводе видны строки о регистрации cdc_acm и создании ttyACM-устройства, со стороны ОС всё в порядке. Если устройство определяется, но открыть порт не удаётся, проверьте права доступа — пользователь должен входить в группу, которой принадлежит устройство (часто это dialout).
| Симптом | Вероятная причина | Что проверить |
|---|---|---|
| Устройство не определяется вообще | Нет тактирования USB, неверная частота кварца в проекте | Конфигурацию clock, схему платы |
| «Unknown Device» в Windows | Ошибка в дескрипторах, проблема с линиями D+/D− | Дескрипторы в коде, целостность кабеля и разводку |
| Порт есть, данных нет | Не вызывается задача стека USB, неверные endpoint'ы | Цикл обработки USB-задач в main |
| Порт открывается и сразу закрывается | Конфликт с другой программой, держащей порт | Закрыть терминалы и мониторы порта |
| Определяется только после сброса | Некорректная инициализация USB при старте | Порядок инициализации в коде |
⚠️ Внимание: «зарядочные» USB-кабели без линий данных — частая причина того, что устройство вообще не появляется в системе. Прежде чем искать ошибку в прошивке, проверьте тот же порт заведомо рабочим кабелем.
Если LPC не определяется как VCOM, начинайте диагностику с тактирования USB и кабеля — эти две причины покрывают большинство случаев «невидимого» устройства.
Типичные ошибки в прошивке
Когда порт определяется, но обмен не идёт, причина почти всегда в коде приложения. Одна из распространённых ситуаций: стек USB требует периодического вызова своей задачи обработки, а в main этот вызов отсутствует или заблокирован длительной операцией. В результате устройство успешно энумерируется, но не отвечает на передачу данных.
Вторая группа ошибок связана с конфигурацией endpoint'ов и буферов. Несоответствие размеров буферов в дескрипторах и в коде приёма/передачи приводит к обрывам данных или зависанию обмена. Здесь помогает сравнение с эталонным примером из SDK: если пример работает, а ваш проект нет, ищите отличия в конфигурационных файлах USB.
Как отличить проблему прошивки от проблемы ПК
Прошейте плату готовым примером usb_device_cdc_vcom из SDK без изменений. Если пример работает на том же ПК и кабеле — проблема в вашем коде. Если пример тоже не определяется, проверяйте кабель, порт, драйверы и тактирование. Это самый быстрый способ локализовать неисправность.
Полезно также помнить про ограничение буферов приёма: если хост отправляет данные быстрее, чем приложение их забирает, часть байт теряется без каких-либо сообщений об ошибке. Для потоковой передачи предусматривайте в приложении кольцевой буфер достаточного размера и обрабатывайте приём по прерываниям или событиям стека.
Отладка обмена данными
Для проверки обмена удобно использовать два направления диагностики. Со стороны ПК — терминал с логированием: отправьте известную последовательность байт и сравните с тем, что вернулось. Со стороны микроконтроллера — отладочный вывод через SWD или отдельный UART, если он есть на плате: так видно, доходят ли данные до приложения.
Если нужно анализировать USB-трафик на уровне пакетов, на Linux применяется usbmon в связке с Wireshark. Это продвинутый инструмент, который помогает увидеть, на каком этапе энумерации или обмена происходит сбой. На практике до такого уровня доходит редко — чаще достаточно сравнения с рабочим примером.
Зафиксируйте в прошивке собственные VID/PID и строковые дескрипторы производителя — так устройство будет легко отличать в диспетчере устройств от других VCOM-устройств на том же ПК.
FAQ: частые вопросы по LPC USB VCOM
Нужен ли отдельный драйвер для LPC VCOM в Windows 10/11?
Как правило, нет: CDC-устройства обслуживаются встроенным драйвером usbser.sys. Отдельный INF-файл может понадобиться только для старых версий Windows или нестандартных конфигураций дескрипторов.
Почему порт появляется в системе, но терминал показывает пустоту?
Проверьте, что в прошивке регулярно вызывается задача обработки USB-стека и что данные реально отправляются приложением. Также убедитесь, что порт не занят другой программой — одновременно его может держать только один процесс.
Можно ли использовать VCOM одновременно с отладкой по SWD?
Да, это независимые интерфейсы. Отладка через SWD/J-Link и обмен через USB VCOM могут работать параллельно, что удобно: логи идут в терминал, а пошаговая отладка — в IDE.
Чем VCOM отличается от преобразователя USB-UART на FTDI?
Функционально для пользователя ПК — почти ничем: и там, и там создаётся COM-порт. Разница в том, что VCOM реализуется самим микроконтроллером LPC без дополнительной микросхемы, а скорость обмена не привязана к классическим значениям baud rate.
Устройство определяется только после нажатия Reset. В чём дело?
Это указывает на проблему инициализации USB при старте прошивки: например, тактирование включается позже, чем начинается энумерация. Проверьте порядок инициализации в коде и сравните с примером из SDK. Точная причина зависит от семейства чипа и конфигурации проекта.