关于使用STM32F103xx用作USBHID设备时的问题

151724   2009-9-28 22:13 楼主
我使用stm32F103RBT6,用来作一个读卡器。发现报告描述符的配置会影响产品的适应性。我开始时把报告描述符中的输入输出报告长度定义为64字节,基本上在所有电脑上都能正确识别,并能正确操作。但为了提高传传输速度,我把输入和输出的报告长度定义为280字节后,发现计算机都能识别,但有几台新的电脑虽然能识别,但不能正常读写。不知道是何原因。请高手解答,谢谢!!!源码如下:
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_config.h"
#include "hw_config.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* USB Standard Device Descriptor */
const u8 DeviceDescriptor[SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x10,                       /*bcdUSB USB1.1 */
    0x01,
    0x00,                       /*bDeviceClass*/
    0x00,                       /*bDeviceSubClass*/
    0x00,                       /*bDeviceProtocol*/
    0x40,                       /*bMaxPacketSize40*/
    ID_VENDOR_L,                /*idVendor (0x0483)这个是需要跟USB组织申请的ID号,表示厂商代号*/
    ID_VENDOR_H,
    ID_PRODUCT_L,               /*idProduct = 0x1010该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序*/
    ID_PRODUCT_H,
    0x00,                       /*bcdDevice rel. 1.00*/
    0x01,
    1,                          /*Index of string descriptor describing
                                              manufacturer */
    2,                          /*Index of string descriptor describing
                                             product*/
    3,                          /*Index of string descriptor describing the
                                             device serial number */
    0x01                        /*bNumConfigurations*/
  }
  ; /* DeviceDescriptor */

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 ConfigDescriptor[SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x01,         /*bNumInterfaces: 1 interface*/
    0x01,         /*bConfigurationValue: Configuration value*/
    0x00,         /*iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xA0,         /*bmAttributes: 总线供电,支持远程唤醒 */
    0xC8,         /*MaxPower 400 mA: this current is used for detecting Vbus*/
    /************** Descriptor of interface ****************/
    /* 09 */
    0x09,         /*bLength: Interface Descriptor size*/
    USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
    0x00,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/
    0x02,         /*bNumEndpoints*/
    0x03,         /*bInterfaceClass: HID*/
    0x00,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
    0x00,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
    0,            /*iInterface: Index of string descriptor*/
    /******************** Descriptor of HID ********************/
    /* 18 */
    0x09,         /*bLength: HID Descriptor size*/
    HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
    0x00,         /*bcdHID: HID Class Spec release number*/
    0x01,
    0x00,         /*bCountryCode: Hardware target country*/
    0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/
    0x22,         /*bDescriptorType*/
    SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
    0x00,
    /******************** Descriptor of  endpoint ********************/
    /* 27 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x81,          /*bEndpointAddress: Endpoint Address (IN)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    SEND_BUFFER_SIZE_L,          /*wMaxPacketSize: 280 Byte max */
    SEND_BUFFER_SIZE_H,
    0x0A,          /*bInterval: Polling Interval (10 ms)*/
    /* 34 */
    /******************** Descriptor of  endpoint ********************/
    /* 27 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x01,          /*bEndpointAddress: Endpoint Address (OUT)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    REC_BUFFER_SIZE_L,    /*wMaxPacketSize: 280 Byte max */
    REC_BUFFER_SIZE_H,
    0x0A,          /*bInterval: Polling Interval (10 ms)*/
    /* 34 */
  }
  ; /* ConfigDescriptor */
const u8 ReportDescriptor[SIZ_REPORT_DESC] =
  {
    0x05, 0xFF,                    // USAGE_PAGE(User define) Device Use=USAGE_PAGE*255+USAGE=0xff*255+USAGE
    0x09, 0x30,                    // USAGE(User define)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x01,                    // USAGE_PAGE(1)
    0x19, 0x00,                    //   USAGE_MINIMUM(0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM(255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x75, 0x10,                    //   REPORT_SIZE (16) (280 bytes=16*140 bits)
    0x95, SEND_BUFFER_SIZE_REP,        //   REPORT_COUNT (140)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x02,                    // USAGE_PAGE(2)
    0x19, 0x00,                    //   USAGE_MINIMUM (0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM (255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x95, 0x10,                    //   REPORT_COUNT (16)   (280 bytes=16*140 bits)

    0x75, REC_BUFFER_SIZE_REP,         //   REPORT_SIZE (140)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
  }; /* ReportDescriptor */
/* USB String Descriptors (optional) */
const u8 StringLangID[SIZ_STRING_LANGID] =
  {
    SIZ_STRING_LANGID,
    USB_STRING_DESCRIPTOR_TYPE,
    0x09,
    0x04
  }

回复评论 (8)

                                 没有高手分析一下吗?帮顶一下
点赞  2009-9-29 09:10
                                 把报告的长度增加,并不能提高速度。因为对于全速设备的中断端点,最快的传输速率只能达到1数据包/ms。
点赞  2009-10-8 23:01
USB 2.0协议里面说:
The maximum allowable interrupt data payload size is 64bytes or less for full-speed. High-speed endpoints are allowed maximum data payload sizes up to 1024 bytes.

280字节超过允许范围了。

要提高速度,改改这个吧:0x0A,          /*bInterval: Polling Interval (10 ms)*/
点赞  2009-10-9 10:37
                                 学习中,能说明下:0x0A,          /*bInterval: Polling Interval (10 ms)*/改这个为什么能提高速度吗
点赞  2009-10-11 09:02
Polling Interval :指示主机隔多少时间向设备请求数据

10ms就是每10ms主机会向设备发一个IN/OUT的TOKEN,就可以进行通信了。
点赞  2009-10-11 09:26
主要是通过usb hid传输协议的话,有些协议头和尾也占字节。所以扩大包处理起来比较方便。
有的计算机能用,有的计算机不能用。这好像只能说明计算机侧有问题。而不说明stm32 有问题。我们用实达的工控机,开始不能用。后来他们升级完工控机的bios后就能识别了。新的电脑按说应该是高速设备呀,为什么不能正常操作呢?只能说是全速设备了看来。
点赞  2009-10-19 16:25
我使用stm32F103RBT6,用来作一个读卡器。发现报告描述符的配置会影响产品的适应性。我开始时把报告描述符中的输入输出报告长度定义为64字节,基本上在所有电脑上都能正确识别,并能正确操作。但为了提高传传输速度, ...
楼主的方向好像错了,不知道你做的是什么读卡器?SD卡读卡器还是智能卡读卡器?如果是SD卡读卡器,应该使用USB Mass Storage协议,如果是智能卡读卡器,应该使用USB CCID协议。

USB HID的应用对象是那些速度很慢的人机交互接口,如键盘、鼠标等设备,它本身就不适合做高速的、大容量的数据传输。
点赞  2009-10-19 16:47
                                 也许是像读RFID卡(例如二代身份证)那样的读卡器吧……是用HID协议的。
点赞  2009-10-22 21:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复