HID-USB-通信
HID USB 通信
摘要:
详细介绍
Visual C ++ 6.0
环境下利用
Windows API(应用程序接口)
函数实现与符合
HID
设备类的
USB
接口通讯,并给出了通信程序的部分代码。
关键词:
通用串行总线人际接口设备
API VisualC ++
1
引言
在
USB
出现之前,计算机的典型接口有并行口(打印口),串行口,鼠标口,键盘口,显示器口,游戏口及各种卡式接口(如声卡,网卡)等,与这些接口对应的有各种不同的电缆在传输速度方面
,这些接口都存在速度偏低的问题;在技术方面,这种设计容易产生
I / O
。冲突中断
(IRQ)
不够用,以及对于每一种新的外设都必须设计新的接口卡等缺点
。当今的计算机外部设备,都在追求高速度和高通用型
。USB
接口适应了这种要求,并以其速度快,使用方便,成本低等优点,迅速得到了众多
PC
厂商和半导体厂商的大力支持,外设向
USB
过渡称为必然的趋势。
但如果主机
PC
不知道如何与
USB
外设通信,那么这个
USB
外设一点用处都没有,人机接口设备(
HID
)类是
Windows
完全支持的第一批
USB
设备类型中的一种。在运行
Windows98
或更高版本的
PC
机上,应用程序可以使用操作系统内置的驱动与
HID
通信,但与
HID
通信不像打开一个端口,设定几个参数,然后就可以读写数据那么简单。在应用程序能与
HID
交换数据之前,它先要找到设备,获取有关它的报告信息,为做到这些,应用程序必须通过访问通信
API
函数,使位于上层的应用程序与位于下层的设备驱动程序进行数据交换
。应用程序可以使用任何能访问
API
函数的编程语言,
C ++
是一种能访问
API
函数的功能强大的语言,本文将在
VisualC ++ 6.0
环境下编写与
USB
设备通信的
Windows
程序。
2 USB
简介
USB
是由
英特尔
,
康柏
,
数字
,
IBM
,
微软
,
NEC
,
北电网络
等七家世界着名的计算机和通信公司共同推出的新一代接口标准
,全称为
通用串行总线
(通用串行总线),它是为了解决日益增加的
PC
外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准,尤其是当传输速率高达
480Mbit / s
的
USB2.0
规范面世后,
USB
应用更加广泛,它具有下属优点:
(1)
适用于多种外设,使它不需要为不同的外设准备不同的接口和协议
;
(2)
Windows能够
自动检测到
USB
设备的热插拔,并自动配置;
(3)
PC
机上的
IRQ
线非常紧缺,而
USB
设备并不需要设置端口和
IRQ
,故无论从用户使用的方便性,或从对资源的占用方面看,
USB
都很有优秀;
(4)
当接入一个
USB
设备时,全速
USB
接口可达
12Mbit / s
,考虑到状态,控制和出错信息,最大理论速度仍可达
9.6Mbit / s
,这是其他串行接口协议所不能比拟的,且
USB
也支持
1.5Mbit / s
的低速传输;,
但是
USB
同样有缺点,诸如:协议复杂,编写设备驱动程序要考虑很多细节,以保证
USB
某些特性的透明性,但通过调用
Win32的的
的
API
函数与设备通信,或者说与内置的驱动程序通信,便没有必要去逐条理解复杂的协议
。
3 VC ++
实现与
USB
接口通信的实例
Windows
下,与
USB
外设的任何通信需要通过设备驱动,该驱动知道如何与系统的
USB
驱动和访问设备的应用程序通信,
Windows
包含应用程序与
HID
通信需要的各种信息,不需要再安装设备驱动。
的Win32的
应用程序接口(
API
)函数,使得设备驱动能与应用程序之间相互通信
,应用程序也不需要为了和
USB
设备通信去了解复杂的
USB
协议。
下面用
VISUALC ++编写
应用程序调用
API
函数,从而简化了与硬件通信的过程。
3.1
建立工程
操作步骤如下:
(1)
在
VC ++ 6.0
工作平台中打开
文件
菜单,选择
新
菜单命令,在对话框中选择
项目
选项,在左边列表框选择
MFC AppWizard(exe)
,在
项目名称中
输入项目名
USBPort
,在
位置
文本编辑框输入项目路径,单击
确定
按钮,进入
MFC AppWizard
。
(2)
在
MFC应用程序向导第一步
窗口中,选择
基于对话框的
选项对话,
不该
变其他选项对话的缺值
(3)
在
MFC AppWizard-Step2 of 4
窗口中,选择
关于框
和
3D控件
复选框
(4)
在
MFC AppWizard-Step3 of 4
到
Step4 of 4
不改变各个项目的缺省设置
(5)
展示展示进入
新项目信息
窗口显示显示,如果检查完全正确后,单击
OK
按钮即生成应用程序所需要的全部文件
。
通过上述操作便生成了基于对话框的工程
USBPort
。
3.2
查找
USB
设备
在应用程序能与
HID
交换数据之前,它先要找到设备,获取有关它的报告信息。首先找到连接到系统的
HID
是什么,然后检索信息,知道满足要求的属性。
(1)
添加成员函数。单击
ClassView
标签,选择
CUSBPortDlg
类,右击添加
OnSearch
消息响应函数,并增加私有类型成员变量,即字符串型变量
strPath
和
strLog
以及布尔类型变量
bFoundDevice
。
(2)
OnSearch
函数调用
API
函数,
HID
类设备是通过
GUID
类型值作标识的,调用函数
HidD_GetHidGuid
颗获得
HID
设备的标识:
Hidd_GetHidGuid(&guidHID)
;
其中
guidHID
是指向
GUID
类型的指针,当函数返回后,它指向的内容就是
HID
类的
GUID
标识,
GUID
是
16
字节大小的结构,用来标识通信接口及类对象,它的定义为:
typedef struct _GUID
{
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4 [8];
} GUID;
调用函数
HidD_GetHidGuid
获得特定的
HID
设备属性
BOOL HidD_GetAttributes(hCom,&strAttrib);
其中
hCom
是对应与选定设备的句柄,根据这个句柄定所关心的设备,
strAttrib
则是指向
HIDD_ATTRIBUTES
类型的指针,当函数返回时即得到了指定设备的属性。
HIDD_ATTRIBUTES
结构定义为:
typedef struct _HIDD_ATTRIBUTES
{
ULONG尺寸;
//
这个
HIDD_ATTRIBUTES
变量大小,以字节为单位
USHORT vendorID;
//
致命
HID
设备的供应商标识
USHORT ProductID;
//
致命
HID
设备的产品标识
USHORT VersionNumber;
// HID
设备的版本号
} HIDD_ATTRIBUTES,* PHIDD_ATTRIBUTES;
OnSearch
函数中还调用了其他与硬件相关的
API
函数,这些函数都在
Setupapi.h
。中定义调用
SetupDiGetClassDevs
函数
用来
获得一类硬件设备的信息
:
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&guidHID,//
这类设备配置或接口类
GUID
NULL,//
特定的字符串,用来选择符合条件的设备
0,//
与获得信息相关的顶层窗体(
Top_Level Window
)句柄
DIGCF_PRESENT |
DIGCF_DEVICEINTERFACE //给出
了设置信息集的方式
);
调用
SetupDiEnumDeviceInterfaces
函数得到一个设备接口信息反复调用得到所有设备接口信息
。若要找到特定设备,可在循环语句内调用该函数,直到找到预期设备或函数返回
FALSE
值。
定义该函数:
BOOL bSuccess = SetupDiEnumDeviceInterface(
HDEVINFO,//
感兴趣的接口句柄
NULL,//
指向
SP_DEVINFO_DATA
类型结构的指针,该结构限定了特定接口
&gudiHID,//
确定了接口的
GUID
标识
0,//
所关心的索引号,以
0
为起点
&strInterfaceData,//
指向
SP_DEVINFO_INTERFACE_DATA
类型的指针,
它所指向的内容就是调用函数的目的所在,当函数返回时,
strInterfaceData
指向的结构就存在相关接口的信息。
);
其中结构
SP_DEVINFO_DATA
定义为:
typedef struct _SP_DEVINFO_DATA {
DWORD cbsize;
//
指定结构的大小
GUID classGuid;
//
设备的
GUID
标识
DWORD DevInst;
//用来
访问设备的句柄
ULONG_PTR保留;
} SP_DEVINFO_DATA,* PSP_DEVINFO_DATA;
结构
SP_DEVICE_INTERFACE_DATA
定义为
typedef struct _SP_DEVICE_INTERFACE_DATA {
DOWRD cbsize;
//
是
SP_DEVICE_INTERFACE_DATA
结构的大小
GUID InterfaceClassGuid;
//
指定了接口的
GUID
标识
DWORD标志;
//
接口所处状态
ULONG_PTR保留;
} SP_DEVICE_INTERFACE_DATA,* PSP_DEVICE_INTERFACE_DATA;
3.3
与
USB
设备交换数据
在
Windows
中,读写端口与读写文件都是调用同样的
API
函数,打开或创建端口用
CreateFile
从端口读数据用
ReadFile
,向端口数据用
WriteFile
。
(1)
设备的打开和关闭,用
API
函数
的的CreateFile
来打开或创建设备:
HANDLE hCom = CreateFile(
m_strPath,//
指定打开设备名
GENERIC_READ |
GENERIC_WEITE,//
允许读写
0,//
独占方式
NULL,//
安全模式
OPEN_EXISTING,//
打开
FILE_ATTRIBUTE_NORMAL,//
文件属性
NULL //
临时文件的句柄
);
如果调用成功,该函数返回文件的句柄;如果调用失败,则返回
INVALID_HANDLE_VALUE
,在打开通信设备时,应该以独占方式打开。
不再使用设备句柄时,应该调用
CloseHandle的的(HCOM)
函数关闭它。
(2)
设备的读写操作,读写通信设备可用同步方式执行,也可用异步方式执行,由这
的的CreateFile
函数中是否指定
FILE_FLAG_OVERLAPPED
来决定;指定为异步方式,未指定则为同步方式,函数
ReadFile的的
状语从句:
WriteFile的的
的参数状语从句:报道查看值类型,的英文下面调用
的ReadFile的
函数的实例。
HANDLE hCom;
void * pBuffer;
DWORD iLength;
DWORD pReadFact;
BOOL ReadFile(hCom,pBuffer,iLength,&pReadFact,NULL);
读取的数据放在内存
p缓冲器
里,
p缓冲器
要先申请内存空间,
iLength
为需要读的数据长度,
pReadFact
存放实际读的数据长度。需要注意的是在读写设备之前,应先调用
ClearCommError
函数
清除
错误标志,此函数负责报告指定的错误的设备的当前状态
,调用
PrugeComm
函数可以更改正在进行的读写操作方式。
4
结论
以上是调用
的Win32
的
API
通信函数用
VC ++
编写的
USB
设备通信程序,它实现了查找符合
HID
类的
USB
设备并与之进行数据交换的基本功能
。这种独立与通信子系统之外实现的应用程序
,可以实现可靠的高速数据传输。对自定义设备,应用程序需要设备的特定供应商和产品
ID
,或设备的特定类型,读者只需要对上述程序作一定修改即可,在
MFC
环境下,
编写
32
位串口通信程序还可采用
的的的ActiveX
的
的的的MSComm
控件,但使用
API
通信函数,具有更大灵活性,可定制性也更强,在设置通信配置和发送错误敏感,无时间限制的数据时,该接口尤其有用。
下载实例