# Компонент USB Virtual COM Port (DS_VirtualComPort) Готовый к интеграции программный компонент на базе официального стека **STMicroelectronics USB Device Middleware** (класс CDC — Communication Device Class). Репозиторий полностью оптимизирован: из него удалены все неиспользуемые USB-классы (Audio, HID, MSC), а файлы низкоуровневой конфигурации (`usbd_conf.c/.h`) и пользовательского интерфейса (`usbd_cdc_if.c/.h`) перенесены прямо внутрь компонента. Это позволяет разворачивать виртуальный COM-порт в проектах с любой архитектурой (HAL/LL) без CubeMX-генерации кода самого USB. ## 📌 Структура оптимизированного компонента ```text Library/DS_VirtualComPort/ ├── Class/ │ └── CDC/ │ ├── Inc/usbd_cdc.h, usbd_cdc_if.h │ └── Src/usbd_cdc.c, usbd_cdc_if.c # Интерфейс приема/передачи данных └── Core/ ├── Inc/usbd_core.h, usbd_conf.h ... └── Src/usbd_core.c, usbd_conf.c # Конфигурация аппаратного USB-драйвера ``` --- ## 🚀 Способ добавления в проект (Git Submodule) ### 1. Подключение подмодуля Выполните команду в корневом каталоге вашего проекта: ```bash git submodule add https://domstudent.ru Library/DS_VirtualComPort ``` ### 2. Автоматическое обновление сборки CMake Запустите PowerShell-скрипт автоматизации из вашей библиотеки утилит (`DS_UpdateCMakeList`): ```powershell cd tools/ ./UpdateCMakeList.ps1 ``` Скрипт автоматически найдет заголовочные файлы и исходный код (включая `usbd_cdc_if.c` и `usbd_conf.c`), после чего корректно пропишет их в конфигурацию вашего `CMakeLists.txt`. --- ## 🛠 Настройка тактирования (Clock Configuration) Для успешной работы USB требуется стабильная частота тактирования шины строго **48 MHz**. В микроконтроллерах с поддержкой безкварцевого USB (например, STM32F042 / STM32G4) это реализуется через внутренний осциллятор **HSI48**. Пример конфигурации тактирования через LL-драйверы: ```c void SystemClock_Config(void) { LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); LL_RCC_HSI48_Enable(); // Включаем внутренний генератор 48 МГц while(LL_RCC_HSI48_IsReady() != 1) {} // Ожидаем стабилизации LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI48); // Назначаем системным источником LL_SetSystemCoreClock(48000000); LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_HSI48); // Назначаем источником тактов USB } ``` --- ## 💻 Интеграция и пример использования в `main.c` Поскольку конфигурация скрыта внутри подмодуля, запуск USB-стека в пользовательском коде сводится к четырем последовательным вызовам функций в секции инициализации периферии. ```c #include "usbd_core.h" #include "usbd_cdc_if.h" /* Глобальные хэндлеры управления стеком */ USBD_HandleTypeDef hUsbDeviceFS; extern USBD_DescriptorsTypeDef Class_Desc; int main(void) { // Буфер сообщения (символ конца строки \n обязателен для терминалов) uint8_t TxMessageBuffer[] = "MY USB IS WORKING! \r\n"; HAL_Init(); SystemClock_Config(); // Инициализация ваших таймеров и портов ввода-вывода (MX_GPIO_Init, MX_TIM2_Init...) /* --- РУЧНОЙ ЗАПУСК СТЕКА USB VCP --- */ USBD_Init(&hUsbDeviceFS, &Class_Desc, DEVICE_FS); // Инициализация ядра USB USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC); // Регистрация класса CDC USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS); // Привязка функций интерфейса USBD_Start(&hUsbDeviceFS); // Физический старт USB-устройства while (1) { /* Отправка данных на ПК */ // Передаем указатель на буфер и его длину (исключая нуль-терминатор строки) CDC_Transmit_FS(TxMessageBuffer, sizeof(TxMessageBuffer) - 1); HAL_Delay(500); // Период отправки пакетов } } ``` --- ## 📋 Справочник API функций ### `uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)` Основная функция верхнего уровня для отправки массива данных на ПК. * **`Buf`**: Указатель на массив байт для отправки. * **`Len`**: Размер отправляемого пакета данных в байтах. * **Возвращаемое значение**: `USBD_OK` (0) при успешной постановке пакета в очередь отправки, или `USBD_BUSY` (1), если предыдущий пакет еще не успел улететь по шине.