STM Урок 34. HAL. USB. HID

 

 

 

Урок 34

HAL. USB. HID

 

 

Сегодня мы познакомимся с новым классом для USB — это Human Interface Device или как в народе говорят HID.

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

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

Для этого мы сначала конечно же сделаем проект.

Проект создаём из проекта TEST002. Назовем его USB_DEVICE_HID. Запустим проект в Cube, отключим выходные светодиоды, кнопку оставим

 

image00

 

Включим USB_OTG_FS в режим Device_Only.

 

image02

 

В USB Device выбираем Human Interface Device Class (HID)

 

image01

 

В Clock Configuration выберем следующие делители

 

image03

 

В Configuration ничего не трогаем.

Сгенерируем и запустим проект.

Соберем проект и настроим программатор на авторезет.

Скачаем файл USB Library User manual.pdf с официального сайта ST Microelectronics и откроем его на странице 39. Там дана функция отправки отчета устройством на host. В качестве хоста у нас будет выступать ПК

 

image04

 

 

Подключим файл в main.c

 

#include "main.h"

#include "usbd_hid.h"

/* USER CODE END Includes */

 

Добавим переменные туда же

 

/* USER CODE BEGIN PV */

/* Private variables ———————————————————*/

#define CURSOR_STEP     1

extern USBD_HandleTypeDef hUsbDeviceFS;

uint8_t HID_Buffer[4];

 

Напишем функцию подготовки буфера для передачи в шину

 

/* USER CODE BEGIN 0 */

static void GetPointerData(uint8_t *pbuf)

{

  static uint8_t cnt = 0; //счетчик циклов

  static uint8_t drct = 0; //направление курсора

  int8_t  x = 0, y = 0 , but = 0;

 

        if((cnt<20)&&(drct==0))

        {

                drct=0;

    x = CURSOR_STEP;

    y = CURSOR_STEP;

                cnt++;

  }

  else if (cnt>0)

  {

                drct=1;

    x = -CURSOR_STEP;

    y = -CURSOR_STEP;

                cnt—;

  }

        else drct=0;

        pbuf[0] = but;

        pbuf[1] = x;

        pbuf[2] = y;

        pbuf[3] = 0;

}

/* USER CODE END 0 */

 

В бесконечный цикл добавим код передачи буфера в шину

 

  /* USER CODE BEGIN WHILE */

  while (1)

  {

                HAL_Delay(100);

                GetPointerData(HID_Buffer);

USBD_HID_SendReport(&hUsbDeviceFS, HID_Buffer, 4);

  /* USER CODE END WHILE */

 

Соберем проект. Прошьем контроллер и посмотрим результат.

Курсор у нас ползает по диагонали вперёд-назад.

Чтобы всё это увидеть, рекомендую посмотреть видеоурок, который откроется, если Вы нажмёте картинку внизу страницы. Также в видеоуроке я даю некоторые пояснения по поводу видов дескрипторов класса HID и много ещё какой информации. Так что милости прошу на канал в YouTube, там вы ещё не то увидите.

Теперь поиграемся с эмуляцией кнопок мыши.

Закомментируем часть кода в функции подготовки буфера и добавим код для эмуляции нажатия левой кнопки мыши

 

  int8_t  x = 0, y = 0 , but = 0;

 

//        if((cnt<20)&&(drct==0))

//        {

//                drct=0;

//    x = CURSOR_STEP;

//    y = CURSOR_STEP;

//                cnt++;

//  }

//  else if (cnt>0)

//  {

//                drct=1;

//    x = -CURSOR_STEP;

//    y = -CURSOR_STEP;

//                cnt—;

//  }

//        else drct=0;

        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_SET)                but=1;

        else but=0;

        pbuf[0] = but;

        pbuf[1] = x;

        pbuf[2] = y;

        pbuf[3] = 0;

}

 

Соберем, прошьем и попробуем нажать кнопку USER.

Заменим единичку на двойку

 

//        else drct=0;

        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_SET)                but=2;

        else but=0;

 

Посмотрим результат.

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Купить отладочную плату можно здесь STM32F4-DISCOVERY

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM32 HAL. USB. HID

Один комментарий на “STM Урок 34. HAL. USB. HID
  1. Михаил:

    Здравствуйте!

    Огромное спасибо за Ваши уроки!

    Я пытаюсь сделать эммулятор мыши на микроконроллере STM32F103RCT6.

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

    uint8_t USB_Report_Buf[] = {0,   0,  0, 0,
                                1,   0,  0, 0, // Нажать кнопку
                                1,  50,  0, 0, // Переместиться влево на 50 пикселей
                                0,   0,  0, 0, // Отпустить кнопку
                                0,  50,  0, 0, // Переместиться влево на 50 пикселей
                                1,   0,  0, 0, // Нажать кнопку
                                1,  50,  0, 0, // Переместиться влево на 50 пикселей
                                0,   0,  0, 0, // Отпустить кнопку
                                0, 206,  0, 0, // Переместиться вправо на 50 пикселей
                                0, 206,  0, 0, // Переместиться вправо на 50 пикселей
                                0, 206,  0, 0, // Переместиться вправо на 50 пикселей
                                0,   0,  2, 0, // Переместиться вниз на 2 пикселя
                                0,   0,  0, 0}; 

    Отправка его осуществляется в главном цикле программы:

      /* USER CODE BEGIN WHILE */
      while (1)
      {
      /* USER CODE END WHILE */

      /* USER CODE BEGIN 3 */
        HAL_Delay(1000);
        pUSB_Report_Buf = &USB_Report_Buf[0]; // Установить указатель на начало списка коменд
        for (uint8_t i = 0; i < sizeof(USB_Report_Buf)/4; i++) { // Цикл по всем командам списка
          USBD_HID_SendReport(&hUsbDeviceFS, pUSB_Report_Buf, 4); // Отправка Репорта
          pUSB_Report_Buf += 4; // Увеличиваем указатель на 4 (количество байт в Репорте)
          HAL_Delay(500);
        }
      }
      /* USER CODE END 3 */

    }

    Но что-то не то происходит с первой командой (перемещает не на 50 пикселей, а меньше). И  это стабильно втечение всего времени работы (главного цикла).

     

    Если открыть редактор Paint, то на экране должно быть что-то типа:

    ___________________                    ___________________

    ___________________                    ___________________

    Но вместо этого выводит

              _________                    ___________________

    _________                    ___________________

    Подскажите в чем может быть проблема. Спасибо.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*