找回密码
 立即注册
查看: 42|回复: 11

HID键盘问题,求助大神

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-03-31 22:13:49
已绑定手机

2

主题

9

回帖

40

积分

新手上路

积分
40
发表于 3 天前 | 显示全部楼层 |阅读模式
最近用STC32G12K64做HID键盘的主控,用官方的标准键盘实例。做出来的键盘和电脑的标准键盘在电脑上面测试基本一致。但是在一些数控设备上面测试,发现用STC32G12K64做HID键盘主控的键盘出现很多问题,比如数控系统插上标准的HID键盘的时候,按26个字母按键,屏幕显示的是大写字母。用STC32G12K64做HID键盘主控的键盘按26个字母的时候,全部显示小写。标准的键盘按SHIFT按脚的时候,数控系统的光标会显示,用STC32G12K64做HID键盘主控的键盘按SHIFT按脚到时候,数控系统画面没有反应,但是shift按脚功能是有效的。还有一些数字按键在数控系统显示的也是不正确的。用STC32G12K64做HID键盘主控的键盘的键值都和标准的HID键盘比对过,都是完全正确的。可是在数控系统上面显示却不一样。

不知道是不是功能按键这部分在初始化到时候有什么差异?


下面是单片机的USB初始化部分 几乎没有修改,只是添加了键盘扫描和按键排序



/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/

#include "stc.h"
#include "usb_desc.h"

char code DEVICEDESC[18] =
{

    0x12,                   //bLength(18);                                                                描述符长度
    0x01,                   //bDescriptorType(Device);                设备描述符
    0x00,0x02,              //bcdUSB(2.00);
    0x00,                   //bDeviceClass(0);                                                由接口描述符定义
    0x00,                   //bDeviceSubClass0);                                        接口描述符定义
    0x00,                   //bDeviceProtocol(0);                                        接口描述符定义
    0x40,                   //bMaxPacketSize0(64);                                最大包大小为64字节
    0xd9,0x04,              //idVendor(34bf);                         VID                        04D9
    0x03,0x12,              //idProduct(ff03);                               PID                        1204
    0x20,0x01,              //bcdDevice(1.00);                  设备版本号                                REV_r                0100   
    0x01,                   //iManufacturer(1);                                                厂商字符串索引
    0x02,                   //iProduct(2);                                                                产品字符串索引
    0x00,                   //iSerialNumber(0);                                                序列号字符串索引
    0x01,                   //bNumConfigurations(1);                        配置描述符数量
       
};
       
       
       

char code CONFIGDESC[41] =
{
// 配置描述符       
    0x09,                   //bLength(9);                                                                                                描述符长度
    0x02,                   //bDescriptorType(Configuration);                配置描述符
    0x29,0x00,              //wTotalLength(41);                 配置描述符总长度  
    0x01,                   //bNumInterfaces(1);                接口数量  
    0x01,                   //bConfigurationValue(1);           配置值
    0x00,                   //iConfiguration(0);                配置字符串索引
    0x80,                   //bmAttributes(BUSPower);           自供电,不支持远程唤醒
    0x32,                   //MaxPower(100mA);                                                                        最大功耗 (100mA)
        // 接口描述符
    0x09,                   //bLength(9);                                                                                                描述符长度
    0x04,                   //bDescriptorType(Interface);                          接口描述符
    0x00,                   //bInterfaceNumber(0);                                                        接口编号  00
    0x00,                   //bAlternateSetting(0);                                                        备用设置
    0x02,                   //bNumEndpoints(2);                                                                        端点数量
    0x03,                   //bInterfaceClass(HID);                                                         HID类       
    0x01,                   //bInterfaceSubClass(Boot);
    0x01,                   //bInterfaceProtocol(Keyboard);      键盘协议
    0x00,                   //iInterface(0);                     接口字符串索引
// HID描述符       
    0x09,                   //bLength(9);                                                                                                 描述符长度
    0x21,                   //bDescriptorType(HID);                                                          HID描述符
    0x01,0x01,              //bcdHID(1.01);                                                                                          HID版本1.11
    0x00,                   //bCountryCode(0);                                                                                国家代码 (无)
    0x01,                   //bNumDescriptors(1);                        描述符数量
    0x22,                   //bDescriptorType(HID Report);                                报告描述符       
    0x41,0x00,              //wDescriptorLength(65);                                                        报告描述符长度       
// 端点描述符
    0x07,                   //bLength(7);                                                                                                        描述符长度
    0x05,                   //bDescriptorType(Endpoint);                                        端点描述符
    0x81,                   //bEndpointAddress(EndPoint1 as IN);        输入端点1       81
    0x03,                   //bmAttributes(Interrupt);                                                中断传输
    0x08,0x00,              //wMaxPacketSize(8);                                                                        最大包大小为8字节       
    0x0a,                   //bInterval(10ms);                                                                                轮询间隔 (10ms)
// 端点描述符
    0x07,                   //bLength(7);                                                                                                        描述符长度
    0x05,                   //bDescriptorType(Endpoint);                                        端点描述符       
    0x01,                   //bEndpointAddress(EndPoint1 as OUT); 输出端点1  01
    0x03,                   //bmAttributes(Interrupt);                                                中断传输
    0x01,0x00,              //wMaxPacketSize(1);                                                                        最大包大小为1字节               
    0x0a,                   //bInterval(10ms);                    轮询间隔 (10ms)
};

/*
Input Report:
0   Modifierkeys (D0:LCtrl D1:LShift D2:LAlt D3:LGui D4:RCtrl D5:RShift D6:RAlt D7:RGui)
1        Reserved
2        Keycode 1
3        Keycode 2
4        Keycode 3
5        Keycode 4
6        Keycode 5
7        Keycode 6
Output Report:
0   LEDs (D0:NumLock D1:CapLock D2:ScrollLock)
*/

char code HIDREPORTDESC[65] =
{
    0x05,0x01,              //USAGE_PAGE(Generic Desktop);                表示用途页为通用桌面设备       
    0x09,0x06,              //USAGE(Keyboard);                                                                表示用途为键盘
    0xa1,0x01,              //COLLECTION(Application);                                表示应用集合,必须要以 END_COLLECTION 来结束它
       
                //(功能按键)
    0x05,0x07,              //  USAGE_PAGE(Keyboard);
    0x19,0xe0,              //  USAGE_MINIMUM(224);
    0x29,0xe7,              //  USAGE_MAXIMUM(255);
    0x15,0x00,              //  LOGICAL_MINIMUM(0);
    0x25,0x01,              //  LOGICAL_MAXIMUM(1);
    0x75,0x01,              //  REPORT_SIZE(1);             功能按键一个字节
    0x95,0x08,              //  REPORT_COUNT(8);            共=8个按键
    0x81,0x02,              //  INPUT(Data,Variable,Absolute);
   
    0x75,0x08,              //  REPORT_SIZE(8);
    0x95,0x01,              //  REPORT_COUNT(1);
    0x81,0x01,              //  INPUT(Constant);
   
    0x19,0x00,              //  USAGE_MINIMUM(0);
    0x29,0x65,              //  USAGE_MAXIMUM(101);
    0x15,0x00,              //  LOGICAL_MINIMUM(0);
    0x25,0x65,              //  LOGICAL_MAXIMUM(101);
    0x75,0x08,              //  REPORT_SIZE(8);              
    0x95,0x06,              //  REPORT_COUNT(6);
    0x81,0x00,              //  INPUT(Data,Array);
               

               
    0x05,0x08,              //  USAGE_PAGE(LEDs);
    0x19,0x01,              //  USAGE_MINIMUM(1);
    0x29,0x03,              //  USAGE_MAXIMUM(3);
    0x15,0x00,              //  LOGICAL_MINIMUM(0);
    0x25,0x01,              //  LOGICAL_MAXIMUM(1);
    0x75,0x01,              //  REPORT_SIZE(1);
    0x95,0x03,              //  REPORT_COUNT(3);
    0x91,0x02,              //  OUTPUT(Data,Variable,Absolute);
   
    0x75,0x05,              //  REPORT_SIZE(5);
    0x95,0x01,              //  REPORT_COUNT(1);
    0x91,0x01,              //  OUTPUT(Constant);
   
    0xc0,                   //END_COLLECTION;
};

char code LANGIDDESC[4] =
{
    0x04,0x03,
    0x09,0x04,
};

char code MANUFACTDESC[14] =
{
    0x0e,0x03,
    'S',0,
    'y',0,
    's',0,
          't',0,
    'e',0,
    'm',0,
};

char code PRODUCTDESC[28] =
{
    0x1c,0x03,
    'U',0,
    'S',0,
    'B',0,
    ' ',0,
    'K',0,
    'e',0,
    'y',0,
    'b',0,
    'o',0,
    'a',0,
    'r',0,
    'd',0,
};

char code PACKET0[2] =
{
    0, 0,
};

char code PACKET1[2] =
{
    1, 0,
};

         




按键排序输出
                if(fKeyOK == 0)      //USB空闲 排序输出
                {
                        BYTE i;
                        BYTE j =0;
                        Keyout[0]=0;
                        Keyout[1]=0;
                        Keyout[2]=0;
                        Keyout[3]=0;
                        Keyout[4]=0;
                        Keyout[5]=0;
                       
                        //检查所有安静,被按下,写出
                       
                        for(  i=1; i<128;i++)
                        {
                          if( Keys > 0 )
                                {
                                          
                                                Keyout[j]        =        i        ;
                                    j++;
                                          
                                }
                                if(j==6) return;   //最多写出6个数据,其余的放弃
                        }
                       
                        if( Keyout[0] != Keyout[6]  ) {fKeyOK = 1;         Keyout[6]  = Keyout[0];}       
                        if( Keyout[1] != Keyout[7]  ) {fKeyOK = 1;         Keyout[7]  = Keyout[1];}
                        if( Keyout[2] != Keyout[8]  ) {fKeyOK = 1;         Keyout[8]  = Keyout[2];}
                        if( Keyout[3] != Keyout[9]  ) {fKeyOK = 1;         Keyout[9]  = Keyout[3];}
                        if( Keyout[4] != Keyout[10] ) {fKeyOK = 1;         Keyout[10] = Keyout[4];}
                        if( Keyout[5] != Keyout[11] ) {fKeyOK = 1;         Keyout[11] = Keyout[5];}
                        if( cKeyCode  != Keyout[11] ) {fKeyOK = 1;         Keyout[11] = cKeyCode ;}        //  字节0     修饰符字节的8个按键       
        }




下面的是USB HID、/PS2专用的键盘主控芯片的USB初始化文件,请大神帮忙参考一下,是哪里的问题

USB Keyboard Description
Device Descriptor:
Descriptor size: 0X12
Descriptor type: 0X01
USB Specification release number: 0X0110
Device class: 0X00
Device subclass: 0X00
Device Protocol: 0X00
Max package for Endpoint 0 0X08
Vendor ID: 0X1267
Product ID: 0X0101
Device Release number: 0X0100
Index of string descriptor describing manufacturer: 0X00
Index of string descriptor describing product: 0X00
Index of string descriptor describing the device’s serial number: 0X00
Number of possible configurations: 0X01



Configuration Descriptor:
Descriptor size: 0X09
Descriptor type: 0X02
Total length of data return for this configuration: 0X003B
Number of interfaces: 0X02
Value used to address this configuration: 0X01
Index of string descriptor describing this configuration: 0X00
Configuration characteristic: 0XA0
Maximum power consumption : 0X32



Interface Descriptor (Interface 0)
Descriptor size: 0X09
Descriptor type: 0X04
Number of this interface: 0X00
Alternate setting: 0X00
Number of endpoints used by this interface: 0X01
Class code: 0X03
Subclass code: 0X01
Protocol code : 0X01
Index of string descriptor describing this interface: 0X00
HID Descriptor
Descriptor size: 0X09
Descriptor type: 0X21
HID Specification release number: 0X0110
Country code: 0X00
Number of class descriptors: 0X01
Type of class descriptor: 0X22
Length of report descriptor: 0X0036
Endpoint Descriptor
Descriptor size: 0X07
Descriptor type: 0X05
Endpoint’s status: 0X81
Endpoint’s attributes: 0X03
Maximum package size of this endpoint: 0X08
Interval for polling endpoint for data transfers: 0X000A



Report Descriptor (Endpoint 1)
USAGE PAGE (GENERIC DESKTOP): 0X05 0x01
USAGE (KEYBOARD): 0X09 0X06
COLLECTION (APPLICATION): 0XA1 0X01
USAGE PAGE (PAGE#FOR LEDs): 0X05 0X08
USAGE MINIMUM (1): 0X19 0X01
USAGE MAXIMUM (3): 0X29 0X03
LOGICAL MINIMUM (0): 0X15 0X00
LOGICAL MAXIMUM (1): 0X25 0X01
REPORT SIZE (1): 0X75 0X01
REPORT COUNT (3): 0X95 0X03
OUTPUT (DATA,VARIABLE,ABSOLUTE): 0X91 0X02
REPORT COUNT (5): 0X95 0X05
OUTPUT (CONSTANT): 0X91 0X01
USAGE PAGE (KEY CODES): 0X05 0X07
USAGE MINIMUM (224): 0X19 0XE0
USAGE MAXIMUM (231): 0X29 0XE7
REPORT COUNT (8): 0X95 0X08
INPUT (DATA,VARIABLE,ABSOLUTE): 0X81 0X02
REPORT SIZE (8): 0X75 0X08
REPORT COUNT (1): 0X95 0X01
INPUT (CONSTANT): 0X81 0X01
USAGE MINIMUM (0): 0X19 0X00
USAGE MAXIMUM (91): 0X29 0X91
LOGICAL MAXIMUM (FF): 0X26 0XFF 0X00
REPORT COUNT (6): 0X95 0X06
INPUT (DATA, ARRAY): 0X81 0X00
END COLLECTION: 0XC0



Interface Descriptor (Interface 1)
Descriptor size: 0X09
Descriptor type: 0X04
Number of this interface: 0X01
Alternate setting: 0X00
Number of endpoints used by this interface: 0X01
Class code: 0X03
Subclass code: 0X00
Protocol code : 0X00
Index of string descriptor describing this interface: 0X00
HID Descriptor
Descriptor size: 0X09
Descriptor type: 0X21
HID Specification release number: 0X0110
Country code: 0X00
Number of class descriptors: 0X01
Type of class descriptor: 0X22
Length of report descriptor: 0X0032
Endpoint Descriptor
Descriptor size: 0X07
Descriptor type: 0X05
Endpoint’s status: 0X82
Endpoint’s attributes: 0X03
Maximum package size of this endpoint: 0X03
Interval for polling endpoint for data transfers: 0X000A



Report Descriptor (Endpoint 2)
USAGE PAGE (CONSUMER): 0X05 0X0C
USAGE (CONSUMER): 0X09 0X01
COLLECTION (APPLICATION): 0XA1 0X01
REPORT ID (01): 0X85 0X01
USAGE MINIMUM (00): 0X19 0X00
USAGE MAXIMUM (023C): 0X2A 0X3C 0X02
LOGICAL MINIMUM (0): 0X15 0X00
LOGICAL MAXIMUM (023C): 0X26 0X3C 0X02
REPORT COUNT (1): 0X95 0X01
REPORT SIZE(10): 0X75 0X10
INPUT (DATA,ARRAY,ABSOLUTE): 0X81 0X00
END COLLECTION: 0XC0
USAGE PAGE (GENERIC DESKTOP): 0X05 0X01
USAGE (SYSTEM CONTROL): 0X09 0X80
COLLECTION (APPLICATION): 0XA1 0X01
REPORT ID (2): 0X85 0X02
USAGE MINIMUM (81): 0X19 0X81
USAGE MAXIMUM (83): 0X29 0X83
LOGIC MAXIMUM (1): 0X25 0X01
REPORT SIZE (1): 0X75 0X01
REPORT COUNT (3): 0X95 0X03
INPUT (DATA,VARIABLE,ABSOLUTE): 0X81 0X02
REPORT COUNT (5): 0X95 0X05
INPUT (CONSTANT): 0X81 0X01
END COLLECTION: 0XC0





截图202603291734319522.jpg






回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:366
  • 最近打卡:2026-03-31 16:31:44

844

主题

1万

回帖

2万

积分

管理员

积分
22789
发表于 3 天前 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:491
  • 最近打卡:2026-03-31 08:56:02
已绑定手机

104

主题

4219

回帖

9371

积分

荣誉版主

无情的代码机器

积分
9371
发表于 3 天前 | 显示全部楼层
同一个键表现差异优先对比键盘发出的报文差异

可以用bus hound或者usb抓包硬件

其次就是两个键盘设备在系统中识别的驱动差异
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:206
  • 最近打卡:2026-04-01 00:01:42
已绑定手机

15

主题

266

回帖

1450

积分

金牌会员

DIY玩家

积分
1450
发表于 3 天前 | 显示全部楼层
数控设备和普通电脑驱动可能有差异
数控设备驱动程序可能较严格
真正的学徒往往怀着大师的心
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-03-31 22:13:49
已绑定手机

2

主题

9

回帖

40

积分

新手上路

积分
40
发表于 前天 08:56 | 显示全部楼层
为已经用好几个键盘软件试过,数据是一样的,刚才特意用抓包软件抓包对比过

键盘1.jpg 键盘2jpg.jpg

这俩个是用HID Assist监听的,对比一致的
下面是用Bus Hound监听的,数据对比也是一致的
键盘3jpg.jpg 截图202603300851313457.jpg







现在的问题是在电脑上面测试都一样的。我 用WIN7旗舰版     WIN10家庭板    WIN11的系统都测试过,都正常使用的。
但是再数控系统上不一样的。感觉肯定是有差异的,但是找不出来哪里的差异。目前只是怀疑是不是初始化的时候有什么不一样?

截图202603300851531607.jpg










回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-03-31 22:13:49
已绑定手机

2

主题

9

回帖

40

积分

新手上路

积分
40
发表于 前天 09:00 | 显示全部楼层










刚才上传的图片上并排放置的,好像没有传输成功

键盘1.jpg
键盘2jpg.jpg
键盘3jpg.jpg
键盘4jpg.jpg
键盘6jpg.jpg

点评

报文一样就对比下在数控电脑上识别的驱动差异 用usb tree view 对比两者描述符差异 pid vid改成一样的试下加载同样驱动。 [attachimg]134671[/attachimg]  详情 回复 发表于 前天 09:06
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:491
  • 最近打卡:2026-03-31 08:56:02
已绑定手机

104

主题

4219

回帖

9371

积分

荣誉版主

无情的代码机器

积分
9371
发表于 前天 09:06 | 显示全部楼层
dczn*** 发表于 2026-3-30 09:00
刚才上传的图片上并排放置的,好像没有传输成功

报文一样就对比下在数控电脑上识别的驱动差异
用usb tree view 对比两者描述符差异
pid vid改成一样的试下加载同样驱动。


截图202603300904566892.jpg

UsbTreeView_x64.zip (481.97 KB, 下载次数: 1)
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-03-31 22:13:49
已绑定手机

2

主题

9

回帖

40

积分

新手上路

积分
40
发表于 前天 09:12 | 显示全部楼层
数控电脑是封闭的系统,我们没有办法去安装软件或者查看驱动差异。

点评

上USB协议分析仪,抓完整USB描述符。 尽量搞成一样的,主机只能根据描述符里的内容分配驱动。  详情 回复 发表于 前天 09:27
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:491
  • 最近打卡:2026-03-31 08:56:02
已绑定手机

104

主题

4219

回帖

9371

积分

荣誉版主

无情的代码机器

积分
9371
发表于 前天 09:27 | 显示全部楼层
dczn*** 发表于 2026-3-30 09:12
数控电脑是封闭的系统,我们没有办法去安装软件或者查看驱动差异。

上USB协议分析仪,抓完整USB描述符。
尽量搞成一样的,主机只能根据描述符里的内容分配驱动。

三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-03-31 22:13:49
已绑定手机

2

主题

9

回帖

40

积分

新手上路

积分
40
发表于 前天 09:28 | 显示全部楼层
现在就是能不能用我上面提供的标准键盘的描述符,我试一下,看是不是驱动的问题。我也怀疑是数控系统的驱动问题,但是数控系统我们没办法升级他的驱动。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-1 08:58 , Processed in 0.133020 second(s), 85 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表