原创 智林开发板上实现自定义的USB HID设备

2010-5-4 21:01 8954 14 14 分类: MCU/ 嵌入式

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 


一、自定义HID设备的相关概念


1HID设备


HID设备的直译是指“人机接口设备”,但实际上HID设备并不需要一定有人机接口。只要是主机与设备之间数据交换格式满足一定的要求,都可以使用人机接口类别来实现。


HID设备实现的数据交换的特征:


1交换的数据用报表描述符描述其格式,主机和设备以描述符约定的格式交换数据。


2)数据传输速率较低。


 


鼠标、键盘都是windows系统标准的“HID设备”,这样的设备在主机端甚至都不需要编写应用程序。


但是我们在控制系统中,将开发板做成一个HID设备,肯定是要PC与开发板之间交换一些特殊的控制和配置数据,而不是为了把开发板做成一个键盘或鼠标。


 


要达到这样的目的,可以使用自定义的“HID设备”。


 


2、自定义HID设备


实际上,要让主机将设备视为一个“自定义的HID设备”,很简单,只要在“接口描述符”指定“HID类别”,而在“报告描述符”里不指明具体用途页就行了。


下面是接口描述符:


 


    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,         /*这个设为0*/


    0x00,         /*这个也设为0,非0情况一般用于键盘和鼠标启动/


    0,            /*iInterface: Index of string descriptor*/


 


下面是报告描述符的开端:


 


    0x05,  0x01,        /*Usage Page(Generic Desktop)*/


    0x09,        


 //  0x06,   /*Usage(键盘)*/


    0x00,      //06改为00后,该设备就成为一个自定义的HID设备。


    0xA1,          /*Collection(Logical)*/


    0x01,


在以下对“报告”组成的元素描述过程中,也不要出现与“特定用途页”相关的性质定义。具体格式如下


    0x15,  0x00,        /*Logical Minimum(0)*/


    0x25,  0x01,        /*Logical Maximum(1)*/


    0x19,  0x01,        /*Usage Minimum(1)*/


    0x29,  0x08,        /*Usage Maximum(8)*/


    0x95,  0x08,        /*Report Count(8)*/


    0x75,  0x01,        /*Report Size(1)*/ //每个1位,加起来一个字节。


    0x81, 0x02,         /*Input(Variable)*/


   如果是一个数据要占据8位,则逻辑最大值设为0xFF,报告大小设置为8位就行了。


 


“自定义HID设备”报告的发送和接收与“USB鼠标”、“USB键盘”类似,只是此时主机方对输入报告的处理、输出报告的发送就需要用户字节编写应用程序了。


 


二、主机应用程序的编写


1、目的


1)应用程序能反映智林开发板上的按键的状态


2)应用程序能够控制开发板上的一个灯


 


2、实现过程


我对于PC上的编程现在已经很生疏了,以前经常用VB编程,VC学过但没用过。我现在也没有学VC编程的计划,因此上位机编程就在“圈圈光盘上给的代码”基础上修改


 


1)需要修改点


我把VID设为8888PID设为6666PVN设为0200


我的报告描述符:输入两个字节第一个字节的每个位代表开发板按键状态BIT0-4代表五向摇杆,BIT5代表PB2按键,PB6-7未用。第二个字节本来我想将开发板上电位器的采用数值发给主机显示,但是ADC的设置上要花费较多功夫,以后用到AD的时候再学习吧。


输出一个字节,BIT0控制开发板上的灯,其它未用。


 


 


2)默认厂商号、产品号的修改


 


      //初始化VIDPIDPVN数据区


      SetDlgItemText(IDC_VID_EDIT,"8888");


      SetDlgItemText(IDC_PID_EDIT,"6666");


      SetDlgItemText(IDC_PVN_EDIT,"0200");


这个在CMyUsbHidTestAppDlg::OnShowWindow(BOOL bShow, UINT nStatus)函数中,窗口显示前的设置。


 


 


3)接收报告的处理,改为接收3个字节的报告


      //如果字节数为9,则说明获取到了正确的9字节报告


             if(Length==3)


             {


             //第一字节为报告ID,应该为0


                    if(ReadReportBuffer[0]==0)


                           {


                                  //第二字节为按键状态,将其保存到KeyStatus中。


                                  KeyStatus=ReadReportBuffer[1];


                                  //刷新按键的情况。


                                  pAppDlg->SetKeyStatus();


      //3456字节为设备返回的发送次数值。计算出值后并显示。


                                  Counter=0;


                                  Counter=ReadReportBuffer[2];


                                  pAppDlg->SetCounterNumber(Counter);


                           }


                    }


 


4)发送报告的处理,每次发送2个数据,第一个字节为报告ID=0


      //设置要发送报告的数据


      WriteReportBuffer[0]=0x00;   //报告ID0


      WriteReportBuffer[1]=LedStatus;      //控制LED的状态。


      //显示发送数据的信息


      AddToInfOut("发送输出报告2字节");


      Str="";


      for(i=0;i<2;i++)


      {


             Str+=itos(WriteReportBuffer,16).Right(2)+" ";


      }


 AddToInfOut(Str,FALSE);


 


//调用WriteFile函数发送数据


      Result=WriteFile(hWriteHandle, WriteReportBuffer, 2, NULL, &WriteOverlapped);


 


 


程序编译,运行,以下是按下“OK”键的效果,它的按键编号为“4”。实际为第5个按键。


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


 

6d7fd7c5-b51c-437f-bcae-bb0ec43cf21b.jpg


 


 


 


 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
14
关闭 站长推荐上一条 /2 下一条