Здравствуйте,
Я отлаживаю периодическую проблему с USB CDC на плате STM32F103C8T6. После выхода из режима останова компьютер иногда теряет виртуальный последовательный порт (устройство не повторно определяется без аппаратного сброса). Надеюсь, что сообщество поможет проверить правильность моей последовательности инициализации тактовых сигналов/USB и предложить проверенное решение.
Аппаратные средства и компоненты
- МК: STM32F103C8T6, работает на 72 МГц (HSE 8 МГц с умножением на 9 через PLL).
- Плата: тип “Blue Pill” («Маленькая синяя плата»); LDO преобразует 5 В в 3.3 В, декуплирующие конденсаторы 0.1 мкФ + 1 мкФ рядом с выводом VDD, кварцевый резонатор HC-49 8 МГц с конденсаторами нагрузки 22 пФ.
- USB: устройство полной скорости, вывод D+ подтянут к 3.3 В через резистор 1.5 кОм; последовательные резисторы 22 Ом на линиях D+/D-.
Симптомы неисправности
- При первом включении: USB CDC нормально определяется в Windows 10 и Ubuntu 22.
- После выхода из режима останова через 5-30 секунд устройство иногда не определяется хостом (нет событий новых PID/VID, последовательный порт исчезает). Переподключение USB не всегда помогает, аппаратный сброс через NRST всегда восстанавливает работу. Вероятность воспроизведения: ~10%-30%.
Пробованные методы
- После выхода из останова повторно включать HSE/PLL и перезапускать тактирование USB.
- Переключать тактирование USB и выполнять последовательность USBD_DeInit() → USBD_Init().
- Убедиться в вызове функции SystemCoreClockUpdate() после переключения тактирования.
- Добавить задержку 1-10 мс между инициализацией RCC и USB.
- Измерить пульсации питания 3.3 В с помощью осциллографа: пульсации при выходе из останова <20 мВpp; напряжение на D+ в состоянии покоя ~3.3 В.
Последовательность настройки тактирования/RCC (библиотека HAL)
// После выхода из останова: повторно включить HSE/PLL и переключить SYSCLK на PLL
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_RCC_OscConfig(&RCC_OscInitTypeDef){
.OscillatorType = RCC_OSCILLATORTYPE_HSE,
.HSEState = RCC_HSE_ON,
.PLL.PLLState = RCC_PLL_ON,
.PLL.PLLSource = RCC_PLLSOURCE_HSE,
.PLL.PLLMUL = RCC_PLL_MUL9
});
HAL_RCC_ClockConfig(&RCC_ClkInitTypeDef){
.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2,
.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,
.AHBCLKDivider = RCC_SYSCLK_DIV1,
.APB1CLKDivider = RCC_HCLK_DIV2,
.APB2CLKDivider = RCC_HCLK_DIV1
}, FLASH_LATENCY_2);
SystemCoreClockUpdate();
Фрагмент кода повторной инициализации USB
// Полный перезапуск стека USB после стабилизации тактирования
USBD_DeInit(&hUsbDeviceFS);
__HAL_RCC_USB_FORCE_RESET();
HAL_Delay(2);
__HAL_RCC_USB_RELEASE_RESET();
__HAL_RCC_USB_CLK_ENABLE();
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
USBD_Start(&hUsbDeviceFS);
Наблюдения
- Если не использовать режим останова, а только переключаться между режимами работы/ожидания, система стабильна.
- При удержании SYSCLK на HSI после выхода из останова (без включения PLL) система кажется стабильнее, но мне нужен 72 МГц для соблюдения временных характеристик.
- Кратковременное (10 мс) принудительное снижение D+ через GPIO (эмуляция отключения) повышает вероятность восстановления, но не гарантирует 100% успеха.
Вопросы
- Для чипа F103: существует ли стандартная последовательность включения/временные параметры после выхода из останова (HSE→PLL→USBFS), чтобы избежать неисправностей CDC?
- Является ли принудительное “программное отключение” USB (снижение D+) лучшей практикой для серии F1 или есть более надежный метод сброса на уровне стека?
- Есть ли известные ошибки кремния, связанные с влиянием запуска HSE/PLL на USB SOF (сигнал синхронизации кадров) или домен 48 МГц после выхода из останова?
- Рекомендуется ли при восстановлении USB-тактирования сначала использовать HSI, а затем переключаться на PLL, или всегда приоритетно стабилизировать PLL?
- Столкнулись ли вы с подобными аппаратными проблемами: допуск резистора D+, утечка через ESD-диоды, перегрузка кварцевого резонатора, плохая переходная характеристика ЛДО и т.д.?