STM32 и USB. Реализация USB Virtual COM Port.

Работа с USB

Доброго всем дня!

Сегодняшняя статья будет посвящена реализации виртуального COM-порта для микроконтроллеров STM32. Эта тема уже поднималась на нашем сайте (STM32 и USB), но в отличие от всех предыдущих экспериментов сегодня мы будем производить все настройки при помощи STM32CubeMx. Собственно, переходим к делу 🙂

Итак, начинаем с действий, ставших привычными! Создаем новый проект в STM32CubeMx, настраиваем его и выбираем микроконтроллер, для которого мы будем генерировать проект. Я буду использовать отладочную плату STM32F4-Discovery и, соответственно, контроллер STM32F407VG.

С этим никаких сложностей возникнуть не должно, все-таки мы уже много раз проделывали это в предыдущих статьях, посвященных STM32CubeMx (статьи про STM32CubeMx), поэтому давайте сформулируем задачу, которую мы будем сегодня решать.

А задача проста – реализуем поддержку USB Virtual Com Port и отправим тестовый набор данных с платы на ПК. Таким образом, мы должны добиться определения нашей отладочной платы в системе как виртуального COM-порта. А открыв этот порт в какой-нибудь терминальной программе мы должны будем увидеть правильно принятые данные. Перейдем к реализации задуманного!

Первым делом включим поддержку USB в нашем проекте в STM32CubeMx. Во вкладке Pinout ищем пункт USB_OTG_FS:

Использование USB в STM32CubeMx

Кроме того, задействуем внешний тактовый генератор (8 МГц), установленный на плате:

Настройка HSE.

Видим, что Cube отметил все занятые выводы микроконтроллера:

Настройка выводов контроллера для работы с USB Virtual COM Port.

Осталось выбрать режим работы USB для нашего устройства:

Настройка USB Virtual COM port.

На этом первый этап настроек проекта закончен, переходим в окно настроек тактирования (вкладка Clock Configuration). Здесь нам надо настроить использование внешнего генератора (8 МГц), а также все необходимые предделители частоты для всех шин микроконтроллера. Поскольку этому уже была посвящена целая статья (вот она), сейчас останавливаться на этом мы не будем и перейдем дальше 🙂 Приведу только финальные настройки тактирования:

Тактирование USB в STM32.

Двигаемся дальше и переходим на вкладку Configuration, где мы можем получить доступ к многочисленным настройкам непосредственно USB. Для начала заходим в настройки USB_FS, там нам нужно включить использование Vbus (вывод PA9 микроконтроллера):

Конфигурация USB OTG FS.

Здесь мы больше ничего пока менять не будем. Переходим к настройкам USB_DEVICE. В открывшемся окне мы видим идентификаторы VID и PID, используемые устройством, а также достаточно большое количество разных параметров USB. Не буду перечислять их все, их и так видно в окне Cube. Менять мы тут ничего не будем, хотя давайте просто ради тестирования зададим в качестве PRODUCT_STRING какое-нибудь наше название:

USB Virtual COM Port configuration.

В принципе на этом все, можно смело переходить к генерации проекта и исходного кода.

Немного подождав, пока Cube завершит генерацию, получаем проект для IAR’а, в котором выполнена вся необходимая инициализация. Давайте не будем вносить никаких изменений, а просто соберем проект и запрограммируем микроконтроллер. После этого подключаем USB-кабель к плате и в диспетчере устройств видим новое устройство:

Виртуальный COM-порт в Windows.

Если мы зайдем в свойства устройства, то можем увидеть там значения VID и PID, которые были установлены в настройках STM32CubeMx, а кроме того измененную нами строку PRODUCT_STRING:

USB Virtual COM Port на плате STM32F4Discovery.

Никаких сомнений в правильной работе сгенерированного проекта не остается 🙂 Но это только часть задачи, которую мы сами себе поставили. Нам нужно реализовать отправку данных. А необходимые для этого функции находятся в файле usbd_cdc_if.c:

  • CDC_Receive_FS() – для приема данных.
  • CDC_Transmit_FS() – для передачи данных.

Итак, давайте в основном цикле нашей программы будем раз в секунду отправлять 8 тестовых байт. Кстати для реализации временных задержек в HAL_Driver есть функция HAL_Delay(). В качестве аргумента мы должны передавать количество миллисекунд. В общем, получаем такой код:

int main(void)
{

	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration----------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* Configure the system clock */
	SystemClock_Config();

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_USB_DEVICE_Init();

	/* USER CODE BEGIN 2 */

	/* USER CODE END 2 */

	/* USER CODE BEGIN 3 */
	uint8_t testDataToSend[8];

	for (uint8_t i = 0; i < 8; i++)
	{
		testDataToSend[i] = i;
	}

	/* Infinite loop */
	while (1)
	{
		HAL_Delay(1000);
		CDC_Transmit_FS(testDataToSend, 8);
	}
	
	/* USER CODE END 3 */
}

Теперь остается только прошить контроллер, открыть терминал и убедиться, что данные принимаются верно. Так и поступим:

Реализация приема данных

Все работает отлично, как и планировалось!

Собственно, на этой мажорной ноте мы заканчиваем сегодняшнюю статью, а вместе с ней и обсуждение реализации USB Virtual COM Port при помощи STM32CubeMx. В следующих статьях мы будем работать уже с другими режимами работы USB, так что оставайтесь на связи!

Поделиться!

Подписаться
Уведомление о
guest
245 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
Ali
Ali
5 лет назад

Здравствуйте, каким вы терминалом пользуетесь?

vladk
vladk
Reply to  Aveal
2 лет назад

Попробовал эту программу – очень даже да, но!
Не смог найти где выбирать эмулируемый терминал – хотя бы VT102.

“терминал” без эмуляции терминалов – деньги на ветер.

elis
elis
5 лет назад

Спасибо за статью)

Roman
Roman
5 лет назад

Ну что за непруха. Опять (SD так и не заработала) не получается “USB составное устройство” с ошибкой. А могут мои проблемы быть связаны с особенностями компиляции работы ЮСБ и СД в Кейле 5? ктоньть пробовал на кейле?

віталік
віталік
5 лет назад

в мене після кількох рестартів мк запускався нормальний драйвер, а не композіт девайс

віталік
віталік
5 лет назад

щоб проект запрацював, треба у функції CDC_Transmit_FS змінну UserTxBufferFS змінити на Buf і плюс до того, якщо 64б віндовс, то у стартапі проекту змінити Stack_Size EQU 0x00004000 та Heap_Size EQU 0x00002000. А так все працює. Дякую.

stscat
stscat
Reply to  віталік
3 лет назад

Точно. Так и надо сделать. На 64 разрядной винде все заработало. Проект генерил в Keil 4.74

stscat
stscat
Reply to  stscat
3 лет назад

И еще в main.c добавить:
#include “usbd_cdc_if.h”

тогда не будет предупреждения
warning: #223-D: function «CDC_Transmit_FS» declared implicitly

Sergei
Sergei
5 лет назад

Вопрос: как узнать что данные можно читать с помощью CDC_Receive_FS , а то она судя по всему блокирует пока не примет всё а мне этого не нужно?

Pavel
Pavel
5 лет назад

Доброго времени суток! Спасибо за статью, очень полезно и интересно. Но есть у меня с данным примером проблема: отказ виртуального СОМ порта. Что я делаю не так, с чем это связано? Заранее спасибо!

Pavel
Pavel
5 лет назад

Я вот пробую. Не работает. Но дело не в кейле.

Сергей
Сергей
5 лет назад

всем здравствуйте. Нужна помощь с генерировал по статье код для MDK-ARM v5 stm32l152 выдает предупреждение
..\Src\main.c(97): warning: #223-D: function “CDC_Transmit_FS” declared implicitly
и зависает при отправке. кто сталкивался с такой проблемой уже второй день борюсь помогите пожалуйста

Pavel
Pavel
5 лет назад

Порт появляется в диспетчере, но он не работает. В свойствах указано: не удается запустить устройство (код 10). И при попытке обращение к этому порту, выдает ошибку, что такого порта нет.

Pavel
Pavel
Reply to  Aveal
4 лет назад

Keil v5, Dyscovery F407VGT

Alex Sh
Alex Sh
Reply to  Pavel
3 лет назад

В файле startup_stm32f407xx.s поменяй Stack_Size на 4000 вместо 400 и Heap_Size на 2000 вместо 200. Проблема исчезнет.

Адилет
Адилет
Reply to  Alex Sh
2 лет назад

Спасибо, хороший человек, ошибка исчезла

Игорь
Игорь
Reply to  Alex Sh
9 минут назад

А где именно и что именно использует так много места?
Что если я хочу принимать, например, 1 Мб данных?
Они точно не влезут все в кучу.
у меня есть внешняя SDRAM, она прекрасно работате и я хочу часть ее памяти зарезервировать под обработку USB пакетов, Но что-то никак не могу найти где же это используется..
Причем нигде толком не нашел объяснения.
Все только и пишут, что нужно объем стека и кучи увеличить..

Pavel
Pavel
5 лет назад

STM32F4-DISCOVERY c 407 контроллером. KEIL v5 и KEIL v4 пробовал.

niza93
niza93
5 лет назад

Был трабл с зависанием, теперь решился, благодаря
уроку отсюда
http://www.youtube.com/watch?v=enZqu2FV1eU
мб, кому-то поможет
работал на F103
но теперь другой трабл, при подкл./откл. от ПК никаких проблем нет, однако если во время подключения к ПК принять через ком порт данные и, закрыв соединение, отключить провод, то иногда при повторном подключении устройство улетает в HARDFAULT_handler из функции USBD_CDC_DeInit через функцию USBD_free(pdev->pClassData);
может, кто то сталкивался???

niza93
niza93
5 лет назад

сам решил проблему:
в файле usbd_conf надо закоментить 494 строку
//free(p); проблема сразу решилась и без плясок с бубном как на видео

Alex
Alex
5 лет назад

Большое СПАСИБО за статью. Есть проблема, драйвера ни в какую работать не хотят устройство видеться. Код ошибки 10. Если в CUBE поменять параметр USBD_MAX_NUM_CONFIGURATION на отличный от 1 код ошибки исчезает, однако данные через виртуальный ком порт не идут. При попытки отправить данные в ком порт есть ошибка превышения таймаута. Если можно по подробнее на счет настроек по точнее. Какие параметры выставить в cubemx чтобы виртуальный ком порт прочухался. Спасибо

Alex
Alex
5 лет назад

В качестве среды разработки используется for IAR Embedded Workbench for ARM version 7.40.2 попробовал с платами stm32f4discovery и stm32f429 discovery эффект один и тот же

Alex
Alex
5 лет назад

драйвера с сайта st пробовал под win_xp 32 Win 7 32 однотипно как в первом посте …. Подскажите куда копать … а то смотришь красиво начинаешь ковырять и вот…((((((((

Alex
Alex
5 лет назад

Спасибо за ссылки посмотрел повертел и результат никакой ((( … есть подозрение что с Н-ной версии CUBE MX стал страдать “прихрамыванием”…(

Alex
Alex
4 лет назад

Вопрос с драйвером решился для iar следующим образом : в настройках IAR увеличение размера “кучи” и стека

Альфис
Альфис
4 лет назад

Что за переменная lt в форе “for (uint8_t i = 0; i < 8; i++)”

Альфис
Альфис
4 лет назад

А видимо глюк в коде на сайте!

Ivan
Ivan
4 лет назад

У меня проблема решилась уменьшение максимального размера пакета с
512 до 64
#define CDC_DATA_HS_MAX_PACKET_SIZE 64

Max
Max
4 лет назад

Нужно поставить Heap_Size EQU 0×00004000 и будет счастье

Сергей
Сергей
4 лет назад

Отично! Все работает! Спасибо!

Паша
Паша
4 лет назад

Будет пример реализации в качестве Host-a?

Алексей
Алексей
4 лет назад

Спасибо за статью.
После прошивки МК с диспетчере пояляется Unknown Device. Ставил драйвера VCP_V1.3.1_Setup_x64. (http://www.st.com/web/en/catalog/tools/PF257938).
Подскажите где капать решение проблемы. И еще вопрос. Мне надо организовать мост USB – USART. Использую HAL драйвера и STM32_USB-FS-Device_Lib_V4.0.0. Может быть есть какой нить пример решения.

Алексей
Алексей
Reply to  Aveal
4 лет назад

Я извиняюсь. Прочитал многие Ваши статьи (спасибо за ваш труд), а ответ написал не в той)))
После генерации в кубе все работает, порт определяется, данные посылаются. Пробовал ваш проект из статьи Микроконтроллер STM32 и USB(https://microtechnics.ru/mikrokontroller-stm32-i-usb/). вот с этим проектом – неизвестное устройство. Хотел поэкспериментировать…. и никак. А по поводу моста – принцип понимаю, но есть вопросы. Если не ошибаюсь эти обработки надо писать в прерывании в файле stm32f3xx_it.c. Запутало то, что не могу понять где и как организовываются endPoint . Немного о проекте: по USB мне надо конфигурировать мое устройство (менять некоторые параметры). К устройству через usart подключен радио модем которые передает сигнал исполнительному устройству. Так вот через мост usb-usart надо настраивать модем( частоты , канал и тд.) В общем пока, что каша в голове, так как только вчера начал разбираться с USB. Ищу примеры что бы разобраться.

Алексей
Алексей
4 лет назад

После генерации в кубе система определяет STMicroelectrinics Virtual COM Port. Хочу , что бы определялось типа Мое устройство(COM10). Меняю VID PID и соответственно устройство не определяется. Как можно написать свои драйвера для своего устройства. Может есть какая нить инструкция.

Владимир Березин
Владимир Березин
4 лет назад

У меня на старенькой Windows XP такая же проблема. vcp-драйвер версии 1.4.0 от STMicroelectronix не помог.

Николай
Николай
4 лет назад

Спасибо автору за статью. Удалось разобраться с настройкой USB CDC. У меня осталось несколько неясных моментов. Особенно интересует как убедиться в готовности USB, прежде чем отправлять через него данные. У меня устройство работает автономно, передавая по USB данные измерений. Но подключено к компьютеру оно не всегда, периодически отключается. Так вот как мне в программе определить подключен ли USB или нет. Устройство перезапускать нельзя. Заранее спасибо 🙂

Николай
Николай
4 лет назад

Как вариант – можно попробовать, но тогда еще придется ставить задержку при появлении питания на ноге для инициализации USB, и нет гарантии что она пройдет успешно. В результате при попытке отправить данные, контроллер вываливается в HardFault_Handler(((. Должен же быть более цивилизованный способ. В библиотеке HAL не нашел функции, сообщающей о состоянии USB.

Павел
Павел
4 лет назад

Помогите! Может у кого было…? После сборки и загрузки проекта в KEILe подключаю USB, а определяется как 2 COM порта!? Это как? Я новичок прошу сильно не пинать!

Дмитрий
Дмитрий
4 лет назад

Спасибо за статью, всё заработало.

Но пока так и не нашёл, где менять настройки порта.
По умолчанию стоит 9600, и где менять – непонятно.
Смотрел Line_Coding, но там мало материала.

Boris
4 лет назад

Если настроить тактирование как у автора проблем не должно быть .Это я об ошибке 10(помогает CDC_DATA_HS_MAX_PACKET_SIZE 256). Следующая ошибка 28 относится к установке драйверов.Проблема в том что никто не читает инструкцию по установке драйвера .Одним запуском еxe из архива дело не обходится он драйвера не устанавливает , а распаковывает в STMicroelectronics/…читаем файл readme.txt и делаем все как написано.

Pavel
Pavel
4 лет назад

У меня как-раз таки виртуальный ком-порт не появляется в системе

Ефим
Ефим
4 лет назад

контроллер STM32F103C8T6 в системе определяется как ункновн девайс может кто подскажет, кто сталкивался (тестером кабель и от МК до порта все проверил) МК не выдает VIP и PID в чем проблема 🙁

Efim
Efim
4 лет назад

Ув. Aveal настройки дефоултовые от кварца на 8М, частота на USB 48M куда еще смотреть?

Ефим
Ефим
4 лет назад

Ув. Aveal от внутреннего не хочет, куб ругается

Ефим
Ефим
4 лет назад

Ув. Aveal у меня контроллер STM32F103C8T6 кварц на 8Мгц в RCC ставлю внешний кварц, автоматом частота 48 Мгц, но могу и 72 (максимальная) поставить (могу скрины кинуть ), а от внутреннего пишет USB работать не будет

Ефим
Ефим
4 лет назад

Ув. Aveal готовая отладочная маде ин наши ускоглазые соседи https://detail.tmall.com/item.htm?spm=a230r.1.14.97.d3erSV&id=522586249180&ns=1&abbucket=9

Ефим
Ефим
4 лет назад

1. на счет тактирования куб сам ставит, что надо
2. так хоть бы vip и PID было видно, а то просто ункновн
3. есть такой вариант, т.к. я так понимаю еще правят в нем ошибки
а может просто где галки не хватает

Ефим
Ефим
4 лет назад

Ув. Aveal
вот схема тактирования, которая сейчас с USB
http://s019.radikal.ru/i604/1603/d8/a200093d101b.jpg

с таймером брал значение частоты на APB1 Timer Cloсks там было 36, но результат был как будто значение было другим

Ефим
Ефим
4 лет назад

Прихожу к выводу, что куб генерирует некорректный код. проделал опыт с таймером и указал частоту 8МГц и значения 8000 и 499 соответственно, все ок. Потом добавил USB настройки частот как на фото выше, т.е. на таймере должно быть 48МГц, выставляю значения 48000 и 499 и получаю 6 секунд.
при частоте 72Мгц поставил 36000 и 499 и так же 6 секунд. хотя должно быть 2. В общем или я что не понимаю, или куб врет

Dmitry
4 лет назад

Добрый вечер. Попала в руки плата STM32F429I-DISCO. Решил освоить периферию и наконец перейти на STM32CubeMX(Так сказать убить двух зайцев сразу). Но вот незадача, решил начать с USB (VIrtual Com Port). Настраиваю USB_OTG_FS, RCC, USB Device как Virtual com port. Генерю код и ничего не изменяю загружаю прошивку. Просто хочу проверить связь с устройством, но не тут то было. Комп отказывается искать устройство вообще! То есть не всплывает даже “Неопознанное устройство”. Вообще 0 эффекта. Не могу понять, что за грабли на которые я наткнулся.

Dmitry
Reply to  Aveal
4 лет назад

Настройка PinOut
Настройка Clock (на всякий случай)
https://dropmefiles.com/qg3VM

Ефим
Ефим
4 лет назад

Ув. Aveal отправил вам на почту с контактов в архиве проект для воркбенха и репорт из куба

Dmitry
4 лет назад

Странно. И правда пины РВ13, РВ14 и РВ15. А куб генерит под другие для этого микроконтроллера.

Dmitry
Reply to  Aveal
4 лет назад

А можно как нибудь в кубе изменить пины?или только самому в коде?

Dmitry
Reply to  Aveal
4 лет назад

Не помогло(((

Dmitry
Reply to  Aveal
4 лет назад

https://dropmefiles.com/JRbsK
Вот…кубовский

Dmitry
Reply to  Aveal
4 лет назад

Большое спасибо)Наконец то плата определилась)

Efim
Efim
4 лет назад

Схемы нет, но она простая как два пальца. ЮСБ идут точно от нужных ног прозвонил, кварц на 8 так же на месте
на выходных еще раз проделаю, мог промазать в кубе, но как я понимаю у этих чипов только разное кол во оперативки и пзу, хотя перепроверю

Ефим
Ефим
4 лет назад

от внутреннего кварца таймер работает хорошо , USB проверить не могу, т.к. не позволяет, а вот только как вместо встроенного кварца выбираешь внешний, частота увеличивается (точнее снижается) в 6 раз. вместо герца 1 в 6 секунд

Ефим
Ефим
4 лет назад

http://s020.radikal.ru/i703/1603/2c/9e1b673b270e.jpg ругается в системе тактирования

Ефим
Ефим
4 лет назад

Ув. Aveal замена кварца решила проблему 🙂 (ремонт обошелся в 36р) первый раз с таким сталкиваюсь, а так значит делал все правильно

Ефим
Ефим
4 лет назад

Если честно заказывал очень много чего, за все время, только второй раз вылез косяк, но тут чисто брак кварца (это как брак процессора 1-2 на 1000 штук), а так спасибо за помощь

Павел
Павел
4 лет назад

Как понять подключен хост (ПК) или нет?
У меня если шнурок выдернут то при попытке CDC_Transmit_FS контроллер уходит HardDefault. В usbd_cdc_if.h и usbd_cdc_if.с ничего подобного не увидел.
Хотелось бы понять, когда делать CDC_Transmit_FS а когда нет.

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Июнь 2020
Пн Вт Ср Чт Пт Сб Вс
« Май    
1234567
891011121314
15161718192021
22232425262728
2930  

© 2013-2020 MicroTechnics.ru