经常看到一些USB设备采用HID设备类,这种设备使用时不需要另外安装驱动程序,使用起来非常方便,如我自己用的PIC单片机在线调试工具PIC KIT3和C8051F系列单片机在线调试工具U-EC5都是HID设备,还有日常生活中常用的读卡机、指纹考勤机等都经常设计成USB HID接口,HID设备直接插上电脑就可以使用,在后面章节中介绍的超酷实例—51系列单片机编程器 也是基于HID设备类的。 由于HID的数据包可以由报告描述符来定义,所以可以方便地由设计人员自己定义适合项目所要的数据包格式,这样就可以利用HID设备类实现大多数数据通讯的应用需求,更重要的一点是操作系统通常都自带了HID设备驱动程序,用户使用时不需要插入驱动光盘来安装驱动程序,使用起来非常方便。从这一节开始我们来介绍如何实现自定义USB HID设备类,一般自定义USB HID设备类一般都有PC端用户应用程序,所以我们还会讲到如果编写PC端应用程序来与自定义HID设备通讯,这一节先介绍如何编写自定义USB HID设备固件。 《USB鼠标实例》一节已经通过实验证明HID接口描述符中bInterfaceProtocol字段的值并不影响设备类型,而且查看协议得知只有1和2两种取值有具体含义,影响设备类型的是报告描述符,报告描述符的用途页(USAGE_PAGE)有厂商自定义(Vendor Defined Page)的选项,所以要实现自定义USB HID设备类,只需要在报告描述符里定义厂商自定义的描述符就可以了,我们在上一节实例的基础上修改报告描述符,修改内容如下:
以上报告描述符只定义了一个报告(数据包,包括输入和输出),所以没有报告ID,这个报告由64个字节组成。 但是这个自定义USB HID设备什么功能也没有,下面我们简单地实现一个功能:数据包前8个字节为命令(主机到设备)或状态(设备到主机),如果收到前八个字节是字符串“_SET_LED”,那后面紧跟的一个字节代表8个LED状态(每位代表一个LED的状态),如果收到的前八个字节是字符串“GET_TEXT”则代表要求设备返回一个字符串,此时设备应返回64个字节,前面八个字节仍为“GET_TEXT”代表返回LED状态,后面是返回的字符,以NULL结尾;如果设备返回数据包前八个字节为“KEY_STAT”,则代表设备返回按键状态,紧跟后面的一个字节低两位分别代表K1和K2的状态。继续修改main函数,内容如下:
测试: 由于目前还没有编写上位机应用程序,所以只能用常用的bus hound工具来测试,bus hound可以抓取USB设备枚举及数据交换过程中的数据包,并可向指定端点发送数据包。首先下载bus hound,我这里使用的是5.0版本。 A、编译并烧录上面的程序,然后打开BUS HOUND,点“Settings”按钮切换到设置页,将“Max Phase”的值设为64并点“Apply”按钮,这样BUS HOUND才能监控最多64个字节的数据流。 图1
B、插上烧好程序后的设备,点“Devices”按钮切换到Devices页,选中我们刚插入的硬件(要选“USB Root Hub”分支下的那个设备)
图2
C、点“Capture”按钮,切换到Capture页,确保右下角“Run”按钮被选中,这时分别按扩展板上的K1键和K2键,结果BUS HOUND捕捉到了一些数据,如下所示,前八个字符应该是“KEY_STAT”,第9个字符的低两位代表K1和K2状态,下图所示为K1按下时捕捉到的数据,其中Phase列的“DI”代表输入数据(设备到主机)
图3 D、点“Devices”按钮,切换到“Devices”页,再次选中我们的“USB人体学输入设备”,如图2所示,再点右下角的“Send Commands”按钮。 然后出现下面所示画面,选中“Endpoint”为2,“Direction”为Out的那项,“Data Length”的值填64,代表发送64个字节的数据,发送的数据前八个字节填“_SET_LED”,第九个字节填:AA,即二进制的10101010,意思是点这D1,D3,D5,D7, 然后点左上角的“Run”按钮,这只看到扩展板上的LED相就的灯被点这了(图5)。
图4
图5
E、重新设备前八字节为字符串“GET_TEXT”,然后点“Run”按钮,再切换到“Capture”页,可以看到返回了一些数据,前八字节仍为“GET_TEXT”,后面是:Easy usb 51 programer plus - usb.baiheee.com 。
图6
|