Проект виртуального сом порта для отладочной платы stm32h107

Проект виртуального СОМ порта для отладочной платы STM32H107

Для изучения работы USB в микроконтроллерах STM32F105, STM32F107 существует определенное количество отладочных плат. Большинство из них имеет высокую стоимость, но, при этом, существуют демо-проекты, написанные и отлаженные производителем STMicroelectronics, которые без дополнительных усилий можно сразу загрузить в эти платы и все будет работать.

Существуют и дешевые отладочные платы, например STM32-H107 фирмы Olimex. Но проблема в том, что для дешевых плат нельзя найти готовые для использования демо-проекты.

Эта статья представляет демо-проект виртуального COM порта, который содержится в библиотеке от STMicroelectronics stm32_f105-07_f2_f4_usb-host-device_lib STM32_USB-Host-Device_Lib_V2.1.0ProjectUSB_Device_ExamplesVCPTrueSTUDIOSTM3210C-EVAL_USBD-FS , адаптированный для работы с отладочной платой STM32-H107 и результаты тестов скорости передачи.

Скачать его можно по ссылке ниже

Распакуйте архив проекта. Запустите Atollic TrueStudio.

Выберите File->Import->General->Existing Projects into workSpace->Next.

Выберите папку проекта VCP.

Установите галку Copy projects into workspace.

Скомпилируйте проект и он готов к загрузке в плату STM32-H107.

При создании проекта установлена конфигурация JTAG порта процессора как ST-Link.

Я использовал ST-Link, имеющийся на отладочной плате STM32VLDISCOVERY. См. рисунок ниже.

Схема соединений следующая:

Предварительно, на персональном компьютере (PC) надо установить драйвер от STMicroelectronics VCP_V1.3.1_Setup.exe.

Загрузите исполняемый код в STM32-H107 и запустите его выполнение.

Через небольшое время, необходимое для инициализации виртуального COM порта, на PC в диспетчере оборудования, в разделе порты COM и LPT появится устройство виртуальный COM порт, как показано на рисунке ниже.

Номер порта назначается первый свободный в системе.

Если этот номер не устраивает, его можно изменить средствами операционной системы ОС.

В этой статье не рассматривается использование виртуального COM порта по его прямому назначению, когда данные, принятые от РС через USB, отправляются на передачу через USARTx (UARTx) микропроцессоров STM32F105 или STM32F107, а данные, принятые USARTx(UARTx), отправляются на передачу через USB микропроцессоров на РС. Это требуется только в случае построения USB-serial преобразователей.

Гораздо более интересное использование этого демо-проекта для обмена по USB в режиме CDC (common device class).

В классическом варианте использования CDC должна быть библиотека функций для использования в программе микроконтроллера STM32F10x (это

библиотека STM32_USB-Host-Device_Lib_V2.1.0 и она свободно распространяется на сайте STMicroelectronics).

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

Обойти вопрос покупки библиотек можно, используя со стороны микроконтроллера режим передачи CDC, а со стороны РС только драйвер виртуального COM порта. Все необходимые функции для работы с виртуальным COM портом такие же, как для обычных СОМ портов и содержатся в WinSDK. Функции объявлены в файле winbase.h, а содержатся в библиотеке kernel32.lib.

Эти функции следующие:

При помощи этой функции открывается СОМ порт.

Ниже дается пример вызова функции:

При помощи этой функции закрывается СОМ порт.

BOOL CloseHandle(HANDLE hObject); // handle to object to close

Функция для передачи данных от PC на COM порт:

Данные от СОМ порта принимаются в отдельном потоке при помощи:

Для того, чтобы на стороне микроконтроллера использовать режим CDC, в библиотечный файл usbd_cdc_vcp.c добавлена функция

uint16_t CDC_DataTx (uint8_t* Buf, uint32_t Len); , которая является аналогом имеющейся там функции uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len);

, с разницей в источнике данных для передачи. Для первой функции это uint8_t* Buf – массив данных, который требуется передать, второй функции данные поставляет USARTx(UARTx) микроконтроллера.

Таким образом, функция CDC_DataTx является точкой входа для передачи данных по USB от микроконтроллера на РС.

На стороне PC использовалась самодельная программа для приема/передачи байтов по порту RS232, окно которой показано ниже:


Рис.1

Она позволяет:
– оперативно открывать/закрывать COM порт с любым номером
– устанавливать требуемую скорость работы порта
– имеет поток, который принимает байты от порта и выводит их на левый экран.

Для случая проверки максимальной скорости передачи, вывод принятых байтов на экран заблокирован, а добавлен счетчик, который выводит на форму количество принятых байтов в секунду(обведено красным).

– передавать из правого окна одиночные байты, массивы байтов и строки.

Для проверки максимальной скорости передачи от микроконтроллера к PC, на плате STM32-H107 надо нажать кнопку WKUP. Загорается зеленый светодиод, микроконтроллер в цикле main следит за переменной USB_Tx_State. Когда она становится равной 0(т.е.ресурсы USB на передачу свободны), загружает эти ресурсы очередным массивом данных.

Из рис.1 видно, что скорость передачи составила 424.5 килобайт/сек. Такая скорость получена при установке в 0 параметра

#define CDC_IN_FRAME_INTERVAL 0 /* Number of frames between IN transfers */ в файле usbd_conf.h. Если параметр увеличивать, скорость будет уменьшаться.

В этой проверке установленная скорость виртуального порта не играет никакой роли.

Прием байтов от РС

Из программы на РС передается байт 123 (см.рис.2)


Рис.2

На рис.3 видно, в каком месте проекта появляется принятый от РС пакет.


Рис.3

Принятый от РС пакет содержит переданный байт 123(фигурная скобка), USB_Rx_Cnt=1, т.е длина пакета равна 1.

Для проверки максимальной скорости передачи байтов от PC на микроконтроллер программа на РС передавала пакет из 64 байтов и ждала подтверждения от микроконтроллера о приеме пакета. Потом цикл повторялся. Функция usbd_cdc_DataOut в программе микроконтроллера была модифицирована следующим образом:

Т.е функция APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt); закомментирована, чтобы она не передавала принятые байты в USART микроконтроллера. Поток, работающий на прием на РС, подсчитывал, при этом, 1-байтовые ответы от микроконтроллера.

На рис.4 показан результат теста:


Рис.4

Скорость передачи составила 8926 х 64 = 571264 байт/с.

Следует отметить, что и в этом тесте установленная скорость виртуального порта не имеет никакого значения. Можно поставить малую скорость, например 115200 бит/с, а результат остается тем же.

Можно подвести итог:

  1. Данные по скорости обмена по USB получены при минимальной их обработке со стороны микроконтроллера. Если обработка данных будет более сложная, скорость обмена уменьшится.
  2. Скорость обмена ограничивается быстродействием микроконтроллера, работающего на частоте 72МГц.
  3. Скорость обмена достаточно большая и позволяет использовать описанные в статье методы приема и передачи данных по USB микроконтроллеров STM32F105, STM32F107 при написании программ для широкого круга приложений.

STM Урок 33. HAL. USB. Virtual Com Port

Урок 33

HAL. USB. Virtual Com Port

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

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

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

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

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

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

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

Соберем проект. Прошьём контроллер. У нас появится неизвестное устройство, скачаем драйвер на наше виртуальное устройство usb. Для этого зайдем на сайт st.com, в строке поиска там вводим virtual com port, скачиваем и устанавливаем драйвер. Затем желательно зайти в папку с установленным драйвером, выбрать папку, соответствующую разрядности нашей операционной системы, и запускаем также установку и оттуда.

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

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

#define CDC_DATA_HS_MAX_PACKET_SIZE 256 /* Endpoint IN & OUT Packet size */

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

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

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

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

/* It’s up to user to redefine and/or remove those define */

#define APP_RX_DATA_SIZE 64

#define APP_TX_DATA_SIZE 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 */

В бесконечном цикле попробуем эти данные отправить в порт USB, используя функцию, прототип которой мы добавили

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 какие-нибудь строки.

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

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

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

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

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

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

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

Спасибо огромное за ваши материалы по STM32 , подключил TFT 320×240 – все отлично работает . Вернулся к материалу для подключения флешки . Все отладочные средства у меня находятся на VirtualBox ( W7 ) . Скачал по вашей инструкции и поставил драйвер Virtual com port . Он поставился , но в диспетчере задач ничего не появилось ни в разделе com портов , ни в других . Может вы сталкивались с подобной проблемой ? Если нет – в любом случае еще раз спасибо за проделанную работу .

Сначала не смог реализовать данный пример на SystemWorkbench в части приёма данных и передачи их из функции приёма в main посредством массива str_rx с модификатором extern – компилятор ругается на использование неопределённых переменных, а если задать ему какие-нибудь значения, то только эти заданные значения и будут передаваться. Вышел из положения объявив массив обмена str_rx в заголовочном файле usbd_cdc_if.h

Спасибо.Я сделал так.В хидер 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 чистить не нужно от мусора,он сам чистится.

Здравствуйте! Спасибо огромное за ваши уроки, тут пожалуй лучший ресурс с уроками по стм32!
Хочу спросить, а как использовать CDC_Receive_FS в main.c? Я проделал в usbd_cdc_if.c “эхо”, но мне нужно принимать из него и гнать дальше. Наверное вопрос больше в целом по си чем по контроллеру, а то иначе мне получается надо много всего переносить в usbd_cdc_if.c.

Думаю, что следует добавить в main.c функцию, а в файле usbd_cdc_if.c – на неё прототип и вызвать её в CDC_Receive_FS, И весь свой пользовательский код затем писать в файле main.c.
Это именно СИ. Так что обязательно подтяните свои знания по языку.

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

При переходе на USB cтолкнулся с такой проблемой. Скажем, конструкция, приведённая в примере, а именно
sprintf(str_tx,”USB Transmitrn”);
CDC_Transmit_FS((unsigned char*)str_tx, strlen(str_tx));
работает без проблем. Но, если я делаю так
sprintf(str_tx,”USB Transmit”);
CDC_Transmit_FS((unsigned char*)str_tx, strlen(str_tx));
CDC_Transmit_FS((unsigned char*)”rn”, 2);
то CDC_Transmit_FS((unsigned char*)”rn”, 2); не срабатывает (не успевает) и данные летят без переноса строки. Если ставить задержку, то работает как надо. По неопытности, может, это я и принял бы как должное, если бы перед этим не работал бы с UART где такая же конструкция работает без проблем. Для работы с UART уже написана довольно хорошая часть программы и менять её структуру очень не хочется, тем более, что данные передаются не в текстовом формате а в посылке имеется несколько меток. Что можно сделать, чтобы посылки могли идти подряд без задержки?

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

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

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

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

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

Hello, I’m new to STM32. How do I send int32_t value via usb CDC from ADC input ? or How to convert int32_t to char?

You can use(for example):

sprintf(str_tx,”ADC:%d rn”,ADC_Data);
CDC_Transmit_FS((unsigned char*)str_tx, strlen(str_tx));

where ADC_Data is your ADC value.

Спасибо за примеры. С USB в базовой библиотеке что-то не так. При первом подключении ком порт работает, но при передергивании USB – становится неизвестным устройством, иногда не сразу а через 5-10 секунд после повторного подключения…
Сейчас копаю в сторону функций вызываемых на отключение и подключение USB. Первое что кажется подозрительным, то что на подключение вызывается инициализация а на отключение USBD_LL_Suspend, затем на подключение снова инициализация, хотя есть USBD_LL_Resume. Пока дальнейших идей нет. Может что-то подскажете?

STM32 – организация виртуального COM-порта

Раз у камня есть аппаратный USB, то грех им не пользоваться. Один из способов плюнуть байтом в компьютер и чтобы он при этом не очень обиделся — это организация виртуального COM-порта.
Все в железе пробовалось на камне STM32F103ZE, на аналогах тоже должно взлететь.

Забиваем.

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

Точные названия я привожу на случай если на сайте производителя будет какая-нибудь реорганизация и ссылки станут невалидными.

Не забываем дрова виртуального ком-порта. У меня вообще-то оно само все нашлось, но я много чего ставил от STM, может там в комплекте и пришлись.

Также нам пригодятся следующие стандарты
USB 2.0 Specification
USB CDC

В составе библиотеки есть пример как раз организации виртуального COM-порта. Правда там он сделан как мост USART-USB, но мы же не боимся трудностей?

Цель этой статьи — разобрать приложение, делающее следующее:

Поджигаем

Собираем проект из нужных нам библиотек: CMSIS, SPD, USB. Дерево проекта прилагаю.

Как обычно, самое интересное в папочке /src. Вот её-то и будем разбирать.

Неторопливо курим

Начнем с раскуривания библиотеки от STM

Эта библиотека предназначена и для connectivity-line устройств (это STM32F105/107), у них не просто USB FS, а USB OTG. Поскольку камней с OTG у меня пока нет, сконцентрируемся на простом USB FS.
В примере, который мы взяли за основу, есть куча дефайнов, как раз на случай отличить connectivity-line от других демоплат. Я эти дефайны повырезал, чтобы глаза не мозолили.

Cо всей картинки нас интересует High Layer — синенькие квадратики, которые и составляют, собственно, пользовательскую часть библиотеки. Их мы меняем под свои нужды, все остальное остается неизменным. Если заглянуть в папочку /src, то видно, что все эти файлики там и собраны.

Первая затяжка — usb_conf.h

Самые общие настройки библиотеки.
Указано сколько у нас будет endpoints (а нам их надо 4 штуки — нулевой для начального конфигурирования устройства, один для команд, один для приема и один для передачи).
Также расписаны, какие нам будут нужны коллбэки. Все взаимодействие библиотеки и пользовательской программы построено на обратных вызовах: в случае возникновения какого-либо события вызывается функция с заданным названием. А уже содержание этой функции — проблема разработчика.
Нам будет нужен SOF_CALLBACK – сигнал начала фрейма (Start Of Frame). По нему будем выплевывать то, что накопилось в буфере передачи.
Также резервируем еще два коллбэка — на прием и передачу. По приему символа будем мигать светодиодами, чтобы уж как-нибудь задействовать канал приема.

Упс, кончился файл. Короткая получилась затяжка.

Файл берем из примера, ничего не меняем.

Вторая затяжка — usb_desc.h / usb_desc.c

В этих файлах находятся дескрипторы устройства и эндпоинтов.
Информация по стандартным дескрипторам есть в стандарте USB, в разделе 9.6 Standard USB Descriptor Definitions
Специфические дескрипторы описаны в USB CDC, раздел 5 (так и называется Descriptors),

Эти все тонны текста в стандартах для того, чтобы USB стала действительно Universal. Поэтому тщательно выведена классификация устройств и интерфейсов — чтобы глянув на дескриптор хост сразу понял, что с этим делать.

Особо подробно разбирать смысла не вижу — это не характерно для STM32, это общая боль разработчиков USB устройств.

Файл берем из примеров, ничего не меняем.

Продолжение дескрипторов — usb_prop.h / usb_prop.c

В этих файлах описана таблица реакции на запросы. Все запросы к устройству пронумерованы и стандартизованы. В этих файлах определяется массивы функций Device_Property, User_Standard_Requests и просто массивы String_Descriptor, например. Это все используется ядром. Когда в устройство приходит определенный запрос, например «Выдай мне дескриптор устройства», то ядро посмотрит в таблице, какая функция обрабатывает этот запрос, вызовет эту функцию, а оно уже отработает:

Читайте также:  Как рассчитать количество люминесцентных ламп?

Опять же, берем файл из примеров.

Прерываемся — usb_istr.h / usb_istr.c

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

Прерывание будет настраиваться в файле hw_config.c, обработчик выглядит очень просто:

void USB_LP_CAN1_RX0_IRQHandler(void)
<
USB_Istr();
>

его можно разместить в файлах stm32f10x_it.*, а в данном проекте, чтобы не растекаться мысью по древу, я его включил в файл main.c

И тут особо ничего не меняем, все как в примере.

Питание — usb_pwr.h / usb_pwr.c

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

Ничего не меняем, файл из примеров.

Коллбэки — usb_endp.c

Этот файл я переписал, поскольку у нас не будет работы с USART, как это было в примере. Приведу код с комментариями:

Работа с железом — hw_config.h / hw_config.c

В этом файле собраны функции инициализации периферии, прерываний, функции управления светодиодами и работы с буфером отправки.

USB-порт и подтяжки на моей плате сделаны по такой схеме:

И USB_EN заведен на пин PF11. Значит надо не забыть его проинициализировать и дернуть вовремя.

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

По приему символов ‘A’, ‘B’, ‘C’, ‘D’ – зажигаются соответствующие светодиоды, ‘a’, ‘b’, ‘c’, ‘d’ – гасятся.
‘1’ и ‘0’ — соответственно зажигают и гасят все светодиоды.

Ну и все, что будет передано функции USB_Send_Data() попадает в буфер, а затем и через USB – в комп.

Уфф. С USB вроде закончили.

Теперь в головной программе можно просто вызывать USB_Send_Data() и посимвольно передавать данные в комп.

Если мы на этом остановимся, то размер кода будет порядка 11 кБ:

Более двух килобайт bss – это буферы приема и передачи. Понятное дело, их можно уменьшить.

Выдыхаем — printf()

Но мы же хотим, чтобы вывод функции printf() перенаправлялся в наш свежесозданный COM-порт. Подключаем и офигеваем от количества ошибок линковки:

А тут все просто — стандартная библиотека ввода-вывода подразумевает работу с файлами, но в больших системах есть ОС, которая собственно и занимается организацией файлов для программ пользователя. А поскольку у нас нет никакой ОС, то библиотека вполне справедливо недоумевает «А что же мне делать-то?»

Вот, чтобы это обойти, в проект включается файл newlib_stubs.c
В нем находятся функции-заглушки ко всем вышеперечисленным ошибкам. Но и кроме этого, есть одна функция, которую нам и надо переписать, чтобы весь вывод шел в USB:

Видим, что как раз и вызывается наша функция USB_Send_Data()

Все, компилим, собираем, запускаем.

Архив с проектом прилагаю — это на случай, если кто не заметит маленькие буковки внизу 🙂

Использование USB в STM32 на примере Virtual COM port

К счастью, задача программирования работы с портом USB для контроллеров STM32 не отличается особой сложностью. Программа STM32CubeMX, предназначенная для конфигурирования периферии микроконтроллеров STM32, сделает самую грязную работу — скомпонует комплект файлов с исходным кодом, при работе которого ваш прибор уже будет определяться как готовое к работе устройство. Все что вам останется, это обеспечить работу USB-порта с точки зрения схемотехники плюс, разумеется, написать саму логику обработки принимаемой и отдаваемой по USB информации.

В этой статье будет рассмотрена реализация на базе STM32 виртуального COM порта, как одного из наиболее простых вариантов обеспечения совместной работы устройства на STM32 и персонального компьютера (вопросы, относящиеся к программированию ПК, более подробно освещены в статье «Обмен данными между STM32 и ПК через USB virtual COM port»).

Давайте сделаем четыре простых шага:
1. рассмотрим схемотехнические нюансы подключения;
2. при помощи STM32 Cube MX создадим минимальный программный проект с уже подключенным USB модулем;
3. дополним наш минимальный проект кодом, который будет возвращать ПК полученные от него данные (примерно как если бы мы замкнули пинцетом выводы RX и TX разъема RS-232);
4. ну и в конце добавим немного «нормального», рабочего кода, демонстрирующего работу с данными, полученными по USB.

Итак, схема.
В принципе, схемотехника подключения интерфейса USB к современному микроконтроллеру проста до безобразия. Один провод от контакта D+ USB к нужной ножке микроконтроллера, еще один провод для D-, да одна общая «земля». Но мы, в надежде на долгую жизнь разрабатываемого устройства, чуть-чуть усложним схемотехнику, добавив на шину USB пару защитных деталей. Общая схема показана на рисунке внизу (он кликабелен) и содержит следующие узлы:

1. Защитные резисторы R6, R7, последовательно включенные в линии D+, D- линий USB.
2. Защитная диодная сборка USBLC6-4SC6, включается параллельно с портом микроконтроллера.
3. Резистор R3 1.5 кОм, предназначен для обеспечения работоспособности конкретно STM32F102RBT6, который требует подключения внешнего резистора между D+ и питанием. Микроконтроллер, который будете применять вы, скорее всего, не будет требовать подобных внешних подключений, имея все необходимое «на борту».

Остальные узлы схемы имеют отношение не к USB, а к обеспечению минимальной работоспособности схемы:
1. Тактовый генератор на ZQ1, C7, C8 и R9. Кстати, если для работы последовательного порта подходит практически любая частота кварцевого резонатора, поскольку нужную нам скорость передачи можно «накрутить» при помощи самого UART, то USB гораздо менее гибок (подробности ниже, в разделе, посвященному STM32CubeMX).
2. Отладочный разъем XS1 с обвязкой для подключения к отладчику по SWD.
3. Фильтрующие конденсаторы, включенные в шину питания C1, C2, C4, C5, C6.

Далее, что касается STM32CubeMX, то последовательность создания проекта с интерфейсом USB (который, по общепринятой терминологии, относится к т. н. middleware) проще всего проиллюстрировать тремя кликабельными скриншотами, расположенными ниже. Полный мануал по использованию STM32CubeMX сюда, думаю, копировать не стоит, желающие могут погуглить последовательность действий, необходимую для создания вменяемого проекта, а мы ограничимся ключевыми моментами.

Сначала выберите нужный вам контроллер. На рисунке необходимая опция выделена красным прямоугольником. Не создавайте пробный проект на абы каком контроллере в надежде внести изменения позже. К сожалению, тип микроконтроллера после первоначального выбора изменить уже нельзя (такая вот небольшая «пасхалка» от программистов STMicroelectronics) и если вы, паче чаяния, набьете этот проект рабочей информацией, то вам придется править текстовый файл *.ioc с записанным проектом.

Самое «сложное» — включите собственно USB и выберите необходимый режим работы порта. Список доступных режимов несколько меняется в зависимости от контроллера, например, младшие модели STM32 не могут работать в качестве Mass Storage. В нашем конкретном случае для создания Virtual COM Port нужен Communication Device Class. Не пугайтесь кракозябры справа, это просто кусок рабочего проекта, у вас, разумеется, выводы контроллера будут названы иначе.

Перед тем, как создать заготовку с кодом из вашего проекта (Project -> Generate Code), обязательно зайдите в настройки (Project -> Settings -> Code Generation) и поставьте галочку у опции «Generate peripheral initialization as a pair of ‘.c/.h’ files per IP». Если этого не сделать, то кодогенератор свалит все исходники в main.c, что не только не очень хорошо с точки зрения структурированности кода, но и чревато ошибками (с кривой инициализацией АЦП сталкивался лично).

Теперь, когда вы при помощи STM32CubeMX удачно (я надеюсь) создали папку с подпапками с подпапками с рабочим кодом под ваш любимый компилятор, можно переключиться собственно на программирование поведения вашего USB-устройства. Давайте для начала реализуем простой «возвращатель байтов», хотя бы просто для того, чтобы найти в получившемся коде место, ответственное за работу с USB.

Проект виртуального сом порта для отладочной платы stm32h107

Источники питания электронной аппаратуры, импульсные и линейные регуляторы. Топологии AC-DC, DC-DC преобразователей (Forward, Flyback, Buck, Boost, Push-Pull, SEPIC, Cuk, Full-Bridge, Half-Bridge). Драйвера ключевых элементов, динамика, алгоритмы управления, защита. Синхронное выпрямление, коррекция коэффициента мощности (PFC)

  • 21 час назад
  • Тема:Вопрос по драйверам ключей блоков питания ATX.
  • От:-=TRO=-
  • Обратная Связь, Стабилизация, Регулирование, Компенсация

    Организация обратных связей в цепях регулирования, выбор топологии, обеспечение стабильности, схемотехника, расчёт

    • 16 мая
    • Тема:Источник тока Управляемый напряжением
    • От:Шнекоход
  • Первичные и Вторичные Химические Источники Питания

    Li-ion, Li-pol, литиевые, Ni-MH, Ni-Cd, свинцово-кислотные аккумуляторы. Солевые, щелочные (алкалиновые), литиевые первичные элементы. Применение, зарядные устройства, методы и алгоритмы заряда, условия эксплуатации. Системы бесперебойного и резервного питания

    • 12 мая
    • Тема:Контроллер Li-Ion батареи BQ30Z55 не работает
    • От:rfengin
  • Высоковольтные Устройства – High-Voltage

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

    • В воскресенье в 11:22
    • Тема:Какую топологию ВВ источника выбрать для двунапр…
    • От:iiv
  • Электрические машины, Электропривод и Управление

    Электропривод постоянного тока, асинхронный электропривод, шаговый электропривод, сервопривод. Синхронные, асинхронные, вентильные электродвигатели, генераторы

    • 28 мая
    • Тема:Помогите подобрать качественный драйвер ШД
    • От:dinam
  • Индукционный Нагрев – Induction Heating

    Технологии, теория и практика индукционного нагрева

    • 16 мая
    • Тема:Индукционный нагреватель на 100 кВт своими рукам…
    • От:dericc
  • Системы Охлаждения, Тепловой Расчет – Cooling Systems

    Охлаждение компонентов, систем, корпусов, расчёт параметров охладителей

    • 20 мая
    • Тема:Изолирующая прокладка между силовым компонентом …
    • От:vladec
  • Моделирование и Анализ Силовых Устройств – Power Supply Simulation

    Моделирование силовых устройств в популярных САПР, самостоятельных симуляторах и специализированных программах. Анализ устойчивости источников питания, непрерывные модели устройств, модели компонентов

    • 9 апреля
    • Тема:Micro-CAP 12. Цепи с одинаковым именем почему-то…
    • От:SAVC
    Читайте также:  Датчик движения для включения света регулировка чувствительности
  • Компоненты Силовой Электроники – Parts for Power Supply Design

    Силовые полупроводниковые приборы (MOSFET, BJT, IGBT, SCR, GTO, диоды). Силовые трансформаторы, дроссели, фильтры (проектирование, экранирование, изготовление), конденсаторы, разъемы, электромеханические изделия, датчики, микросхемы для ИП. Электротехнические и изоляционные материалы.

    • 24 мая
    • Тема:Программы расчета трансформаторов и дросселей
    • От:kochkuroff
  • Интерфейсы

      Последнее сообщение

    Форумы по интерфейсам

    все интерфейсы здесь

    • 19 часов назад
    • Тема:Облачный сервис расшифровки автомобильных кан-ло…
    • От:eurosens
  • Поставщики компонентов для электроники

      Последнее сообщение

    Поставщики всего остального

    от транзисторов до проводов

    • Вчера в 04:18
    • Тема:Изготовление лицевой панели
    • От:destroit
  • Компоненты

    Закачка тех. документации, обмен опытом, прочие вопросы.

    • 2 июня
    • Тема:Что за диод, есть фото.
    • От:Georgy
  • Майнеры криптовалют и их разработка, BitCoin, LightCoin, Dash, Zcash, Эфир

      Последнее сообщение

    Обсуждение Майнеров, их поставки и производства

    наблюдается очень большой спрос на данные устройства.

    • 21 февраля
    • Тема:Зачем нужны дорогие майнеры
    • От:Doka
  • Дополнительные разделы – Additional sections

      Последнее сообщение

    Встречи и поздравления

    Предложения встретиться, поздравления участников форума и обсуждение мест и поводов для встреч.

    • 1 июня
    • Тема:С Днём Великой Победы в Великой Войне.
    • От:evgdmi
  • Ищу работу

    ищу работу, выполню заказ, нужны клиенты – все это сюда

    • 7 часов назад
    • Тема:МОНТАЖ ПЕЧАТНЫХ ПЛАТ
    • От:radiomont
  • Предлагаю работу

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

    • 2 часа назад
    • Тема:ТЗ на разработку электронного устройства.
    • От:ergovit
  • Kуплю

    микросхему; устройство; то, что предложишь ты 🙂

    • 2 часа назад
    • Тема:SAW фильтр на 737 МГц
    • От:3apw
  • Продам

    есть что продать за деньги, пиво, даром ?
    Реклама товаров и сайтов также здесь.

    • 9 часов назад
    • Тема:Плата многоканального АЦП E14-440 (USB) и промыш…
    • От:Linker
  • Объявления пользователей

    Тренинги, семинары, анонсы и прочие события

    • 3 часа назад
    • Тема:CSP-3000 — мощные высоковольтные источники питан…
    • От:КОМПЭЛ
  • Общение заказчиков и потребителей электронных разработок

    Обсуждение проектов, исполнителей и конкурсов

    Atollic True Studio – урок по переносу проекта для STM32

    STMicroelectronics STM32F100RB

    Колыванов Сергей, Свердловская обл.

    Получившая распространение среда разработки Atollic TrueSTUDIO for STM32 стала бесплатной. Фирма STMicroelectronics купила ее у Atollic и выложила в свободное пользование для всех желающих. В данном материале приведу инструкцию по портированию программы, сделанной профессиональным программистом в среду Atollic TrueSTUDIO. По ходу изложения читатель познакомится с работой в среде разработки и получит возможность изучить стиль работы продвинутых программистов.

    В качестве примера для STM32 взят демонстрационный проект широко распространенной в кругах эмбеддеров реализации файловой системы FAT от ChaN, еще именуемой FatFs, для SD-карт памяти. По ссылке [1] в разделе Загрузки можно скачать набор примеров подключения карты к различным микроконтроллерам. В архиве лежит каталог с примером для платы STM32VLDiscovery с микроконтроллером STM32F100. Работа достаточно качественная, компилируется и работает без проблем и дополнительных настроек. Качаем и распаковываем. Предполагается, что саму среду уже загрузили с atollic.com и установили. Пример написан без использования библиотек посторонних разработчиков. Исходный пример компилируется и линкуется из командной строки под управлением утилиты make из среды Linux. Утилита make – это ставший стандартом способ управления процессом компиляции. В каталоге с примером для STM32 находится Makefile – текстовый файл, в котором расписан процесс компиляции и линковки. Если его открыть, то можно распознать списки объектных файлов, которые будут получены в результате компиляции, название компилятора, которым будет компилироваться программа arm-none-eabi-gcc и сопутствующие утилиты. В Makefile сосредоточена вся информация по процессу компиляции. Многие проекты свободного ПО для встраиваемых систем организованы по такому же принципу.

    Запускаем Atollic, выбираем File, New, C Project, Empty Project. Вводим подходящее название проекта. В поле Toolchains выбираем Atollic ARM Tools. Создается почти пустой проект, что и нужно (Рисунок 1).

    Рисунок 1.

    Выделяем вновь созданный проект правой кнопкой на вкладке Project Explorer и из контекстного меню выбираем Import…. Если вкладки Project Explorer нет, то из пункта View выбираем Project Explorer. В открывшемся окне Import выбираем File System и кнопку Next>. Затем выбираем каталог с примером проекта и все файлы с расширениями «.c» и «.h». Снимки экрана операций приведены на Рисунках 2 и 3.

    Рисунок 2.
    Рисунок 3.

    Выбранные файлы будут скопированы в папку с проектом и включены в процесс компиляции. Кроме файлов с исходным кодом, нужно импортировать скрипт линкера – файл с расширениям «.ld». Этот файл управляет линковкой программы. Следующий этап – настройка параметров компиляции. В Makefile имеются все данные для настройки компиляции, но это для тех, кто хорошо разбирается в процессе.

    Рисунок 4.

    Выбираем пункт Project, Properties, C/C++ Build, Settings. В окне Settings на вкладке Target Settings будет предложено выбрать целевую систему, для которой будет сформирован массив с параметрами компиляции. Кроме параметров компиляции будет и создан скрипт линковки для целевой системы, который будет заменен на имеющийся в примере. Выбираем STM32F100RB и сохраняем (Рисунок 4).

    Рисунок 5.

    Там же на вкладке выбираем Tool Settings, затем C Compiler и Optimization. Ставим галки на Prepare dead code removal и на Pretare dead data removal. Поясняет операцию Рисунок 5.

    В пункте C linker, General в этом же окне ставим галки на Do not use standard start files и Do not use standard default libraries. В поле ввода Linker script подставляем путь к файлу скрипта линкера, который поставляется с примером и импортирован в проект ранее. Файлы проектов находятся в домашнем каталоге пользователя в подкаталоге “Atollic”, там нужно искать каталог созданного проекта с файлами (Рисунок 6).

    Рисунок 6.

    В пункте Optimization ставим галку Dead code removal. В пункте Other, Output format выделяем галкой Convert build output. По завершении компиляции будет создан двоичный образ для записи во флэш-память микроконтроллера в выбранном формате. Снимок экрана показан на Рисунке 7.

    Рисунок 7.

    Суммарно действующие параметры, с которыми будет вызываться компилятор и линковщик, можно посмотреть, выделив в меню пункты C compiler и C Linker; они должны быть такими как на Рисунках 8 и 9.

    Рисунок 8.

    Компилируется проект командой из основного меню Project, Build Project. Информация о процессе компиляции выводится в текстовую консоль. Если окно консоли неактивно, его можно вызвать из основного меню View, Console. Если компиляция прошла успешно, будут созданы файлы с расширениями «.elf» и «.hex» или «.binary».

    Рисунок 9.

    Для записи двоичного образа программы в микроконтроллер на первых порах можно использовать программу STM32 ST-Link Utility. Для более профессиональной работы нужно настроить среду разработки, чтобы использовать утилиту командной строки ST-LINK_CLI.exe, поставляемой с STM32 ST-Link Utility. Если ST-Link не установлена, то нужно скачать дистрибутив и установить. В основном меню выбираем Run, External tools…, External Tools Configure. Ставим фокус на Program, создаем конфигурацию для программы прошивки, вводим подходящее название, подставляем путь к утилите ST-LINK_CLI.exe, выставляем рабочий каталог для утилиты и задаем параметры запуска ‘-c , в зависимости от активной конфигурации. По умолчанию устанавливается конфигурация Debug. Процесс конфигурирования иллюстрируется Рисунком 10.

    Рисунок 10.

    Схема подключения (Рисунок 11), взятая из каталога демонстрационного проекта, была вложена в папку с программным кодом. Контроллер подключается к компьютеру через RS-232. В микроконтроллере STM32F100 отсутствует аппаратный контроллер USB, наверно именно поэтому автор программы выбрал RS-232, еще достаточно распространенный в промышленности и в различном специальном оборудовании. Для сопряжения нужно использовать устройство на микросхемах, подобных MAX3232. Контакты платы STM32VLDiscovery используются следующим образом: PA10 – Rx, PA9 – Tx, PA6 MISO – DO, PA7 MOSI – DI, PA5 – SCLK, PA4 – CS_SEL; PC4 нужно замкнуть на GND.

    Рисунок 11.

    После подключения SD-карты и записи программы в микроконтроллер подключаемся к компьютеру через RS-232, возможно, с помощью переходника RS-232–USB. Для общения используем какую-либо терминальную программу. Параметры настройки порта: скорость 115200, 8N1. В Atollic имеется простой терминал последовательного порта (Рисунок 12), окно которого открывается из основного меню посредством View, Terminal. Когда откроется терминальное окно, жмем Ctrl+Alt+Shift+T, – появится окошко настройки параметров соединения.

    Рисунок 12.

    Если связь исправна, то после сброса микроконтроллера должно появиться сообщение с информацией о программе и приглашение к вводу команд ‘>’.

    По команде ‘?’, выводится краткий справочник по командам. Команда ‘di 0’ выполнит инициализацию карты. Если команда прошла успешно, то ответ будет ‘rc=0’, противное означает какую-то неисправность. Командой ‘ds 0’ проверяем статус устройства. Монтируем файловую систему: ‘fi 0’; проверяем статус системы: ‘fs 0’ (Рисунок 13). Команда ‘fl’ выводит содержимое текущего каталога.

    Рисунок 13.

    Программа задействует часы реального времени микроконтроллера, встроен также программный календарь. По команде ‘t’ на экран выводится текущее время. Дата и время устанавливаются командой ‘t 2019 1 25 12 30 00’. Если подключить батарейное питание к контакту VBAT платы, то время будет отсчитываться и при отсутствии основного питания. Не забудьте убрать перемычку SB1 на плате.

    Драйвер USART сделан с использованием обработчика прерываний и кольцевого буфера. Для формирования точных временных задержек создан обработчик прерываний на системном таймере. Среда разработки имеет развитые средства для навигации по исходному коду. Изучая профессиональные программные проекты можно повысить свою квалификацию как программиста. Удачи в работе.

  • Рейтинг
    ( Пока оценок нет )
    Загрузка ...
    Adblock
    detector