HID USB 通信

摘要:详细介绍Visual C ++ 6.0 环境下利用Windows API(应用程序接口)函数实现与符合HID 设备类的USB 接口通讯,并给出了通信程序的部分代码。

关键词:通用串行总线人际接口设备  API VisualC ++

引言

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 函数可以更改正在进行的读写操作方式。

结论

以上是调用的Win32 API 通信函数用VC ++ 编写的USB 设备通信程序,它实现了查找符合HID 类的USB 设备并与之进行数据交换的基本功能。这种独立与通信子系统之外实现的应用程序,可以实现可靠的高速数据传输。对自定义设备,应用程序需要设备的特定供应商和产品ID ,或设备的特定类型,读者只需要对上述程序作一定修改即可,在MFC 环境下,编写32 位串口通信程序还可采用的的的ActiveX 的的的MSComm 控件,但使用API 通信函数,具有更大灵活性,可定制性也更强,在设置通信配置和发送错误敏感,无时间限制的数据时,该接口尤其有用。


下载实例 点击打开链接

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值