STM32F103C8 (Source Code)
Serial(UART) to USB HID Keyboard Mouse Joystick
串口 转 USB键盘;鼠标;手柄 源码
(1) 使用Composite Device 组合(复合)设备
(1.1) 1个Device -> 1个 Configuation -> 3个Interfance (Keyboard & Mouse & Joystick)
(1.2) Keyboard Interfance -> HID (boot mode) -> 2个Endpoint(IN_0x81 & OUT_0x01) -> KeyboardReportDescriptor(不使用Report ID)
(1.3) Mouse Interfance -> HID (boot mode) -> 1个Endpoint(IN_0x82) -> MouseReportDescriptor(不使用Report ID)
(1.4) Joystick Interfance -> HID -> 1个Endpoint(IN_0x83) -> JoyStickReportDescriptor
(1.5) 使用HID boot模式, 不使用Report ID, 以便兼容在 计算器设定BIOS模式 中的操作
(1.6) 支持反馈Keyboard_LED灯号: All Off; Num Lock; Caps Lock; Scroll Lock; Compose; Kana
(2) 串口接收 命令
(2.1) UART协议: 115200, n, 8, 1
(2.2) 1帧发送字符串格式, 以 '{'开始, '}'结束 ','分隔 共9个10进制数字
例如: {1,2,3,4,5,6,7,8,9}
(2.3) 第1位 区分 Keyboard(128) 或是 Mouse(64) 或是 Joystick(32) 命令
例如:
{32, 0,0,0,0,0,0,0,0} --- 发送Joystick命令
{64, 0,0,0,0,0,0,0,0} --- 发送Mouse命令
{128,0,0,0,0,0,0,0,0} --- 发送Keyboard命令
(3) 发送Keyboard键盘命令时 : 第2~9位 分别如下
(3.1) 第2位 : Modify_Key(修饰键)
Key_Release = 0x00,
Left_Control = 0x01,
Left_Shift = 0x02,
Left_Alt = 0x04,
Left_GUI = 0x08,
Right_Control = 0x10,
Right_Shift = 0x20,
Right_Alt = 0x40,
Right_GUI = 0x80,
例如:
{128, 8,0,0,0,0,0,0,0} --- 发送 Win_Key键
{128, 128,0,0,0,0,0,0,0} --- 发送 WinApp_Key键
{128, 32,0,0,0,0,0,0,0} --- 发送 右Shift键
(3.2) 第3位 : 保留,不使用,一律填0
(3.3) 第4~9位 : 可以同时发送6个Keyboard按键
例如:
{128, 0,0,4,5,6,7,8,9} --- 发送 'abcdef'键
{128, 2,0,4,5,6,7,8,9} --- 按住 左Shift 发送 'abcdef'键 => 'ABCDEF'
{128, 0,0,0,5,0,7,0,9} --- 发送 'bdf'键 (0表示 无按键)
按键码 可参阅: (HID Usage ID)
http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
https://www.hiemalis.org/~keiji/PC/scancode-translate.pdf
https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
(4) 发送Mouse鼠标命令时 : 第8~9位 分别如下
(4.1) 第2位 : 鼠标按钮(左,中,右)占3bits
Button_Release = 0x00,
Left_Button = 0x01,
Right_Button = 0x02,
Mid_Button = 0x04,
例如:
{64, 1,0,0,0,0,0,0,0} --- 点击 左键
{64, 2,0,0,0,0,0,0,0} --- 点击 右键
{64, 4,0,0,0,0,0,0,0} --- 点击 中键
(4.2) 第3~5位 : 移动(X,Y), 滚轮(Wheel)
X: -127~127:左右移动鼠标
Y: -127~127:上下移动鼠标
Wheel: -127~127:上下转动滚轮
例如:
{64, 0,20,-10,0,0,0,0,0} --- 鼠标 右移20,上移10
{64, 0,0,0,-30,0,0,0,0} --- 滚轮-30
(4.3) 第6~9位 : 保留,不使用,一律填0
(5) 发送Joystick手柄命令时 : 第8~9位 分别如下
(5.1) 第2~4位 : 移动X,Y,Z
X: -127~127:X轴左右移动手柄
Y: -127~127:Y轴上下移动手柄
Z: -127~127:Z轴转动手柄
例如:
{32, -127,0,0,0,0,0,0,0} --- 移动手柄X轴到-127(最右边)
{32, 0,127,0,0,0,0,0,0} --- 移动手柄Y轴到127(最下面)
{32, -95,32,96,0,0,0,0,0} --- 移动手柄X,Y,Z轴到(-95,32,96)
(5.2) 第5~7位 : 旋转X,Y,Z
X: -127~127:X轴旋转
Y: -127~127:Y轴旋转
Z: -127~127:Z轴旋转
例如:
{32, 0,0,0, 63,0,0,0,0} --- 旋转手柄X轴到63
{32, 0,0,0, 0,-32,0,0,0} --- 旋转手柄Y轴到-32
{32, 0,0,0, 0,0,127,0,0} --- 旋转手柄Z轴到127
(5.3) 第8位 : 2个 Hat_switch(方向帽) POV1, POV2
POV1_0 = 0x00,
POV1_45 = 0x01,
POV1_90 = 0x02,
POV1_135 = 0x03,
POV1_180 = 0x04,
POV1_225 = 0x05,
POV1_270 = 0x06,
POV1_315 = 0x07,
POV2_0 = 0x00,
POV2_45 = 0x10,
POV2_90 = 0x20,
POV2_135 = 0x30,
POV2_180 = 0x40,
POV2_225 = 0x50,
POV2_270 = 0x60,
POV2_315 = 0x70,
例如:
{32, 0,0,0, 0,0,0, 3,0} --- POV1到90度
{32, 0,0,0, 0,0,0, 103,0} --- POV1到135度(0x07);POV2到270度(0x60) 即(0x07+0x60=0x67=103)
(5.4) 第9位 : 8个按钮(每个按钮占1bit)
例如:
{32, 0,0,0, 0,0,0, 0,85} --- 按钮: (0x55=85) 1,3,5,7:ON; 2,4,6,8:OFF
{32, 0,0,0, 0,0,0, 0,170} --- 按钮: (0xAA=170) 1,3,5,7:OFF; 2,4,6,8:ON