STM32 keyboard USB键盘功能的实现
来源:互联网 发布时间:2018-08-02 分享至微信


下面编写下USB键盘的程序,依然在CustomHID工程上修改。


依旧最先修改的是usb_desc.c文件。我们从设备描述符开始讲述。


设备描述符需要修改下bMaxPacketSize(最大包长度)域为0x08,因为被本次的工程最大通讯长度就是8字节,正好符合USB规范,所以这里改成0x08,还要注意在usb_prop.c的DEVICE_PROP Device_Property结构体里注册的最大长度也要是0x08,与设备描述符的要相同(我们在下文说到)。这里最好还要修改下PID和VID的域的值,以防该PID和VID对应的设备已经在电脑里有了驱动而导致功能不正常。


/* USB标准设备描述符*/


const uint8_t Keyboard_DeviceDescriptor[KEYBOARD_SIZ_DEVICE_DESC] =


{


0x12, /*bLength:长度,设备描述符的长度为18字节*/


USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType:类型,设备描述符的编号是0x01*/


0x00, /*bcdUSB:所使用的USB版本为2.0*/


0x02,


0x00, /*bDeviceClass:设备所使用的类代码*/


0x00, /*bDeviceSubClass:设备所使用的子类代码*/


0x00, /*bDeviceProtocol:设备所使用的协议*/


0x08, /*bMaxPacketSize:最大包长度为8字节*/


0x78, /*idVendor:厂商ID为0x7788*/


0x67,


0x12, /*idProduct:产品ID为0x1122*/


0x01,


0x00, /*bcdDevice:设备的版本号为2.00*/


0x02,


1, /*iManufacturer:厂商字符串的索引*/


2, /*iProduct:产品字符串的索引*/


3, /*iSerialNumber:设备的序列号字符串索引*/


0x01 /*bNumConfiguration:设备有1种配置*/


}; /* keyboard设备描述符 */




接下去修改下配置描述符。找到接口的描述符的bNumEndpoints(该接口所使用的端点数)域,不用修改,但需要提下,还是0x02,表示使用2个端点。修改下接口描述符的nInterfaceProtocol (该接口使用的协议)域为0x01,表示是键盘。在输入端点描述符中端点设置端点1为为中断传输的输入端点,设置 wMaxPacketSize:(该端点支持的最大包长度)域的值为0x08,因为本次键盘的工程需要向USB主机发送8字节。在输出端点描述符设置端点1为中断传输的输出端点,设置为中断传输设置 wMaxPacketSize:(该端点支持的最大包长度)域的值为0x01,因为USB主机只会向USB从设备发送1个字节。


/* USB配置描述符集合(配置、接口、端点、类、厂商)(Configuration, Interface, Endpoint, Class, Vendor */


const uint8_t Keyboard_ConfigDescriptor[KEYBOARD_SIZ_CONFIG_DESC] =


{


0x09, /*bLength:长度,设备字符串的长度为9字节*/


USB_CONFIGURATION_DESCRIPTOR_TYPE, /*bDescriptorType:类型,配置描述符的类型编号为0x2*/


KEYBOARD_SIZ_CONFIG_DESC, /*wTotalLength:配置描述符的总长度为41字节*/


0x00,


0x01, /*bNumInterfaces:配置所支持的接口数量1个*/


0x01, /*bConfigurationValue:该配置的值*/


0x00, /*iConfiguration:该配置的字符串的索引值,该值为0表示没有字符串*/


0xC0, /* bmAttributes:设备的一些特性,0xc0表示自供电,不支持远程唤醒


D7:保留必须为1,D6:是否自供电,D5:是否支持远程唤醒,D4~D0:保留设置为0*/


0x32, /*从总线上获得的最大电流为100mA */


// 0x96, /*MaxPower:设备需要从总线上获取多少电流,单位为2mA,0x96表示300mA*/




/************** 接口描述符****************/


/* 09 */


0x09, /*bLength:长度,接口描述符的长度为9字节 */


USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType:接口描述符的类型为0x4 */


0x00, /*bInterfaceNumber:该接口的编号*/


0x00, /*bAlternateSetting:该接口的备用编号 */


0x02, /*bNumEndpoints:该接口所使用的端点数*/


0x03, /*bInterfaceClass该接口所使用的类为HID*/


0x01, /*bInterfaceSubClass:该接口所用的子类 1=BOOT, 0=no boot */


0x01, /*nInterfaceProtocol :该接口使用的协议0=none, 1=keyboard, 2=mouse */


0, /*iInterface: 该接口字符串的索引 */




/*****************HID描述符 ********************/


/* 18 */


0x09, /*bLength: HID描述符的长度为9字节 */


HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID的描述符类型为0x21 */


0x10, /*bcdHID: HID协议的版本为1.1 */


0x01,


0x21, /*bCountryCode: 国家代号 */


0x01, /*bNumDescriptors: 下级描述符的数量*/


0x22, /*bDescriptorType:下级描述符的类型*/


KEYBOARD_SIZ_REPORT_DESC,/* wItemLength: 下一集描述符的长度*/


0x00,




/********************输入端点描述符******************/


/* 27 */


0x07, /* bLength: 端点描述符的长度为7字节*/


USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: 端点描述符的类型为0x05*/


0x81, /* bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/


0x03, /* bmAttributes: 端点的属性为为中断端点.


D0~D1表示传输类型:0(控制传输),1(等时传输),2(批量传输),3(中断传输)


非等时传输端点:D2~D7:保留为0


等时传输端点:


D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步)


D4~D5表示用途:0(数据端点),1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/


0x08, /* wMaxPacketSize: 该端点支持的最大包长度为8字节*/


0x00,


0x0A, /* bInterval: 轮询间隔(32ms) */




/********************输出端点描述符*******************/


/* 34 */


0x07, /* bLength: 端点描述符的长度为7字节*/


USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: 端点描述符的类型为0x05*/


0x01, /* bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/


0x03, /* bmAttributes: 端点的属性为为中断端点.


D0~D1表示传输类型:0(控制传输),1(等时传输),2(批量传输),3(中断传输)


非等时传输端点:D2~D7:保留为0


等时传输端点:


D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步)


D4~D5表示用途:0(数据端点),1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/


0x01, /* wMaxPacketSize: 该端点支持的最大包长度为字节*/


0x00,


0x0A, /* bInterval: 轮询间隔(32ms) */


/* 41 */


};




讲到报告描述符,得将报告描述符的整个替换掉。该报告描述符定义了8字节的输入域,第一个字节表示特殊件是否按下,键盘的特殊键包括:ctrl,shift,alt键等,该字节D0表示Ctrl键,D1表示Shift键,D2表示Alt键,其他位保留。第二个字节保留,固定值为0。第三个字节到第八个字节用来保存按键值,如果只有一个按键按下,则按键值保存在第三个字节,如果有两个或两个以上的按键按下,则依次保存在从第三字节开始的字节中,当然最多只能6个按键同时按下,超过6个键值,则不响应。报告描述符还定义了一个字节的输出域,该字节是是用来控制LED灯的,我们都知道键盘的上有几个LED灯,比如说大小写键的LED灯等,该字节的定义:D0:Num Lock D1:Cap Lock D2:Scroll Lock D3:Compose D4:Kana,由于我一直用笔记本电脑的键盘,所以我也只认识前三个键。在这个工程,我只做了Ctrl键、Shift键、Num Lock键,以及A键。


/* HID的报告描述符*/


/*定义了8字


[ 新闻来源:互联网,更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj]
存入云盘 收藏
举报
全部评论

暂无评论哦,快来评论一下吧!