Как подключить stm32 к компьютеру

Обновлено: 04.07.2024

На сегодняшний день, даже самые дешевые МК имеют в себе аппаратный usb и в тоже время этот интерфейс является стандартом для подключения периферийных устройств к ПК. Это понимание пришло ко мне не сегодня, но usb достаточно сложен и я долгое время не знал как к нему подойти.

Проблема в том, что за счет того, что обмен идет непрерывно на большой скорости, привычным способом, устанавливая breakpoint, его отлаживать не получиться. Да и сам процесс обмена достаточно сложен и желательно перед глазами иметь картинку для лучшего понимания происходящего.
Оказалось, что китайский salea logic решает эти проблемы, он записывает обмен данными между устройством и компом декодируя при этом посылки.

Про физическую часть скажу всего пару слов, сигнал передается по дифференциальной паре, что помогает достигать высоких скоростей. В зависимости от того, какая из двух линий притянута к питанию устройство будет работать как HS или FS.

Картинка ниже очень наглядно показывает, как программно реализован usb.

STM32 USB НАЧАЛО.

Из нее понятно, что после того как мы подключили устройство обмен данными происходит с помощью конечных точек.

Конечную точку можно представить себе как почтовый ящик, почтальон знает, что в него надо кидать письма, а Вы знаете, что из него можно забирать письма. В случае с usb почтовым ящиком является конечная точка.

Очень важный момент работы usb, что общение всегда инициирует хост, а устройство может лишь отвечать на запросы, которые отправил хост. Давайте создадим нулевую конечную точку, которая предназначена для обмена служебной информацией.

  • Устройство подтягивает к питанию одну из линий передачи данных , таким образом хост узнает о его подключении.
  • Host подает сигнал сброса в шину. Для устройства это значит, что хост собирается с ним общаться и необходимо создать конечную точку.

Давайте оформим это в виде кода.

Тут может возникнуть вопрос, что такое таблица конечных точек?
Так как посылки у usb могут быть разной длины и большого размера, разработчики МК не стали делать для получаемых/принимаемых данных отдельный регистр, для каждой конечной точки. Они выделили для этой цели кусок памяти. А для того, чтобы МК понимал, где заканчивается одна точка и начинается другая, в начале этой памяти расположена таблица.

Создаем конечную точку.

  • Host шлет запрос GET_STATUS. Это своеобразное приветствие, чтобы понять, что конечная точка настроена, устройство понимает хост и дальнейшее общение имеет смысл. Он ожидает от устройства статус default state.
  • Host шлет запрос GET_DESCRIPTOR для получения основной информации о устройстве, в том числе максимальном размере пакета для нулевой конечной точки.

Что касается дескриптора устройства, оставлю тут табличку в которой расписано назначение каждого байта.

STM32 USB НАЧАЛО.

Тут начинается самое интересное, для начала расширим код нашего прерывания, для случая когда МК успешно принял данные.

Теперь добавим, функции записи и чтения конечных точек.

У этой статьи обязательно будет продолжение, но пока выложу её в том виде, что есть.


На дворе 2014 год, а для связи микроконтроллеров с ПК самым популярным средством является обычный последовательный порт. С ним легко начать работать, он до примитивности прост в понимании — просто поток байт.
Однако все современные стандарты исключили COM порт из состава ПК и приходится использовать USB-UART переходники, чтобы получить доступ к своему проекту на МК. Не всегда он есть под рукой. Не всегда такой переходник работает стабильно из-за проблем с драйверами. Есть и другие недостатки.
Но каждый раз, когда заходит разговор о том, применять USB или последовательный порт, находится множество поклонников логической простоты UART. И у них есть на то основания. Однако, хорошо ведь иметь альтернативу?

Меня давно просили рассказать как организовать пакетный обмен данными между ПК и МК на примере STM32F103. Я дам готовый рабочий проект и расскажу как его адаптировать для своих нужд. А уж вы сами решите — нужно оно вам или нет.

Выбор профиля HID

USB-HID — довольно обширный класс устройств, поэтому прежде всего придется выбрать какое именно устройство мы будем создавать.
Мы можем создать эмуляцию клавиатуры, мыши, джойстика и других устройств ввода, а можем создать свое устройство, чтобы не зависеть от довольно жестких рамок стандарта и свободно обмениваться данными с ПК.
Я расскажу как cделать Custom HID device. Это дает максимальную свободу. Чтобы не затягивать статью, постараюсь рассказать максимально кратко — описаний стандарта в сети и без меня много, но лично мне они слабо помогли, когда понадобилось решить конкретную задачу.

Структура проекта

  • Папка USB-FS с библиотекой «STM32F10x, STM32L1xx and STM32F3xx USB-FS-Device Driver» версии 4.0.0.
  • В папках Inc и Src файлы:
    platform_config.h — здесь собраны определения, касающиеся конкретной платы и семейства МК
    stm32_it.h, stm32_it.c — здесь определены обработчики прерываний
    usb_conf.h, usb_endp.c — здесь определяются конечные точки (Endpoint), размеры и адреса их буферов, функции-обработчики
    usb_desc.h, usb_desc.c — здесь собрана информаци о самом устройстве — как оно будет определяться при подключении к ПК и определены размеры и формат пакетов данных
    hw_config.c — здесь собрана вся работа с отправкой данных на ПК
    hw_config.h, usb_istr.h, usb_prop.h, usb_pwr.h
    usb_istr.c, usb_prop.c, usb_pwr.c — нужны для работы USB-FS библиотеки, но лезть в них необязательно

Инициализация USB


Для корректной работы USB модуля важна частота работы МК. Далеко не все частоты позволяют правильно задать тактирование USB. В нашем случае используется кварцевый генератор на 8МГц и МК работает на частоте 72МГц, а USB модуль на 48МГц.
В main.c достаточно включить всего несколько строк кода

В функции Set_System() производится настройка пина подтяжки линии D+ к питанию для программного подключения/отключения устройства от ПК (в нашей плате не используется), настраивается прерывание и инициализируются светодиоды и кнопки для демонстрационного проекта.
В USB_Interrupts_Config() настраиваются прерывания в зависимости от семейства МК (поддерживаются F10x, F37x, L1x).
Функция USB_Init() запускает работу USB модуля. Если временно нужно отключить для отладки работу с USB, просто закомментируйте эту строку.
Далее в бесконечном цикле проверяется, удалось ли сконфигурировать USB модуль при подключении к ПК. Если все сработало верно и устройство успешно подключилось, ПК включен и не находится в режиме энергосбережения, то состояние будет CONFIGURED.
Далее проверяется, была ли закончена предыдущая передача данных в ПК и если да, то готовится к отправке новый пакет в функции RHIDCheckState()

Размер пакета и частота передачи


USB-HID девайс не может сам инициировать передачу, т.к. координацией шины занимается host устройство — ПК. Поэтому при подготовке USB дескриптора нашего устройства, мы пишем, как часто нужно опрашивать наше устройство. По спецификации максимальная частота опроса — 1кГц и максимальный размер передаваемого за раз пакета — 64 байта. Если этого недостаточно — придется использовать другие режимы работы — вроде USB bulk, но там уже без драйверов не обойтись.
За настройку взаимодействия с ПК отвечают 3 дескриптора:

В комментариях все довольно прозрачно. Обратите внимание на DEVICE_VER_L, DEVICE_VER_H — это константы из usb_desc.h, которые вы можете изменить для идентификации версии своего устройства.

Дескриптор конфигурации (описывает возможности устройства)

Здесь стоит обратить внимание на константу wMaxPacketSize — она определяет максимальный размер пакета, которым мы будем обмениваться с ПК. Проект так настроен, чтобы при ее изменении менялись и размеры буферов. Но не забывайте, что больше 0x40 по стандарту указывать не стоит. С этой константой будьте осторожны — если передаваемый пакет будет отличаться по размеру — будут проблемы!
Следующая за ним константа с комментарием bInterval — это период опроса устройства в миллисекундах. Для нашего устройства задано 32мс.

Это самый важный дескриптор — он описывает протокол обмена и функционал устройства. Его формирование — не самая простая задача. Если допустить ошибку при формировании дескриптора — устройство перестанет работать. Формат дескриптора очень жесткий. Есть даже специальная утилита HID Descriptor tool. А в корне проекта лежит файл «RHID.hid» с описанным выше дескриптором для редактирования в этой утилите. Но если вы не понимаете, что делаете, лучше не лезть.
Для простоты я сделал две константы:
RPT3_COUNT — размер OUTPUT буфера в байтах для передачи пакета в МК (в примере — 1 байт)
RPT4_COUNT — размер INPUT буфера в байтах для передачи пакета в ПК (в примере — 4 байта)
Размер любого из этих буферов не должен превышать wMaxPacketSize. Меньше — можно.
Кстати, превратить Custom HID в другой HID девайс, например, клавиатуру или джойстик можно фактически только переписав ReportDescriptor и изменив класс и подкласс устройства в дескрипторе конфигурации.

Что такое Report

  • REPORT_ID = 1 и 2 — команда МК включить/выключить LED1/LED2. Содержит поле размером 1 бит с желаемым состоянием светодиода и поддерживает отправку как методом SET_REPORT так и методом SET_FEATURE (об этом чуть позже).
  • REPORT_ID = 3 — передает один байт в МК. Просто, чтобы показать, как передать данные МК. Мы будем передавать положение ползунка.
  • REPORT_ID = 4 — это репорт для передачи данных ПК. Возвращает информацию о текущем состоянии светодиодов, кнопок (если они есть) и возвращает переданный в репорте с байт, чтобы показать, что данные приняты.

Цикл обмена

Массив uint8_t Buffer[RPT4_COUNT+1] определен как размер полезных данных входящего (рассматривается всегда с точки зрения хоста) пакета + байт ID. Это важно — если размер буфера будет отличаться — будут проблемы. Поэтому для изменения размеров буфера редактируйте значение константы в usb_desc.h.
В функции мы собираем данные в пакет, устанавливаем флаг PrevXferComplete = 0, говорящий о том, что данные отправляются и вызываем функциии библиотеки USB_SIL_Write и SetEPTxValid для отправки данных хосту.
Все, на этом передача данных хосту закончена.

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

Обработка SET_FEATURE

Данные, отправленные методом SET_FEAUTRE обрабатываются в usb_prop.c

Здесь мы проверяем первый байт в репорте и в соответствии с ним обрабатываем остаток пакета — управляем светодиодами или просто берем байт, отправленный нам хостом и кладем в пакет для последующей отправки обратно в функции RHIDCheckState.
Под Report_Buf зарезервировано wMaxPacketSize байт, чтобы влез любой пакет, который нам отправит хост.

Данные, отправленные методом SET_REPORT обрабатываются в usb_endp.c

Здесь почти то же самое, только нужно самостоятельно забрать данные вызовом USB_SIL_Read(EP1_OUT, Receive_Buffer) и в конце сообщить, что мы закончили вызовом SetEPRxStatus(ENDP1, EP_RX_VALID);

Настраивать устройство, передавать и принимать данные в пакетах нужного размера с нужной нам периодичностью мы научились.
Собираем проект и прошиваем в устройство.
Работать, это будет примерно так:


Также я написал маленькую демо-софтинку, которая автоматически определяет подключение к компу и отключение нашего девайса по его VID и PID, отображает статус — подключено/отключено индикатором рядом с чекбоксом Auto Connect

Радиокнока Send using позволяет выбрать метод отправки данных девайсу.
Report: отображает полученный от девайса пакет побайтно, начиная с ReportID.
Щелкая по светодиодам ниже — управляем светодиодами девайса. Их состояние отображает текущее состояние девайса. Считывается из репорта от девайса.
Перемещая ползунок, мы отправляем Report с и значением, соответствующим позиции ползунка. Девайс вернет это значение в 4 байте репорта.
В выпадающем комбобоксе отображаются HID девайсы, найденные в системе и если найден наш девайс, то отображается его название.

Если остались вопросы — пишите в комментариях. Постараюсь ответить. Я постарался не утопить суть в куче мелочей, чтобы сложилось общее понимание. Остальное уже можно понять, изучая проект. Но если вам нужно быстро сделать свое устройство, а лезть в дебри некогда — все, что вам нужно, я описал.

Рано или поздно у каждого разработчика появляется необходимость подключить свое устройство к компьютеру. Для этого можно использовать LPT, COM или USB порты. Если первый морально устарел и зачастую отсутствует на материнских платах, а последний слишком сложен для начинающего, то COM порт является наиболее подходящим. Он все еще есть на материнских платах, и он относительно прост в использовании. Как и раньше, я не буду очень сильно углубляться в теоретические дебри, которых уйма на просторах интернета, а постараюсь максимально доступно объяснить основы работы на практике.

Постановка задачи:
1) Подключить STM32F4Discovery к компьютеру через COM порт;
2) Реализовать режим echo;
3) Набираемые символы должны сохраняться в текстовую переменную, по нажатию Enter в консоль должна вернуться полная строка;
4) При отправки строки “led” должны загореться 4 светодиода на плате.
Подключение к компьютеру является наиболее сложной частью задачи. У UART есть 2 основных вывода: Rx (Received Data) и Tx (Transmitted Data). Главная проблема – согласование уровней напряжения, так как в порте компьютера оно составляет 12В, а в порте микроконтроллера - 3,3В. Для решения этой проблемы используется микросхема MAX3232. Схема переходника показана на рисунке.

Диод VD1 – индикатор питания, светодиод в корпусе 0805, VD2 – защита от переполюсовки, можно взять любой маломощный. Микросхема – MAX3232 в корпусе SO16.

К статье прилагается проект платы в Sprint Layout.

Плата выполнена на одностороннем стеклотекстолите толщиной 2мм. Ответная часть для COM порта берется для монтажа на провод и одевается на текстолит, получается компактно и аккуратно.
Заранее отмечу, что я не изготавливал этот переходник для урока, так как у меня уже есть платка с аналогичной микросхемой, но такие переходники мною делались ранее.
У переходника 4 вывода:
1) Vcc – подключается к 3В питанию на отладочной плате;
2) Rx – подключается к Rx UART2 (PA3) микроконтроллера;
3) Tx – подключается к Tx UART2 (PA2);
4) GND – подключается к «земле» на плате.
Для связи с компьютером используется программа-терминал Putty.

Настройка:
Во вкладке Session выбираем Serial.
В строке Serial line пишем номер порта, к которому вы подключили плату.
В строке Speed пишем 9600 – это скорость работы.
Переходим во вкладку Serial.

Data bits ставим 8.
Stop bits – 1.
Parity и Flow control надо выставить None.
Нажимаем Open и получаем консоль.

Если подключить переходник к COM порту, выводы Vcc и GND подключить к плате, а Tx и Rx соединить, тогда то, что вы будете писать в консоли, будет возвращаться в нее же. Если при нажатии клавиш ничего не происходит и консоль остается чистой – ищите и исправляйте ошибку.

Итак, с подключением вроде справились. Теперь начинаем писать программу.
Первым делом нужно инициализировать UART, для этого создается функция:

Готово, теперь для инициализации достаточно написать usart_init() в main.
В этой функции UART настраивается по дефолтным значениям. Для более тонкой настройки вместо:

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

Принцип работы прост: send_to_uart отправляет в COM порт байт, а send_str пересылает строку по байту в send_to_uart.


И самое главное – функция обработки прерываний UART:

Вот и все, теперь запускаем консоль, прошиваем плату, подключаем и набираем строку, а затем жмем Enter и наслаждаемся результатом. Команды led0, led1, led2, led3 управляют светодиодами на плате. Как это все работает видно на видео. Исходники и плата прикреплены к статье.

Хочется отметить, что все наработки по данным урокам будут реализованы в плате расширения для STM32F4discovery о разработке которой можно почитать в этой теме

Что такое STM32

История появления

Серия STM32 была выпущена в 2010 году. До этого компанией STMicroelectronics уже выпускались 4 семейства микроконтроллеров на базе ARM, но они были хуже по своим характеристикам. Контроллеры STM32 получились оптимальными по свойствам и цене. Изначально они выпускались в 14 вариантах, которые были разделены на 2 группы – с тактовой частотой до 2 МГц и с частотой до 36 МГц. Программное обеспечение у обеих групп одинаковое, как и расположение контактов. Первые изделия выпускались со встроенной флеш-памятью 128 кбайт и ОЗУ 20 кбайт. Сейчас линейка существенно расширилась, появились новые представители с повышенными значениями ОЗУ и Flash памяти.

Достоинства и недостатки STM32

  • Низкая стоимость;
  • Удобство использования;
  • Большой выбор сред разработки;
  • Чипы взаимозаменяемы – если не хватает ресурсов одного микроконтроллера, его можно заменить на более мощной, не меняя самой схемы и платы;
  • Высокая производительность;
  • Удобная отладка микроконтроллера.
  • Высокий порог вхождения;
  • На данный момент не так много литературы по STM32;
  • Большинство созданных библиотек уже устарели, проще создавать свои собственные.

Минусы STM32 не дают пока микроконтроллеру стать заменой Ардуино.

Сравнение STM32 с Arduino

Сравнение STM32 с Arduino

По техническим характеристикам Ардуино проигрывает STM32. Тактовая частота микроконтроллеров Ардуино ниже – 16 МГц против 72 МГц STM32. Количество выводов GRIO у STM32 больше. Объем памяти у STM32 также выше. Нельзя не отметить pin-to-pin совместимость STM32 – для замены одного изделия на другое не нужно менять плату. Но полностью заменить ардуино конкуренты не могут. В первую очередь это связано с высоким порогом вхождения – для работы с STM32 нужно иметь базис. Платы Ардуино более распространены, и, если у пользователя возникает проблема, найти решение можно на форумах. Также для Ардуино созданы различные шилды и модули, расширяющие функционал. Несмотря на преимущества, по соотношению цена/качество выигрывает STM32.

Семейство микроконтроллеров STM32 отличается от своих конкурентов отличным поведением при температурах от -40С до +80 С. Высокая производительность не уменьшается, в отличие от Ардуино. Также можно найти изделия, работающие при температурах до 105С.

Обзор продуктовых линеек

STM32L

Семейство STM32 имеет широкий ассортимент изделий, различающихся по объему памяти, производительности, потреблению энергии и другим характеристикам.

Серии STM32F-1, STM32F-2 и STM32L полностью совместимы. Каждая из серий имеет десятки микросхем, которые можно без труда поменять на другие изделия. STM32F-1 была первой линейкой, ее производительность была ограничена. Из-за этого по характеристикам контроллеры быстро догнали изделия семейства Stellaris и LPC17. Позднее была выпущена STM32F-2 с улучшенными характеристиками – тактовая частота достигала 120 МГц. Отличается высокой процессорной мощностью, которая достигнута благодаря новой технологии производства 90 нм. Линейка STM32L представлена моделями, которые изготовлены по специальному технологическому процессу. Утечки транзисторов минимальны, благодаря чему приборы показывают лучшие значения.

Важно отметить, что контроллеры линейки STM32W не имеют pin-to-pin совместимости с STM32F-1, STM32F-2 и STM32L. Причина заключается в том, что линейку разрабатывала компания, которая предоставила радиочастотную часть. Это наложило ограничения на разработку для компании ST.

STM32F100R4

Микросхема STM32F100R4 имеет минимальный набор функций. Объем флэш памяти составляет 16 Кбайт, ОЗУ – 4 Кбайт, тактовая частота составляет 12 МГц. Если требуется более быстрое устройство с увеличенным объемом флэш-памяти до 128 Кбайт, подойдет STM32F101RB. USB интерфейс имеется у изделия STM32F103RE. Существует аналогичное устройство, но с более низким потреблением – это STM32L151RB.

Программное обеспечение для работы с контроллером

Keil Uvision 4

Для ARM архитектуры разработано множество сред разработки. К самым известным и дорогостоящим относятся инструменты фирм Keil и IAR System. Программы этих компаний предлагают самые продвинутые инструментарии для оптимизации кода. Также дополнительно существуют различные системы – USB стеки, TCP/IP-стеки и прочие. Применяя системы Keil, пользователь получает хороший уровень технической поддержки.

Также для STM32 используется среда разработки Eclipse и построенные на ней системы Atollic TrueStudio (платная) и CooCox IDE (CoIDE) (бесплатная). Обычно используется последняя. Ее преимущества перед другими средами разработки:

  • Свободно распространяемое программное обеспечение;
  • Удобство использования;
  • Имеется много примеров, которые можно загрузить.

Единственный недостаток среды разработки CooCox IDE – сборка есть только под Windows.

STM32 Discovery

STM32 Discovery

Начать изучение микроконтроллера STM32 лучше с платы Discovery. Это связано с тем, что на этой плате есть встроенный программатор. Его можно подключить к компьютеру через USB кабель и использовать как в качестве программируемого микроконтроллера, так и для внешних устройств. Плата Discovery имеет полную разводку пинов с контроллера на пины платы. На плату можно подключать различные сенсоры, микрофоны и другие периферийные устройства.

Что потребуется для подключения STM32 к компьютеру

Чтобы начать работу, потребуются следующие компоненты:

  • Сама плата STM32 Discovery;
  • Datasheet на выбранную модель;
  • Reference manual на микроконтроллер;
  • Установленная на компьютер среда разработки.

В качестве примера первая программа будет рассмотрена в среде CooCox IDE.

Первая программа

CooCox IDE

Обучение следует начинать с простейшего – с Hello World. Для начала нужно установить CooCox IDE на компьютер. Установка стандартная:

  • Скачивается программа с официального сайта;
  • Там нужно ввести адрес своей электронной почты и начать загрузку файла с расширением .exe;
  • Нужно открыть CooCox IDE вкладку Project, Select Toolchain Path;
  • Указать путь к файлу;
  • Снова открыть среду разработки и нажать View -> Configuration на вкладку Debugger;
  • Теперь можно записывать программу.

Когда программа установлена, ее нужно открыть. Следует перейти во вкладку Browse in Repository и выбрать ST – свой микроконтроллер.

Далее на экране появится список библиотек, которые можно подключить. Для первой программы потребуются системные CMSIS core и CMSIS Boot, библиотека для работы с системой тактирования RCC, GPIO для работами с пинами.

Сама программа пишется как и для Ардуино, нужно знать основы языка Си.

В окошке Project следует открыть main.c. В коде в самом начале следует подключить библиотеки кроме CMSIS (они уже автоматически подключены). Добавляются они следующим образом:

Затем добавляется тактирование порта в главной функции main. Какой контакт за что ответственен, можно просмотреть в даташите к микроконтроллеру.

Для настройки параметров выводов следует прописать ее название и поставить точку. Во всплывающем меню будут указаны все характеристики. Их можно исправлять.

После этого нужно сделать зацикливание в while, чтобы светодиод мигал, пока не отключится питание.

Когда программа написана, ее можно загружать в контроллер. Если есть отладочная плата, ее нужно подключить через USB кабель и нажать Download Code To Flash. Если плата отсутствует, потребуется переходник, который нужно подключить к порту компьютера. Контакт BOOT 0 подключается к плюсу питания контроллера, а затем включается само питание МК. После этого начнется прошивка.

Чтобы загрузить программу в микроконтроллер, нужно следовать указаниям от приложения. Сначала прописывается код порта, к которому подключен микроконтроллер. Также указывается скорость. Советуется брать небольшое значение, чтобы не было сбоев. Программа найдет микроконтроллер, и нужно будет нажать кнопку «далее». Во вкладке Download to device нужно в поле Download from file выбрать написанную программу и нажать «далее».

После этого нужно отключить питание контроллера STM32, закрыть Flash Loader Demonstrator, выключить переходник. Теперь можно снова включить микроконтроллер в обычном режиме. Когда программа будет загружена, светодиод начнет мигать.

Работа в других программах проходит подобным образом. Также выбираются нужные библиотеки, и прописывается код. У платных утилит функционал больше, и можно создавать более сложные проекты.

Отладочную плату ипользуем ту же: STM32F4-DISCOVERY.

Проект создаём из проекта I2CLCD80. Назовем его USB_OTG_CDC. Запустим проект в Cube, включим USB_OTG_FS в режим Device_Only

image00

В USB_DEVICE в разделе Class For FS IP выберем пункт Communication Device Class (Virtual Port Com).

image02

Лапки портов PD4-PD7, PB8, PB9 отключим, это пережиток прошлых занятий

image01

В Clock Configuration выберем следующие делители (нажмите на картинку для увеличения изображения)

image04_0500

В Configuration ничего не трогаем, т.к. прерывания там выставились сами.

Сгенерируем и запустим проект, подключим lcd.c и настроим программатор на автоперезагрузку.

У нас скорей всего устройство установится с ошибкой (код 10)

image03

Есть несколько типов решений, мне понравился именно этот, т.к. более простой: в файле usbd_cdc.h заменим размер пакета, вместо 512 напишем 256 в данной строке:

Соберём, прошьём и увидим, что ошибка исчезла.

Начнём писать код.

Сначала попытаемся передать данные на ПК.

Для этого мы сначала откроем файл usbd_cdc_if.c и исправим там в 2х строчках 4 на 64

В файле main.c закомментируем весь пользовательский код кроме инициализации и очистки дисплея

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

Также в main.c подключим файл usbd_cdc_if.h для видимости функций приема и передачи

/* USER CODE BEGIN Includes */

Немного изменим в главной функции строковую переменную, убавив в ней размер и добавив префикс tx

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

В файле usbd_cdc_if.c добавим прототип функции передачи, скопировав объявление из реализации данной функции в том же файле

/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);

/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */

В main() внесём данные в строку

/* USER CODE END 2 */

CDC_Transmit_FS((unsigned char*)str_tx, strlen(str_tx));

/* USER CODE END WHILE */

Соберём код, прошьём контроллер и посмотрим результат в терминальной программе.

Вроде передать нам что-то удалось. Теперь попробуем что-нибудь принять. Здесь чуть посложнее, т.к. для этого используется уже обработчик прерывания, коим является в файле usbd_cdc_if.c функция CDC_Receive_FS.

Добавим ещё одну строковую глобальную переменную в main()

/* USER CODE BEGIN PV */

/* USER CODE END PV */

Объявим её также и в файле usbd_cdc_if.c

/* USER CODE BEGIN PRIVATE_VARIABLES */

extern char str_rx[21];

/* USER CODE END PRIVATE_VARIABLES */

В функцию CDC_Receive_FS в этом же файле добавим некоторый код и кое-что закомментируем

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

/* USER CODE BEGIN 6 */

Добавим переменную в main()

/* USER CODE BEGIN 1 */

Занесенные в наш буфер данные попробуем вывести на дисплей, для этого в бесконечном цикле в функции main() добавим определённый код

CDC_Transmit_FS((unsigned char*)str_tx, strlen(str_tx));

Соберём проект. Прошьём код и посмотрим результат, вводя в терминальной программе и отправляя в порт USB какие-нибудь строки.

STM32 HAL. USB. Virtual Com Port

22 комментария на “ STM Урок 33. HAL. USB. Virtual Com Port ”

Просто измените размер кучи (Minimum Heap Size) в настройка CubeMX. Вместо значения 0x200 задайте 0x400.

И комп увидит устройство без ошибок.

При инициализации структур компилятору элементарно не хватает места, заданного по умолчанию, для выделения памяти.

Пардон, очепятка вышла. Не компилятору, а функции malloc.

Спасибо, так действительно проще.

Спасибо.Я сделал так.В хидер usbd_cdc_if.h добавил две строчки
extern uint8_t UserRxBufferFS[1000];
uint8_t receiveBufLen;
В метод CDC_Receive_FS добавил перед return receiveBufLen = *Len;
И в main ловил данные просто одним условием
if(receiveBufLen > 0)// если получены данные от ПК
HAL_Delay(250);
CDC_Transmit_FS((uint8_t*) UserRxBufferFS,receiveBufLen);
// эхо для наглядности
receiveBufLen = 0;// сброс получения
>
Всё просто,а UserRxBufferFS чистить не нужно от мусора,он сам чистится.

может в usbd_cdc_if.c ?

Ох, видимо сперва надо читать коментарии, прочитал тот что выше.

Скорей всего придется делать конкатенацию передаваемых строк с помощью strcat. Была аналогичная проблема при использовании CDC. Автор применял этот метод в одном из уроков.

Здравствуйте
А если я хочу передавать данные с микроконтроллера на компьютер?

Константин:
А мы их туда и передали.

Установил различные драйвера VCP от STM, но при этом плата не определяется при подключении её к компьютеру. только виден STLink Virtual COM Port. Кто уже сталкивался с такой проблемой.

Оказалась, что проблема с дровами. Надо их полностью сносить и устанавливать заново.

You can use(for example):

where ADC_Data is your ADC value.

могу скачать драйвера для виртуального ком порта. У меня STM32F415RG, может есть у кого?

Читайте также: