本帖最后由 缥缈九哥 于 2012-9-14 12:14 编辑
一、何为HID
USB HID类是比较大的一个类,HID类设备属于人机交互操作的设备。用于控制计算机操作的一些方面,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球、电话拨号设备、VCR遥控等等设备。另外,使用HID设备的一个好处就是,操作系统自带了HID类的驱动程序,而用户无需去开发很麻烦的驱动程序,只要直接使用API调用即可完成通信。所以很多简单的USB设备,喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。
二、USB HID类可采用的通信管道
所有的HID设备通过USB的控制管道(默认管道,即端点0)和中断管道与主机通信。
表1、USB HID规范定义的HID设备可用端点
| 管道
| 要求
| 说明
| 控制(端点0)
| 必须
| 传输USB描述符、类请求代码以及供查询的消息数据等
| 中断输入
| 必须
| 传输从设备到主机的输入数据
| 中断输出
| 可选
| 传输从主机到设备的输出数据
|
控制管道主要用于以下3个方面:
- 接收/响应USB主机的控制请示及相关的类数据
- 在USB主机查询时传输数据(如响应Get_Report请求等)
- 接收USB主机的数据
中断管道主要用于以下两个方面:
- USB主机接收USB设备的异步传输数据
- USB主机发送有实时性要求的数据给USB设备
从USB主机到USB设备的中断输出数据传输是可选的,当不支持中断输出数据传输时,USB主机通过控制管道将数据传输给USB设备。
三、与USB HID设备有关的描述符
HID设备的描述符除了5个USB的标准描述符(设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符)外,还包括3个HID设备类特定描述符:HID描述符、报告描述符、实体描述符。
同本程相关的是实体描述符
实体描述符被用来描述设备的行为特性。实体描述符是可选的描述符,HID设备可以根据其本体的设备特性选择是否包含实体描述符。表2所示为HID的实体描述符结构。
表2、HID实体描述符的结构
| 偏移量
| 域
| 大小
| 说明
| 0
| bDesignator
| 1
| 用来指定本体的哪一部分影响项目(含义见表6)
| 1
| bFlags
| 1
| 位指定标志
位0~4:Effort
位5~7:Qualifier(含义见表7)
|
下边说下程序:
程序是通过表来实现交互的
这个程序编译后下到开发板,然后把USBA口插入,这时在系统硬件设备中,出现了一个人体设备,这说明程序运行正常。
硬件初始化完成后,执行函数DrvUSB_Open() 来为HID设备初始化USB端点信息结构,现在系统准备好使能中断并等待插入USB主机。插入USB主机后,USB状态将从eDRVUSB_DETACHED 变为eDRVUSB_ATTACHED ,插入主机后执行函数HID_Init 来初始化HID供应商描述符为HID键盘或者HID鼠标。当我按KEY1键时光标无论在哪都向右移动,按一下动一下。
下边贴下主要函数,其实它就是个小人,总是向主机打小报告,这样的人还真有,没有程序就坏菜了
int32_t HID_MainProcess(void)
{
int32_t i32Ret = 0;
E_DRVUSB_STATE eUsbState;
GPIOB->IEN = (1 << 15);
NVIC_EnableIRQ(EINT1_IRQn);
i32Ret = DrvUSB_Open((void *)DrvUSB_DispatchEvent);
if(i32Ret != 0)
return i32Ret;
while(1)
{
/* Disable USB-related interrupts. */
_DRVUSB_ENABLE_MISC_INT(0);
/* Enable float-detection interrupt. */
_DRVUSB_ENABLE_FLDET_INT();
/* Start HID and install the callback functions to handle in/out report */
HID_Init();
/* Enable USB-related interrupts. */
_DRVUSB_ENABLE_MISC_INT(INTEN_WAKEUP | INTEN_WAKEUPEN | INTEN_FLDET | INTEN_USB | INTEN_BUS);
/* Enter power down to wait USB attached */
PowerDown();
/* Poll and handle USB events. */
while(1)
{
eUsbState = DrvUSB_GetUsbState();
if (eUsbState == eDRVUSB_DETACHED)
{
DBG_PRINTF("USB Detached!\n");
break;
}
if(eUsbState & eDRVUSB_SUSPENDED)
{
/* Enter suspend here */
PowerDown();
}
if (eUsbState == eDRVUSB_CONFIGURED)
{
/* Set HID IN report for interrupt IN transfer */
HID_SetInReport();
}
}
/* Disable USB-related interrupts. */
_DRVUSB_ENABLE_MISC_INT(0);
}
}
程序打包
|