由于 STM 引入了用于代码生成的 CubeMX,我寻找了一个有趣的应用程序来使用这个工具并检查它的易用性。选择是制作一个 HID 设备,特别是具有 X/Y 模拟输入和一些按钮的操纵杆或游戏手柄,在 Window10 下支持。
使用 Cube 项目“USBTest4_joystick”
Nucleo32对于硬件,我们使用 STM43L432KC Nucleo-32 板,但您可以使用任何其他支持备用 USB 接口的 nucleo(32/64/144) 板,但我喜欢小巧的外形和 Arduino 接头样式。它配备了一个大型 32 位微控制器,在本例中为 Cortex-M4 - QFN32 封装中的低功耗
该板预定义了一个调试芯片 - ST-Link -,它使用顶部的 mico-usb 通过虚拟 com 端口和/或大容量存储接口进行通信。这个 ST-Link 是您的程序和调试接口(和电源),并且使用 UArt2 RX/TX 进行接口,(这不是我们将使用的 USB !!)备用 USB 设备被移植到 PA_12(D2 ) 和板上的 PA_11 (D10)。为了准备,您可以使用旧的 USB 电缆,切断外围连接器(迷你或微型 USB)并剥去电线。:
红色 = 5V,黑色 = GND,绿色 =D+,白色 =D-。这个不错的部分是您可以将 USB 直接连接到核板,不需要接口,如果您愿意,除了一些保护(即钳位二极管,或者在我的情况下,5V 电源线上的二极管以避免核电源在连接错误)。现在您已准备好设置工具。
立方体MX
CubeMX 是一款免费工具,支持使用基本驱动程序或 Bsp(板级支持包)轻松设置 STM32 设备,以用于新的开发项目。它会生成一组标准的库和驱动程序,因此您可以快速准备好构建自己的应用程序。CubeMX 可在此处下载,CubeIDE在此处,安装在您的系统上并启动 CubeMX。
现在选择新项目,并使用板选择器工具找到您的核板。生成默认值,您最终将得到所选设备的引脚。
当您选择板时,布局已经预先定义,板上的 IO 布线,如 OSC、UArt2 RX/TX 和 PB3 上的绿色 LED。在左侧,您可以选择每个功能块的芯片布局详细信息。要添加 USB,请选择connecivity ,选择USB并选择FS device ,现在已经配备了引脚 PA11 和 PA12。对于中间件(驱动程序),选择中间件部分,USB_Device并选择人机接口设备(HID)的下拉框(不要使用自定义的)USB需要48Mhz时钟,所以在顶部选择时钟配置,您可以使用自动时钟解析器将USB 时钟设置为 48Mhz。您几乎可以编写应用程序了!
立方IDE
还有一些准备工作的步骤:选择Project Manager选项卡,为项目命名,使用Basic Application Structure(对于 main.c 结构),然后在 Toolchain 部分选择CubeIDE 。保存您的项目....然后按右上角的生成代码!准备好后,您可以打开项目,CubeIDE 将启动:
我不打算解释 CubeIDE 接口,假设您以前使用过像 Gnu 或 Keil 这样的 IDE。这是 CubeMX 所做的好事:
USB 描述符
这本身就是一个故事。请让自己了解 USB 是如何工作的,以及描述符是如何工作的。有趣的链接是:
那么要改变什么呢?- 检查这篇文章中的 CubeMX 项目文件,打开带有项目的 CubeIDE:USBTest4_joystick 。此示例构建 USB 接口并生成“假”XY 运动和按钮按下作为示例。
中间件部分:Class>HID>SRC>usbd_hid.c - 在这里我们必须更改描述符。首先适配“ USB HID device Configuration Descriptor ”:,这有3个部分:FS/HS和OtherSpeed,都是一样的设置。将接口子类更改为无启动 (0x00) 并将接口协议更改为 0x04 = 操纵杆。对所有 3 个部分执行此操作(!)
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x04, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse 4=joystick */
其次,我们必须更改 HID 设备描述符。这描述了我们发送给 USB 主机的报告,以告知我们的设备正在吐出哪些数据:find static uint8_t HID_MOUSE_ReportDesc (我们保持相同的鼠标命名,但如果您愿意,可以在整个文件中更改它)。数组内容将是:
0x05, 0x01, // Usage Page ( Generic Desktop controls)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0xA1, 0x02, // Collection (Logical)
0x05, 0x01, // Usage Page (Generic Ctrls)
0x09, 0x30, // Usage X
0x09, 0x31, // Usage Y
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8) -> 8 bits (1 byte value)
0x95, 0x02, // Report Count (2) -> 2x = 2 bytes -> no bit stuffing
0x81, 0x02, // Input (Data,Var,Abs,...)
0x05, 0x09, // Usage Page (Button)
0x09, 0x01, // Usage Button1
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1) -> 1 bit
0x95, 0x01, // Report Count (1) -> 1 value : need to stuff 7 more bits
0x81, 0x02, // Input (Data,Var,Abs...)
0x75, 0x07, // Report Size (7) -> 7 bit
0x95, 0x01, // Report Count (1) -> 1 value 7 bits for byte alignment
0x81, 0x03, // Input (Const,Var,Abs,,,,,)
0xC0, // end collection Logical
0xC0, // End Collection => 46 bytes
// Report 2 bytes signed for XY and 1byte unsigned for button info bit-0
现在更改包含文件以将 Class>HID>SRC>usbd_hid.h 中此数组的大小更改为 46:
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x04U // kept the same
#define USB_HID_CONFIG_DESC_SIZ 34U
#define USB_HID_DESC_SIZ 9U
#define HID_MOUSE_REPORT_DESC_SIZE 46U // CHANGED
现在,对这两个文件进行备份,因为当您运行另一个代码生成器时,cubeMX 会覆盖这些文件!这就是我们所做的全部更改,USB 部分将使用 STM USB-ID,并且设备将被识别为 STM 产品。对于测试,这很好,对于您自己的产品,您应该通过 USB.ORG 获取您自己的 ID。
Src > Main() :首先将 Hid 包含文件添加到用户包含部分:
/* USER CODE BEGIN Includes */
#include
#include "usbd_hid.h"
/* USER CODE END Includes */
其次,我必须显式声明 USB 句柄,否则编译器会出错(可能是我的路径有问题?):
/* USER CODE BEGIN PV */
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE END PV */
现在设置一个符合 usbd_hid.c 中报告描述符的结构和变量:
// HID Game
struct gameHID_t {
int8_t JoyX; // X 1 byte, signed value
int8_t JoyY; // Y 1 byte, signed value
uint8_t JoyB1; // Button, one byte, button is bit #0
};
struct gameHID_t gameHID;
gameHID.JoyX = 0;
gameHID.JoyY = 0;
gameHID.JoyB1 = 0;
int8_t counter1=0; // counter for makingthe fake values wrapping around
最后但同样重要的是,在主 while 循环中设置和发送报告值:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// Send HID report
counter1=(counter1+1)%32-127; // faking X,Y and button values
gameHID.JoyX = counter1*2;
gameHID.JoyY = counter1*4;
gameHID.JoyB1 = ~gameHID.JoyB1; //
USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*) &gameHID, sizeof(struct gameHID_t));
HAL_Delay(100);
}
/* USER CODE END 3 */
编译项目,并启动代码(使用调试器或使用 Bin 文件转储到 PC 上 nucleo 的大容量存储驱动器。如果您需要使用 nucleo 板在 CubeIDE 中设置调试器的帮助,这是有趣的阅读:
视窗 USB
运行后,将 USB 插入系统,它应该可以识别 USB 设备。在 Windows> ControlPanel > Devices & Printers 下,会弹出一个新设备作为 GameController STM32 !
左键单击新设备,然后选择设置,双击 STM 控制器打开测试窗口。- 如果您的设备根本不显示,请检查您的 USB HID 代码。- 如果您的设备显示,但有感叹,点击设备,windows给你一个故障描述,主要是描述符有问题(错误代码,或者数组大小不匹配)-如果你的设备显示正常,但测试结果不存在(没有移动或按钮闪烁),报告发送有问题,请检查 main() 中的报告数据和结构。
要进行更多调试,您可以使用由 CubeMX 实例化的 ST-Link 调试 Uart(在本例中为 uart2)并使用虚拟 com-port 通过 HAL_UART_Transmit( ) 函数发送/接收文本,请参阅此阅读链接。(它在 115200baud, 8, n, 1 上启动)
工作正在进行中....
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !