21. STM32. Программирование STM32F103. USB


01.11.2016

На тестовой плате STM32F103 есть microUSB разъем. И он служит не только для подачи питания. STM32F103 может работать с USB в качестве различных USB - устройств. Как USB HID устройство, в том числе как клавиатура или мышка, как виртуальный последовательный порт, USB Mass Storage, и тому подобное. Мы рассмотрим лишь пару примеров. В первом - компьютер будет воспринимать STM32F103 как виртуальный последовательный порт. Во втором примере STM32F103 эмитирует клавиатуру и мышку. STM32F103 будет двигать мышкой, (конечно на экране :), и эмитировать нажатие кнопок на клавиатуре.

Описание работы USB

В общем, Вы должны понимать что:
  • USB устройства подключаются к Хосту (чаще всего, это - компьютер). Хост - главный, он всем управляет.
  • USB устройство не может быть инициатором передачи данных. То есть, оно сидит и молчит, пока его не спросят. Спросили или прислали данные, - оно ответило или приняло данные и замолчало.
  • USB устройство имеет уникальный идентификатор. Каждое USB устройство может иметь несколько конечных точек, каждая из которых имеет уникальный адрес. Именно через конечные точки передаются данные или команды.
  • USB устройство имеет Дескриптор. Это массив данных, в котором содержится описание устройства. Благодаря дескриптору, операционная система получает информацию о USB устройстве и использует для общения с ним соответствующий драйвер.
  • Хост идентифицирует USB-устройство по ID вендора и ID продукта (Vendor ID - VID и Product ID - PID)
Я не хочу копипастить фрагменты чужих статей о том, как работает USB, и некоторые аспекты использования USB в STM32. Поэтому просто дам несколько ссылок, где можно на досуге почитать о USB: http://microtechnics.ru/osnovy-interfejsa-usb/ http://webhamster.ru/mytetrashare/index/mtb0/1410507212bb4zf8gacj http://radiokot.ru/circuit/digital/pcmod/63/ http://microtechnics.ru/mikrokontroller-stm32-i-usb/ http://microtechnics.ru/stm32-peredacha-dannyx-po-usb/ Мы можем достаточно длительное время углубляться в изучение USB интерфейса,  но мы держим в руках плату STM32F103 с USB. Мы готовы немедленно подключить ее к компьютеру. И нам уже хочется "пощупать USB за вымя". Тогда скорее "переходим к слайдам".

Библиотека STM32 USB FS Device Lib

Для работы с USB, существует библиотека для STM32. Я использую версию STM32_USB-FS-Device_Lib_V4.0.0. Архив с библиотекой содержит несколько примеров. К сожалению, для CoIDE проектов нет. Обратите внимание, что тактирование USB интерфейса требует фиксированной частоты 48МГц. STM32_Clock_01 Я приведу два, на мой взгляд, наиболее интересных примера. Первый: эмуляция виртуального порта.

Виртуальный последовательный порт

Прежде всего, нам надо позаботиться о том, чтобы компьютер смог адекватно воспринять наш STM32 как последовательный порт. Для этого надо установить драйвер, который очень сложно найти на сайте st.com, поэтому я его выложил на GITHUB: https://github.com/avislab/STM32F103/tree/master/Example_USB_Virtual_Com_Port/Drivers Драйвер для Win7, Win8 - VCP_V1.4.0_Setup.exe, для WindowsXP - VCP_V1.3.1_Setup.exe. Эти драйверы нужны только для Windows. Для Linux (Ubuntu) драйвер не нужен. Ubuntu его распознает и так. Обычно Ubuntu видит виртуальный порт как /dev/ttyACM0. Теперь пара слов о примере Example_USB_Virtual_Com_Port. После подключения прошитой платы с микроконтроллером к порту USB компьютера, компьютер будет воспринимать ее, как последовательный порт. В Windows это будет COM порт, в Linux - что-то вроде /dev/ttyACM0. В примере программа микроконтроллера реализует только эхо (echo). То есть, отправляет назад все принятые данные. Поэтому, когда Вы подключитесь к последовательному порту с помощью терминальной программы (например Putty), и начнете набирать текст, Вы увидите его на экране терминала. Если набрать символ `1` загорится светодиод на плате, когда микроконтроллер получит любой другой символ - он погасит светодиод. Этот функционал реализован в главном цикле программы:

int main(void)
{
  Set_System();
  SetSysClockTo72();
  Set_USBClock();
  USB_Interrupts_Config();
  USB_Init();
  /* Initialize Leds mounted on STM32 board */
  GPIO_InitTypeDef  GPIO_InitStructure;
  /* Initialize LED which connected to PC13, Enable the Clock*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  /* Configure the GPIO_LED pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_SetBits(GPIOC, GPIO_Pin_13);
  while (1)
  {
    if (bDeviceState == CONFIGURED)
    {
      CDC_Receive_DATA();
      // Check to see if we have data yet
      if (Receive_length  != 0)
      {
    	  // If received symbol `1` then LED turn on, else LED turn off
    	  if (Receive_Buffer[0]==`1`) {
    		  GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    	  }
    	  else {
    		  GPIO_SetBits(GPIOC, GPIO_Pin_13);
    	  }
    	  // Echo
    	  if (packet_sent == 1) {
    		  CDC_Send_DATA ((uint8_t*)Receive_Buffer,Receive_length);
    	  }
    	  Receive_length = 0;
      }
    }
  }
}
Полный код примера можно скачать здесь: https://github.com/avislab/STM32F103/tree/master/Example_USB_Virtual_Com_Port

Клавиатура и мышь

Этот пример можно использовать, когда нужно создать устройство типа сканера штрих-кодов, который эмулирует нажатия клавиши на клавиатуре. Для использования подобных устройств не требуется специальных драйверов или отдельных программных решений. После подключения к USB порту компьютера плата с микроконтроллером эмулирует последовательность нажатия кнопок на клавиатуре (функция KEYBOARD_SEND_word), и передвигает курсор мыши на один пиксель вправо и вверх (функция MOUSE_move):

int main(void)
{
  Set_System();
  SetSysClockTo72();
  USB_Interrupts_Config();
  Set_USBClock();
  USB_Init();
  while (1)
  {
    if (bDeviceState == CONFIGURED)
    {
      if (PrevXferComplete)
      {
    	  KEYBOARD_SEND_word("HELLO!!!");
    	  MOUSE_move(1,-1);
    	  //RHIDCheckState();
      }
    }
  }
}
Желательно открыть текстовый редактор и после этого подключать плату, тогда Вы сможете увидеть как набирается текст "HELLO !!!". Обратите внимание, что микроконтроллер эмулирует нажатие кнопок на клавиатуре, а не передает символы. Если у Вас будет включена русская раскладка клавиатуры, Вы увидите "РУДДЩ !!!" вместо "HELLO !!!". Полный код примера можно скачать здесь: https://github.com/avislab/STM32F103/tree/master/Example_USB_Keyboard

USB Mass Srorage

Этот пример демонстрирует возможность использования Flash памяти микроконтроллера в качестве USB носителя, то есть небольшой флешки. Размер памяти для использования всего 54Кб. С практической точки зрения это не имеет особой ценности, но в некоторых проектах возможность использовать STM32 как USB Mass Storage может пригодиться.

#include "stm32f10x.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include "usb_lib.h"
#include "hw_config.h"
#include "usb_pwr.h"
int main(void)
{
	Set_System();
	Set_USBClock();
	USB_Interrupts_Config();
	USB_Init();
	while (bDeviceState != CONFIGURED);
	while (1)
	{
	}
}
Полный код примера можно скачать здесь: https://github.com/avislab/STM32F103/tree/master/Example_USB_Mass_Storage

Защита USB

К сожалению, STM32 оказался слабым перед электростатическими зарядами на линиях USB. Вы с легкостью можете сжечь порт микроконтроллера и даже не заметить этого. Компьютер просто перестанет распознавать STM32 как USB устройство. Все остальные части микроконтроллера могут дальше исправно работать и Вам может показаться, что это проблемы в контактах, или в прошивке контроллера. К сожалению, такое случается. STM32F103C8_01 Если внимательно рассмотреть эту плату, Вы не заметите ничего, что могло бы защитить микроконтроллер от пагубного влияния электростатического напряжения. Ножки, которые отвечают за USB, подключенные к разъему через резисторы 22 Ом. Для защиты USB от статических разрядов стандартно используют супрессоры или TVS-диод (Transient Voltage Suppressor). Есть специализированные микросхемы для USB - это сборник супрессоров малой емкости, которые не влияют на скорость передачи данных. Я рекомендую позаботиться о подобной защите в своих проектах. Подробнее о защите USB читайте здесь: http://www.mirpu.ru/interface/86-usb/179-xaschita-usb.html Желаю успехов!

Смотри также:

Коментарі:
Sandor говорить:
13.02.2017 20:47
Спасибо за работу очень полезный ресурс
Sandor говорить:
13.02.2017 20:47
Спасибо за работу очень полезный ресурс
TSL говорить:
28.07.2017 20:59
В Вин7 драйвер подтянулся из инета.
Спасибо за замечательные статьи!
Евгений говорить:
28.08.2017 09:46
Ресурс действительно ценный, за что автору огромное спасибо. Я употребил в эксперименты часть проектов отсюда и всё прекрасно отработало, в результате чего случилось накопление бесценного опыта. Но вот один из проектов ну ни как не реализуется. Это Example_USB_Keyboard !
Проект компилируется в кукоксе, но при попытке прошить из него же через stlink приводит к потере программатором прошиваемой платы. Платка после этого уже не стирается и кукокса и лечится стиранием через UART. Прошивка бинарника через уарт происходит ОК, но платка при подключинее не опрделеяется, то есть неизв устройство, вид\\пид-ов винда не видит.
Автор, плиз, если услышишь, подкинь идеек как найти причину и через это получить ещё кусочек бесценного опыта! :)
Константин говорить:
10.05.2020 22:17
Всем добра! Отличный ресурс! Изучаю по нему STM, дошел до USB. В качестве отладочной платы использую Blue pill, пример для COM-порта работает нормально, а клавиатура с мышью и USB Mass Srorage при подключении не определяются. В диспетчере устройств Unknown Device. Подскажите пожалуйста, в чем может быть причина и как это дебажить? Спасибо.

Додати коментар

* - обов'язкові поля

Архіви