HID 修改包大小

本文记录利用STM32的USB设备以HID方式实现与PC的自定义包大小通信的上下位机开发过程.


关键字: USB, HID, HID读写,Report Descriptor


要解决的问题 : 假定某一串行通信协议, 命令的最大长度为64个字节, 而现在改用USB- HID方式来通信, 通信协议不变, 我们如何实现?


芯片: STM32F103ZE; 基础代码: 官方USB固件库V3.2.0; PC端工具: VS2005;调试工具: USBLyzer


适当修改官方固件库中的Custom_HID工程中与Board相差的配置, 然后编译运行, 便可以在设备管理器看到55970df6-73d9-4228-ad4e-915d36fe6850.JPG
HID已经识别成功了.


在该工程中, 实现了三个通信过程, 其中两个IN传输: ADC采样输入, 按钮输入; 一个属于OUT传输:LED灯控制;   每次传输两个字节, 一个数据和一个报告ID, 而在平常使用中, 大家总是希望通信过程能够模拟串口那种以多字节包的方式来输入和输出, 显然, 官方的示例并不能实现我们的目标。要实现目标, 我们动手修改源代码。。。。。


1、修改Endpoint Descriptor


官方代码中, 在CustomHID_ConfigDescriptor串末尾定义了两个Endpoint Descriptor,我们在它的基础上修改Endpoint 的最大传输字节。


   2、修改Endpoint 的最大接收与发送包大小


    在CustomHID_Reset函数中,修改语句以设置最大包:


SetEPTxCount();
SetEPRxCount();


3、修改Report Descriptor


要解决我们的问题, 我们仅需要实现两个Report , 一个IN, 一个OUT, 大小均是64个字节, 根据这些要求, 使用USB.ORG提示的HID   Descriptor TOOL生成Report Descriptor.


4、修改IN传输的函数:


__IO uint8_t Send_Buffer[65];
void vUSBSendBytes(void)
{
    uint8_t i;
    Send_Buffer[0] = 0x01;
    for(i = 1; i< 65; i++)
      {        
        Send_Buffer[i]++;
      }
    /* Write the descriptor through the endpoint */
    USB_SIL_Write(EP1_IN, (uint8_t*) Send_Buffer, 65);
}


5、修改IN传输的调用 函数


   在MAIN函数中改写while()循环


while (1)
{    
        Delay(20000000);
        vUSBSendBytes();     
}


至些, 与USB有关的修改已经结束, 接下来可以删除与本应用无关的代码, 如ADC\LED相关.


编译代码, 运行, 在USBlyzer可以看到以下信息



0909ddc1-3b5c-4294-96e5-faca33c2133c.JPG


IN传输成功完成, 下面开始编写上位机代码



     1、环境配置及头文件、库的包含


      环境: DDK或者WDK编译环境


      头文件包含:


extern "C" 
    {
        #include "setupapi.h"
        #include "hidsdi.h"
        #include "dbt.h"
    }


    库文件:


#pragma comment(lib,"hid.lib")
#pragma comment(lib,"setupapi.lib")


   2、设备发现


    查询HID设备的代码很多, 略


   特殊提示: 使用


                       HIDP_CAPS Capabilities;


                        PHIDP_PREPARSED_DATA PreparsedData;
                       HidD_GetPreparsedData(handle,&PreparsedData);
                       HidP_GetCaps (PreparsedData,&Capabilities);


可以获取HIDP_CAPS参数, 其参数结构如下:


typedef struct _HIDP_CAPS
{
    USAGE    Usage;
    USAGE    UsagePage;
    USHORT   InputReportByteLength;
    USHORT   OutputReportByteLength;
    USHORT   FeatureReportByteLength;
    USHORT   Reserved[17];


    USHORT   NumberLinkCollectionNodes;


    USHORT   NumberInputButtonCaps;
    USHORT   NumberInputValueCaps;
    USHORT   NumberInputDataIndices;


    USHORT   NumberOutputButtonCaps;
    USHORT   NumberOutputValueCaps;
    USHORT   NumberOutputDataIndices;


    USHORT   NumberFeatureButtonCaps;
    USHORT   NumberFeatureValueCaps;
    USHORT   NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;


其中关键参数 InputReportByteLength,OutputReportByteLength就是关键的IN与OUT包的大小, 在READ与WRITE函数调用时需要用到。


3、读写操作


    略, 仅提供示例函数:


   1) 读


    bRet = ReadFile(handle, rBuffer, 65, &dwRet, NULL);


2) 写


        wBuffer[0] = 0x02;//report id
        BOOL bRet = WriteFile(handle, wBuffer, 65, &dwRet, NULL);


至此, 我们就可以通过VC来完成对HID设备的读写操作了。 IN与OUT双向传输,最大包64个字节并可以随意修改,灵活吗?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值