版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、用VC+实现USB接口读写数据的程序2009-08-15 11:55用VC+实现USB接口读写数据的程序 使用一个GUIDguidHID_1查找并打开一个USB设备 extern "C" int PASCAL SearchUSBDevice() HANDLE hUsb; int nCount, i, j;/标记同一设备个数 HDEVINFO hDevInfoSet; BOOL bResult; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL; memset(m_sysversion, 0, 20); GetSysVersion(
2、m_sysversion); / 检索相关GUID的USB设备总设备个数 if (!GetUSBList() return 0; / 取得一个该GUID相关的设备信息集句柄 hDevInfoSet = :SetupDiGetClassDevs(LPGUID)&guidHID_1,/GUID_CLASS_USB_DEVICE, / class GUID NULL, / 无关键字 NULL, / 不指定父窗口句柄 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); / 目前存在的设备 / 失败. if (hDevInfoSet = INVALID_HANDLE_
3、VALUE) return NULL; / 申请设备接口数据空间 nCount = 0; bResult = TRUE; for (i=0; i< 34; i+) bDeviceOpen = FALSE; memset(m_DeviceDesc, 0, 256); SP_DEVICE_INTERFACE_DATA ifdata; / 设备序号=0,1,2. 逐一测试设备接口,到失败为止 while (bResult) ifdata.cbSize = sizeof(ifdata); / 枚举符合该GUID的设备接口 bResult = :SetupDiEnumDeviceInterface
4、s( hDevInfoSet, / 设备信息集句柄 NULL, / 不需额外的设备描述 (LPGUID)&guidHID_1,/GUID_CLASS_USB_DEVICE, / GUID (ULONG)nCount, / 设备信息集里的设备序号 &ifdata); / 设备接口信息 if (bResult) ULONG predictedLength = 0; ULONG requiredLength = 0; / 取得该设备接口的细节(设备路径) bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, / 设备信息集句柄
5、 &ifdata, / 设备接口信息 NULL, / 设备接口细节(设备路径) 0, / 输出缓冲区大小 &requiredLength, / 不需计算输出缓冲区大小(直接用设定值) NULL); / 不需额外的设备描述 / 取得该设备接口的细节(设备路径) predictedLength=requiredLength; / if(pDetail) / / pDetail =NULL; / pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA):GlobalAlloc(LMEM_ZEROINIT, predictedLength); pDeta
6、il->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, / 设备信息集句柄 &ifdata, / 设备接口信息 pDetail, / 设备接口细节(设备路径) predictedLength, / 输出缓冲区大小 &requiredLength, / 不需计算输出缓冲区大小(直接用设定值) NULL); / 不需额外的设备描述 if (bResult) / 复制设备路径到输出缓冲区 /:strcpy(pszDe
7、vicePathnCount, pDetail->DevicePath); if (strcmp(m_sysversion, "winnt")=0) char ch18; for(i=0;i<17;i+) ch=*(pDetail->DevicePath+8+i); ch17='0' if (strcmp(ch,"vid_0471&pid_0666")=0)/比较版本号,防止意外出错 memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; memset( &WR
8、ITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, / no security TRUE, / explicit reset req FALSE, / initial event reset NULL ) ; / no name if (READ_OS.hEvent = NULL) break; WRITE_OS.hEvent = CreateEvent( NULL, / no security TRUE, / explicit reset req FALSE, / initial event rese
9、t NULL ) ; / no name if (NULL = WRITE_OS.hEvent) CloseHandle( READ_OS.hEvent ); break; hUsb=CreateFile(pDetail->DevicePath,/&guidHID_1,/ GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL/*| FILE_FLAG_OVERLAPPED*/, NULL); if (hUsb != NULL)
10、 / 比较定位找到的USB在哪个USB PORT上 char id30; memset(id, 0, 30); i=0; do id=*(pDetail->DevicePath+26+i); i+; while(id!='#'); id = '0' for (j=0; j<34; j+) if(strcmp(id, m_USBListj)=0) sprintf(m_DeviceDescj+1, "%s", pDetail->DevicePath); m_USBPositionMapnCount = j+1; break; C
11、loseHandle(hUsb); nCount+; / break; / 比较驱动版本 / 比较操作系统版本 else memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, / no security TRUE, / explicit reset req FALSE, / initial event reset NULL ) ; / no name if (READ_OS.h
12、Event = NULL) break; WRITE_OS.hEvent = CreateEvent( NULL, / no security TRUE, / explicit reset req FALSE, / initial event reset NULL ) ; / no name if (NULL = WRITE_OS.hEvent) CloseHandle( READ_OS.hEvent ); break; hUsb=CreateFile(pDetail->DevicePath,/&guidHID_1,/ GENERIC_READ|GENERIC_WRITE, FI
13、LE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL/*| FILE_FLAG_OVERLAPPED*/, NULL); if (hUsb != NULL) if(strcmp(pDetail->DevicePath, m_USBListj)=0) sprintf(m_DeviceDescj+1, "%s", pDetail->DevicePath); m_USBPositionMapnCount = j+1; break; CloseHandle(hUsb); nC
14、ount+; / break; / 释放设备接口数据空间 :GlobalFree(pDetail); / 关闭设备信息集句柄 :SetupDiDestroyDeviceInfoList(hDevInfoSet); iDeviceCount = nCount; return nCount; / 写 BOOL Writestr(char *buf,int buflen, int index) BOOL fWriteStat; DWORD dwErrorFlags; DWORD dwError; COMSTAT ComStat; char szError 10 ; DWORD ret; int le
15、n, i, j, packet; div_t div_result; BYTE sendpacket65; BYTE xorcode="0x00" if (m_gphdComindex = NULL) / no usb device(jk100c) return -1; div_result = div(buflen, 58); if (div_result.rem = 0) packet = div_result.quot; else packet = div_result.quot+1; for (i=0; i<packet; i+) memset(sendpac
16、ket, 0, 65); if(i=packet-1) / end packet if (div_result.rem = 0) len = 58; else len = div_result.rem; else len = 58; sendpacket0 = 0x13; sendpacket1 = 3+len; sendpacket2 = 0x01; sendpacket3 = packet*16+i+1; memcpy(sendpacket+4, buf+(i*58), len); for(j=0;j<len+3;j+) xorcode=sendpacketj+1; sendpack
17、etlen+4 = (char)xorcode; sendpacketlen+5 = 0x23; PurgeComm(m_gphdComindex,PURGE_RXCLEAR|PURGE_TXCLEAR); / Sleep(10); fWriteStat = WriteFile(m_gphdComindex, sendpacket, len+6,&ret, NULL); if (!fWriteStat) if(GetLastError() = ERROR_IO_PENDING) dwError = GetLastError(); / an error occurred, try to
18、recover wsprintf( szError, "nr <CE-%u>", dwError ) ; OutputDebugString(szError); ClearCommError(m_gphdComindex, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) wsprintf( szError, "nr <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); else / some other
19、error occurred ClearCommError(m_gphdComindex, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags > 0) wsprintf( szError, "nr <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); return FALSE; if (i != packet-1) / should be receive ack if (ReceivePacketAnswer(index) != 0) retur
20、n FALSE; return TRUE; / 读 int Readstr(char *buf,int nMaxLength, int index) BOOL fReadStat ; COMSTAT ComStat; DWORD dwErrorFlags; DWORD dwLength; DWORD dwError; char szError 10 ; if (fCOMMOpened=0) return FALSE; /串口未打开 / only try to read number of bytes in queue ClearCommError(m_gphdComindex, &dw
21、ErrorFlags, &ComStat) ; /dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ; dwLength=nMaxLength; if (dwLength > 0) if (olap=TRUE) fReadStat = ReadFile(m_gphdComindex,buf, dwLength, &dwLength,&READ_OS) ; if (!fReadStat) if (GetLastError() = ERROR_IO_PENDING) OutputDebugString(&quo
22、t;nrIO Pending"); while(!GetOverlappedResult(m_gphdComindex, &READ_OS, &dwLength, TRUE ) dwError = GetLastError(); if(dwError = ERROR_IO_INCOMPLETE) continue; else / an error occurred, try to recover ClearCommError(m_gphdComindex,&dwErrorFlags, &ComStat ) ; break; else / end-if
23、(GetLastError() = ERROR_IO_PENDING) / some other error occurred dwLength = 0 ; ClearCommError(m_gphdComindex, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) wsprintf( szError, "nr <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); / end-if (!fReadStat) / end-if (olap
24、=TRUE) else fReadStat = ReadFile( m_gphdComindex,buf, dwLength, &dwLength, NULL ) ; if (!fReadStat) dwError = GetLastError(); ClearCommError(m_gphdComindex,&dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) wsprintf( szError, "nr <CE-%u>", dwErrorFlags ) ; OutputDebugStr
25、ing(szError); PurgeComm(m_gphdComindex,PURGE_RXCLEAR|PURGE_TXCLEAR); return dwLength; 用VC+编写USB接口通讯程序摘要:详细介绍Visual C+ 6.0环境下利用Windows API(Application Program Interface)函数来实现与符合HID设备类的USB接口通讯,并给出了通信程序的部分代码。关键词:通用串行总线 人际接口设备 API VisualC+1 引言在USB出现之前,计算机的典型接
26、口有并行口(打印口)、串行口、鼠标口、键盘口、显示器口、游戏口及各种卡式接口(如声卡、网卡)等,与这些接口对应的有各种不同的电缆。在传输速度方面,这些接口都存在速度偏低的问题;在技术方面,这种设计容易产生I/O冲突。中断(IRQ)不够用,以及对于每一种新的外设都必须设计新的接口卡等缺点。当今的计算机外部设备,都在追求高速度和高通用型。USB接口适应了这种要求,并以其速度快,使用方便,成本低等优点,迅速得到了众多PC厂商和半导体厂商的大力支持,外设向USB过渡称为必然的趋势。但如果主机PC不知道如何与USB外设通信,那么这个USB外设一点用处都没有,人机接口设备(HID)类是Windows完全支
27、持的第一批USB设备类型中的一种。在运行Windows98或更高版本的PC机上,应用程序可以使用操作系统内置的驱动与HID通信,但与HID通信不像打开一个端口,设定几个参数,然后就可以读写数据那么简单。在应用程序能与HID交换数据之前,它先要找到设备,获取有关它的报告信息,为做到这些,应用程序必须通过访问通信API函数,使位于上层的应用程序与位于下层的设备驱动程序进行数据交换。应用程序可以使用任何能访问API函数的编程语言,C+是一种能访问API函数的功能强大的语言,本文将在VisualC+6.0环境下编写与USB设备通信的Windows程序。2 USB简介USB是由Intel,Co
28、mpaq,Digital,IBM,Microsoft,NEC,Northern Telecom等七家世界著名的计算机和通信公司共同推出的新一代接口标准,全称为Universal Serial Bus(通用串行总线)。它是为了解决日益增加的PC外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准,尤其当传输速率高达480Mbit/s的USB2.0规范面世后,USB应用更加广泛,它具有下属优点:(1)适用于多种外设,使它不需要为不同的外设准备不同的接口和协议;(2)Windows能自动检测到USB设备的热插拔,并自动配置;(3)PC机上的IRQ线非常紧缺,而U
29、SB设备并不需要设置端口和IRQ,故无论从用户使用的方便性,或从对资源的占用方面看,USB都很有优秀;(4)当接入一个USB设备时,全速USB接口可达12Mbit/s,考虑到状态,控制和出错信息,最大理论速度仍可达9.6Mbit/s,这是其他串行接口协议所不能比拟的,且USB也支持1.5Mbit/s的低速传输;、但是USB同样有缺点,诸如:协议复杂,编写设备驱动程序要考虑很多细节,以保证USB某些特性的透明性,但通过调用Win32的API函数与设备通信,或者说与内置的驱动程序通信,便没有必要去逐条理解复杂的协议。3 VC+实现与USB接口通信的实例Windows下,与USB外设的任何
30、通信需通过设备驱动,该驱动知道如何与系统的USB驱动和访问设备的应用程序通信,Windows包含应用程序与HID通信需要的各种信息,不需要再安装设备驱动。Win32的应用程序接口(API)函数,使得设备驱动能与应用程序之间相互通信,应用程序也不需要为了和USB设备通信去了解复杂的USB协议。下面用VisualC+编写应用程序调用API函数,从而简化了与硬件通信的过程。3.1 建立工程操作步骤如下:(1)在VC+6.0工作平台中打开File 菜单,选择New菜单命令,在对话框中选择Project选项,在左边列表框选择MFC AppWizard(exe),在Proje
31、ct name 文本编辑框中输入项目名USBPort,在Location文本编辑框中输入项目路径,单击OK按钮,进入MFC AppWizard。(2)在MFC AppWizard-Step1窗口中,选择Dialog based选项,不该变其他选项的缺省值(3)在MFC AppWizard-Step2 of 4窗口中,选择About box和3D controls复选框(4)在MFC AppWizard-Step3 of 4到Step4 of 4不
32、改变各个选项的缺省设置(5)进入New Project Information窗口,如果检查完全正确后,单击OK按钮即生成应用程序所需要的全部文件。通过上述操作便生成了基于对话框的工程USBPort。3.2 查找USB设备在应用程序能与HID交换数据之前,它先要找到设备,获取有关它的报告信息。首先找到连接到系统的HID是什么,然后检索信息,知道满足要求的属性。(1)添加成员函数。单击ClassView标签,选定CUSBPortDlg类,右击添加OnSearch消息响应函数,并增加私有类型成员变量,即字符串型变量strPath和strLog以及布尔类型变量bFoun
33、dDevice。(2)OnSearch函数调用API函数,HID类设备是通过GUID类型值作标识的,调用函数HidD_GetHidGuid颗获得HID设备的标识:Hidd_GetHidGuid(&guidHID);其中guidHID是指向GUID类型的指针,当函数返回后,它指向的内容就是HID类的GUID标识,GUID是16字节大小的结构,用来标识通信接口及类对象,它的定义为:typedef struct _GUIDDWORD Data1;WORD Data2;WORD Data3;BYTE
34、; Data48;GUID;调用函数HidD_GetHidGuid获得特定的HID设备属性BOOL HidD_GetAttributes(hCom,&strAttrib);其中hCom是对应与选定设备的句柄,根据这个句柄定所关心的设备,strAttrib则是指向HIDD_ATTRIBUTES类型的指针,当函数返回时即得到了指定设备的属性。HIDD_ATTRIBUTES结构定义为:typedef struct _HIDD_ATTRIBUTESULONG size;/这个HIDD_ATTRIBUTES变量大小,以字节为单位USHORT
35、60;vendorID;/致命HID设备的供应商标识USHORT ProductID;/致命HID设备的产品标识USHORT VersionNumber;/HID设备的版本号HIDD_ATTRIBUTES,*PHIDD_ATTRIBUTES;OnSearch函数中还调用了其他与硬件相关的API函数,这些函数都在Setupapi.h中定义。调用SetupDiGetClassDevs函数用来获得一类硬件设备的信息:HDEVINFO hDevInfo = SetupDiGetClassDevs(&guidHID,/这类设备配置或接口类GUID
36、NULL,/特定的字符串,用来选择符合条件的设备0,/与获得信息相关的顶层窗体(Top_Level Window)句柄DIGCF_PRESENT | DIGCF_DEVICEINTERFACE/给出了设置信息集的方式);调用SetupDiEnumDeviceInterfaces函数得到一个设备接口信息反复调用得到所有设备接口信息。若要找到特定设备,可在循环语句内调用该函数,直到找到预期设备或函数返回FALSE值。定义该函数:BOOL bSuccess = SetupDiEnumDeviceInterface(hDevInfo,/感兴趣
37、的接口句柄NULL,/指向SP_DEVINFO_DATA类型结构的指针,该结构限定了特定接口&gudiHID,/确定了接口的GUID标识0,/所关心的索引号,以0为起点&strInterfaceData,/指向SP_DEVINFO_INTERFACE_DATA类型的指针,它所指向的内容就是调用函数的目的所在,当函数返回时,strInterfaceData指向的结构就存在相关接口的信息。);其中结构SP_DEVINFO_DATA定义为:typedef struct _SP_DEVINFO_DATADWORD cbsize;/指定结构的大小GUID classGuid;/设备的GUID标识DWORD DevInst;/用来访问设备的句柄ULONG_PTR Reserved;SP_DEVINFO_DATA,*PSP_DEVINFO_DATA;结构SP_DEVICE_INTERFACE_DATA定义为typedef struct _SP_DEVICE_INTERFACE_DATADOWRD cbsize;/是SP_DEVICE_INTERFACE_DATA结构的大小GUID InterfaceClassGuid;/指定了接口的GUID标识DWORD
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 北师大版一年级下册数学第五单元 加与减(二) 测试卷及参考答案(黄金题型)
- 煤炭开采引发地质灾害调查报告(6篇)
- 关于大学生暑假实习心得
- 湖南省常德市2023-2024学年五年级上学期语文期末试卷(含答案)
- 解除租房合同需要哪些条件
- 诚信代理服务合同机构
- 诚恳道歉自白书
- 语文大专班试题
- 语文要素教学的策略与实践
- 购房合同中的交房时间
- JJG 393-2018便携式X、γ辐射周围剂量当量(率)仪和监测仪
- 交往与合作期末考试试题
- 城市管网建设行业市场前景分析与发展展望预测报告
- 办理退休委托书
- 《护士条例》全文
- 2024年中铁集装箱运输有限责任公司招聘笔试参考题库附带答案详解
- 2024中电建水电开发集团有限公司部分管理岗位社会招聘笔试参考题库附带答案详解
- 溜冰场运营方案
- 【智慧农业在农业生产经营的应用研究5000字】
- 信用卡纠纷个人民事答辩状(实用范本)
- 导数与微分的历史渊源
评论
0/150
提交评论