用VC++实现USB接口读写数据的程序

合集下载

用VC++实现USB接口读写数据的程序

用VC++实现USB接口读写数据的程序

用VC++实现USB接口读写数据的程序用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(m_sysversion);// 检索相关GUID的USB设备总设备个数if (!GetUSBList()){return 0;}// 取得一个该GUID相关的设备信息集句柄hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUIDNULL, // 无关键字NULL, // 不指定父窗口句柄DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备// 失败...if (hDevInfoSet == INVALID_HANDLE_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 = ::SetupDiEnumDeviceInterfaces(hDevInfoSet, // 设备信息集句柄NULL, // 不需额外的设备描述(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID(ULONG)nCount, // 设备信息集里的设备序号&ifdata); // 设备接口信息if (bResult){ULONG predictedLength = 0;ULONG requiredLength = 0;// 取得该设备接口的细节(设备路径)bResult = SetupDiGetInterfaceDeviceDetail(hDevInfoSet, // 设备信息集句柄&ifdata, // 设备接口信息NULL, // 设备接口细节(设备路径)0, // 输出缓冲区大小&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)NULL); // 不需额外的设备描述// 取得该设备接口的细节(设备路径)predictedLength=requiredLength;// if(pDetail)// {// pDetail =NULL;// }pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);bResult = SetupDiGetInterfaceDeviceDetail(hDevInfoSet, // 设备信息集句柄&ifdata, // 设备接口信息pDetail, // 设备接口细节(设备路径)predictedLength, // 输出缓冲区大小&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)NULL); // 不需额外的设备描述if (bResult){// 复制设备路径到输出缓冲区//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);if (strcmp(m_sysversion, "winnt")==0){char ch[18];for(i=0;i<17;i++){ch=*(pDetail->DevicePath+8+i);}ch[17]='\0';if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错{memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;READ_OS.hEvent = CreateEvent( NULL, // no securityTRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (READ_OS.hEvent == NULL){break;}WRITE_OS.hEvent = CreateEvent( NULL, // no securityTRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (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){// 比较定位找到的USB在哪个USB PORT上char id[30];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_USBList[j])==0){sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath); m_USBPositionMap[nCount] = j+1;break;}}CloseHandle(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 reqFALSE, // initial event resetNULL ) ; // no nameif (READ_OS.hEvent == NULL){break;}WRITE_OS.hEvent = CreateEvent( NULL, // no securityTRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (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){if(strcmp(pDetail->DevicePath, m_USBList[j])==0){sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath); m_USBPositionMap[nCount] = j+1;break;}CloseHandle(hUsb);nCount++;// 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 len, i, j, packet;div_t div_result;BYTE sendpacket[65];BYTE xorcode="0x00";if (m_gphdCom[index] == 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(sendpacket, 0, 65);if(i==packet-1){// end packetif (div_result.rem == 0){len = 58;}else{len = div_result.rem;}}else{len = 58;}sendpacket[0] = 0x13;sendpacket[1] = 3+len;sendpacket[2] = 0x01;sendpacket[3] = packet*16+i+1;memcpy(sendpacket+4, buf+(i*58), len);for(j=0;j<len+3;j++){xorcode^=sendpacket[j+1];}sendpacket[len+4] = (char)xorcode;sendpacket[len+5] = 0x23;PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);// Sleep(10);fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL); if (!fWriteStat){if(GetLastError() == ERROR_IO_PENDING){dwError = GetLastError();// an error occurred, try to recoverwsprintf( szError, "\n\r <CE-%u>", dwError ) ;OutputDebugString(szError);ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError);}}else{// some other error occurredClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags > 0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError);}return FALSE;}}if (i != packet-1){// should be receive ackif (ReceivePacketAnswer(index) != 0){return 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 queueClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;dwLength=nMaxLength;if (dwLength > 0){if (olap==TRUE){fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ; if (!fReadStat){if (GetLastError() == ERROR_IO_PENDING){OutputDebugString("\n\rIO Pending");while(!GetOverlappedResult(m_gphdCom[index], &READ_OS,&dwLength, TRUE )){dwError = GetLastError();if(dwError == ERROR_IO_INCOMPLETE) continue;else{// an error occurred, try to recoverClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;break;}}}else // end-----if (GetLastError() == ERROR_IO_PENDING){// some other error occurreddwLength = 0 ;ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;OutputDebugString(szError);}}} // end-----if (!fReadStat)} // end-----if (olap==TRUE)else{fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ; if (!fReadStat){dwError = GetLastError();ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;OutputDebugString(szError);}}PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);}}return dwLength;。

用VC++编写USB接口通讯程序

用VC++编写USB接口通讯程序

用VC++编写USB接口通讯程序摘要:详细介绍Visual C++ 6.0环境下利用Windows API(Application Program Interface)函数来实现与符合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是由Intel,Compaq,Digital,IBM,Microsoft,NEC,Northern Telecom等七家世界著名的计算机和通信公司共同推出的新一代接口标准,全称为Universal Serial Bus(通用串行总线)。

编写在USB接口读写数据的C++程序

编写在USB接口读写数据的C++程序
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;
memset(m_sysversion, 0, 20); GetSysVersion(m_sysversion);
// 检索相关 GUID 的 USB 设备总设备个数 if (!GetUSBList()) { return 0; } // 取得一个该 GUID 相关的设备信息集句柄 hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUI D NULL, // 无关键字 NULL, // 不指定父窗口句柄 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
if (bResult) { ULONG predictedLength = 0; ULONG requiredLength = 0; // 取得该设备接口的细节(设备路径) bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, // 设备信息集句柄 &ifdata, // 设备接口信息 NULL, // 设备接口细节(设备路径) 0, // 输出缓冲区大小 &requiredLength, // 不需计算输出缓冲区大小(直接用设定值) NULL); // 不需额外的设备描述 // 取得该设备接口的细节(设备路径) predictedLength=requiredLength;
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; }

如何实现VC应用程序与PLC的数据交换

如何实现VC应用程序与PLC的数据交换

如何实现VC应用程序与PLC的数据交换当今,随着工业自动化的广泛应用,越来越多的工业企业开始采用可编程逻辑控制器(PLC)来控制和管理生产过程。

而随着信息技术的不断发展,将计算机技术与工业控制相结合,实现VC应用程序与PLC的数据交换,已经成为很多企业提高生产效率、提升产品质量的一种重要手段。

本文将从硬件和软件两个角度来介绍如何实现VC应用程序与PLC的数据交换。

硬件层面:在实现VC应用程序与PLC的数据交换之前,首先需要确保计算机和PLC之间能够进行可靠的通信。

一般而言,可以通过以下几种方式来实现计算机和PLC之间的连接和通信。

1.串口通信:串口通信是最常见的一种方式,通过串口线将计算机的串口与PLC的COM口相连接。

在VC应用程序中,通过编程方式来读写串口数据,从而实现与PLC的数据交互。

2.以太网通信:在以太网通信方式下,计算机和PLC通过以太网进行连接。

可以使用TCP/IP协议来实现数据的传输。

在VC应用程序中,可以使用套接字编程来实现与PLC的通信。

B通信:有些PLC具备USB接口,可以通过USB线将计算机和PLC进行连接。

在VC应用程序中,可以通过USB编程来与PLC进行数据交互。

软件层面:在硬件连接完成之后,下一步就是通过软件来实现VC应用程序与PLC的数据交换。

以下是一些常用的软件开发工具和编程语言,可以帮助我们实现这个目标。

1.Visual Studio:Visual Studio是一个功能强大的集成开发环境,可以用于开发各种类型的应用程序,包括VC应用程序。

在VC应用程序中,可以通过编写相应的代码来与PLC进行数据交换。

2.C#编程语言:C#是一种简单、现代化的编程语言,广泛应用于Windows平台的应用程序开发。

在VC应用程序中,可以使用C#编写代码来实现与PLC的数据交互。

3.编程库:PLC通常配备有相关的编程库,包括DLL、API等,可以用于编写与PLC通信的代码。

在VC应用程序中,可以引用这些编程库,从而实现与PLC的数据交换。

用VC实现与USB驱动程序的通信

用VC实现与USB驱动程序的通信
(4)应用程序调用RecvFile方法将一个文件接收任务加入 一个流,或用RecvData方法将一个数据接收任务加入一个 流,控件接收到数据报后作差错校验、重复接收检验,将接收 到的正确的数据报重组后,RecvFile方法将数据保存为指定目 录下的文件,RecvData方法则将数据流返回给应用程序;
3.W.Richard Stevens,范建华胥光辉张涛等译.TCP/IP 详解,卷1:协议[M】.机械工业出版社,2000
4.A.Jones J.Ohlund,京京工作室译.windows网络编程 技术.机械工业出版社,2000
(收稿日期:2002年11月15日)
(上接第57页) 报告。在实现时,只要把相应的编辑框重新赋值为空即可。
mjtrLog+=J{”准备读取数据时分配内存失败.\r\n“): SetDIgltemTe×t(IDC_EDIT_j{EPORT,m—strLog):
) if(hDevice==INVALlD_j—ANDLE—yALUE)
retUm: eIse
{ Read刚e{hDevice,b uf,n,&nRead,NULL)://读取数据函数
CString p:
//p暂时存放buf中的数据以便输出
p=buf:
mjtrLog+=J(”写入设备的数据是:\n”+p+”\r\n”):
SetDIgItemText(IDC_EDIT—REPORT,m—strLog):

if(buf)
//释放缓冲区
deIete【]buf:
buf=NULL:

3.读数据 从设备读数据时,也要分配一片相应大小的内存空间,暂
(7)如果不再需要,应用程序调用DelStream方法删除一 个流。

C#实现USB接口的程序代码

C#实现USB接口的程序代码

C#实现USB接口的程序代码姑苏行namespace ConsoleApplication1{class Program{static void Main(string[] args){USB usb;usb = new UDisk();//插入U盘usb.OutputFile();//从U盘读出文件usb.InputFile();//往U盘写入文件usb.Dispose();//拔出U盘Console.WriteLine("");usb = new MDisk();//插入移动硬盘usb.OutputFile();//从移动硬盘读出文件usb.InputFile();//往移动硬盘写入文件usb.Dispose();//拔出移动硬盘Console.WriteLine("");usb = new MP4();//插入MP4usb.OutputFile();//从MP4读出文件usb.InputFile();//往MP4写入文件usb.Dispose();//拔出MP4Console.ReadKey();}//USB接口public interface USB : IDisposable{void OutputFile();//读出文件void InputFile();//写入文件}//U盘public class UDisk : USB{public UDisk(){Console.WriteLine("U盘准备就绪...");}public void OutputFile(){Console.WriteLine("从U盘读出文件");}public void InputFile(){Console.WriteLine("往U盘写入文件");}public void Dispose(){Console.WriteLine("U盘已被拔出");}}//移动硬盘public class MDisk : USB{public MDisk(){Console.WriteLine("移动硬盘准备就绪...");}public void OutputFile()Console.WriteLine("从移动硬盘读出文件");}public void InputFile(){Console.WriteLine("往移动硬盘写入文件");}public void Dispose(){Console.WriteLine("移动硬盘已被拔出");}}//MP4public class MP4 : USB{public MP4(){Console.WriteLine("MP4准备就绪...");}public void OutputFile()Console.WriteLine("从MP4读出文件");}public void InputFile(){Console.WriteLine("往MP4写入文件");}public void Dispose(){Console.WriteLine("MP4已被拔出");}}}}。

C实现USBHID设备读写代码

C实现USBHID设备读写代码

USB HID设备读写代码实现c++ 收藏源代码如下:(生成.dll .lib)1.MCDInterface.h/**MCDInterface.h*author:*data:*/#ifndef MCDBOX_H_INCLUDED#define MCDBOX_H_INCLUDED#pragma once#define MCD_IOCTRL_OPEN_SIG 0x1001#define MCD_IOCTRL_CLOSE_SIG 0x1002#define MCD_IOCTRL_FIND_SIG 0x1003#define MCD_IOCTRL_READY 0x1003#define MCD_IOCTRL_UNREADY 0x1004#define KEY_0 0x3A#define KEY_1 0x3B#define KEY_2 0x3C#define KEY_3 0x3D#define KEY_4 0x3E#define KEY_5 0x3F#define KEY_6 0x40#define KEY_7 0x41#define KEY_8 0x42#define KEY_9 0x43#define KEY_STAR 0x44#define KEY_POUND 0x45#define MSG_HOOKOFF 0x16#define MSG_HOOKON 0x12#define MSG_RINGING 0x15#define HID_DEVICE_REMOVE 0x76 //硬件被移走#define CLIENT_READY_WRITE_SIG 0x92 //通知设备软件正在运行,每隔一段时间向缓冲区写该数据#define DLL_EXPORT __declspec(dllexport)#define DLL_IMPORT __declspec(dllimport)//定义用于回调的枚举消息enum{MCD_CALLBACK_MSG_VERSION,//not usedMCD_CALLBACK_MSG_SERIALNO,//not usedMCD_CALLBACK_DEVICE_FOUND,MCD_CALLBACK_DEVICE_NOT_FOUND,MCD_CALLBACK_DEVICE_REMOVE,MCD_CALLBACK_KEYDOWN,MCD_CALLBACK_KEYBUFFER_CHANGED,MCD_CALLBACK_HOOKOFF,MCD_CALLBACK_HOOKON,MCD_CALLBACK_RINGING,MCD_CALLBACK_MSG_WARNING = -2,MCD_CALLBACK_MSG_ERROR = -1,};DLL_EXPORT unsigned long MCD_DeviceIoControl(unsigned long dwIoControlCode,void* lpInBuffer = 0, unsigned long nInBufferSize = 0,void* lpOutBuffer = 0, unsigned long nOutBufferSize = 0);//定义设备状态返回信息enum{MCD_RETURN_SUCCESS = 0,MCD_RETURN_FOUND_HID,MCD_RETURN_NO_FOUND_HID,MCD_RETURN_HID_IS_OPENED,//?MCD_RETURN_HID_NO_OPEN,//?};#endif // MCDBOX_H_INCLUDED2.mcdHid.h#ifndef MCDHID_H_INCLUDED#define MCDHID_H_INCLUDEDextern "C"{#include "setupapi.h"#include "hidsdi.h"#include "dbt.h"}typedef struct _HID_DEVICE {PCHAR DevicePath;HANDLE HidDevice; // A file handle to the hid device.HIDP_CAPS Caps; // The Capabilities of this hid device.HIDD_ATTRIBUTES Attributes;} HID_DEVICE, *PHID_DEVICE;class MCDHid{public:static MCDHid & getInstance(){static MCDHid mcdHid;return mcdHid;}MCDHid(MCDHid & mcdHid);MCDHid & operator=(MCDHid &mcdHid);~MCDHid();unsigned long openMCDHid();void closeMCDHid();void startComm(void * pParam);int writeToHid();int readFromHid();char * getHidDeviceName(){return _hidDeviceName;}bool findMCDHid();HID_DEVICE* getHidDevice(){return & _hidDevice;}bool getUsbCommRunning(){return _fUsbCommRunning;}bool getOffHookSignal(){return _offHookSignal;}unsigned long getDataWaitProcess(){return _dataWaitProcess;}void setUsbCommRunning(bool usbCommRunning) {_fUsbCommRunning = usbCommRunning;}unsigned char _inputReportBuffer[9];unsigned char _outputReportBuffer[2];private:MCDHid();void copy(MCDHid & mcdHid);char *_hidDeviceName;HANDLE _hEventObject;OVERLAPPED _hIDOverlapped;HID_DEVICE _hidDevice;bool _fUsbCommRunning;bool _offHookSignal;unsigned long _dataWaitProcess;unsigned long _inputReportByteLength;unsigned long _outputReportByteLength;};#endif // MCDHID_H_INCLUDED3.mcdHid.cpp/*mcdhid.cppfunction: open HID device ,close HID device ,read data from HID device , write data to HID deviceauthor:date:version:*/#include <stdlib.h>#include <windows.h>#include <stdio.h>#include "mcdhid.h"#include "MCDInterface.h"#include "mcdbox.h"#include "pthread.h"void *getDataThread(void *pParam);#define VENDOR_ID 0x1241//test device vendorId#define PRODUCT_ID 0xe001//test device productId#define CLIENT_RUNNING_MSGMCDHid::MCDHid(){_hidDeviceName = "MCD Human Interface Device";_fUsbCommRunning = false;_offHookSignal = false;_dataWaitProcess = 1;memset(_inputReportBuffer,0,sizeof(_inputReportBuffer));memset(_outputReportBuffer,0,sizeof(_outputReportBuffer));}MCDHid::MCDHid(MCDHid & mcdHid){copy(mcdHid);}MCDHid & MCDHid::operator=(MCDHid & mcdHid){copy(mcdHid);return *this;}void MCDHid::copy(MCDHid & mcdHid){_hidDeviceName = mcdHid._hidDeviceName;_hEventObject = mcdHid._hEventObject;_hIDOverlapped = mcdHid._hIDOverlapped;_hidDevice = mcdHid._hidDevice;_fUsbCommRunning = mcdHid._fUsbCommRunning;_offHookSignal = mcdHid._offHookSignal;_dataWaitProcess = mcdHid._dataWaitProcess;_inputReportByteLength = mcdHid._inputReportByteLength;_outputReportByteLength = mcdHid._outputReportByteLength; for(int i = 0; i<s izeof(_inputReportBuffer); i++){_inputReportBuffer[i] = mcdHid._inputReportBuffer[i];}for(int i = 0; i<s izeof(_outputReportBuffer); i++){_inputReportBuffer[i] = mcdHid._outputReportBuffer[i];}}MCDHid::~MCDHid(){}unsigned long MCDHid::openMCDHid(){if(findMCDHid()){//采用重叠传输方式//if( _hEventObject == 0)// {_hEventObject = CreateEvent(NULL,true,true,"");_hIDOverlapped.hEvent = _hEventObject;_hIDOverlapped.Offset = 0;_hIDOverlapped.OffsetHigh =0;// }return MCD_RETURN_SUCCESS;}elsereturn MCD_RETURN_NO_FOUND_HID;}void MCDHid::closeMCDHid(){CloseHandle(_hidDevice.HidDevice);_hidDevice.HidDevice = INVALID_HANDLE_VALUE;}void MCDHid::startComm(void *pParam){int thr_id;pthread_t m_processT;if((thr_id=pthread_create(&m_processT, NULL, getDataThread, pParam) != 0)){//printf("pthread_create error:%s\n", strerror(thr_id));return;}}bool MCDHid::findMCDHid(){int vendorID = VENDOR_ID;int productID = PRODUCT_ID;DWORD required;GUID hidGuid;HDEVINFO hDevInfo;SP_DEVICE_INTERFACE_DATA devInfoData;int memberIndex = 0;LONG result;bool lastDevice = false;DWORD length;PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;bool deviceDetected = false;HidD_GetHidGuid(&hidGuid);hDevInfo = SetupDiGetClassDevs(&hidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);//当应用程序不再需要使用SetupDiGetClassDevs函数的传回值hDevInfo所指的数组时,应该调用SetupDiDeStroyDeviceInfoList函数来释放资源if(hDevInfo == INVALID_HANDLE_VALUE){//printf("Failed to open device handle!");return false;}devInfoData.cbSize = sizeof(devInfoData);do{result = SetupDiEnumDeviceInterfaces(hDevInfo,0,&hidGuid,memberIndex,&devInfoData);if (result != 0){result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,NULL,0,&length,NULL);detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(length);if(!detailData){//printf("Device information allacation failed!");return false;}detailData -> cbSize =sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,detailData,length,&required,NULL);if(!result){//printf("Device information reallocation failed!");return false;}_hidDevice.HidDevice = CreateFile(detailData->DevicePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);_hidDevice.Attributes.Size = sizeof(HIDD_ATTRIBUTES);result = HidD_GetAttributes(_hidDevice.HidDevice,&_hidDevice.Attributes);if ((_hidDevice.Attributes.VendorID == vendorID) &&(_hidDevice.Attributes.ProductID == productID)){int status;PHIDP_PREPARSED_DATA PreparsedData ;deviceDetected = true;//获取USB设备的预解析数据result =HidD_GetPreparsedData(_hidDevice.HidDevice,&PreparsedData);if(!result){//printf("无法获取USB设备的预解析数据!");return false;}status= HidP_GetCaps(PreparsedData, &_hidDevice.Caps); _fUsbCommRunning = true;HidD_FreePreparsedData(PreparsedData);PreparsedData = NULL;}else//printf("没有找到设备!");closeMCDHid();}free(detailData);detailData = NULL;}else{lastDevice = true;}memberIndex = memberIndex + 1;}while((lastDevice == false)&&(deviceDetected == false));SetupDiDestroyDeviceInfoList(hDevInfo);return deviceDetected;}/**写入数据为MCD设备状态通知,把标识位放在第1位*/int MCDHid::writeToHid(){return 0;}int MCDHid::readFromHid()//int readFromHid(){if(_hidDevice.HidDevice != INVALID_HANDLE_VALUE){int result = 0;DWORD numberOfBytesRead;result = ReadFile(_hidDevice.HidDevice,&_inputReportBuffer,_hidDevice.Caps.InputReportByteLength,&numberOfBytesRead,(LPOVERLAPPED)&_hIDOverlapped);_inputReportByteLength = _hidDevice.Caps.InputReportByteLength; }int waitResult = 0;waitResult = WaitForSingleObject(_hEventObject,10);switch(waitResult)case WAIT_OBJECT_0: break;case WAIT_TIMEOUT:{CancelIo(_hidDevice.HidDevice);break;}default:{break;}}ResetEvent(_hEventObject);return 0;}/************************************************************* **************启动一个读取数据线程,读取数据为拨打电话号码*启动一个写入数据线程, 写入数据为MCD设备状态通知,现在还没有写数据************************************************************** *************/void *getDataThread(void *pParam){MCDBox *ht = (MCDBox *)pParam;MCDHid *hr = &(MCDHid::getInstance());while(hr->getUsbCommRunning())//USB设备running,并且有摘机信号{hr->readFromHid();//readFromHid();//printf("获取缓冲区的数据\n");if(hr->getDataWaitProcess() > 0)//可以定义_dataWaitProcess为一次拨号数据的长度{unsigned long i = 0;for(i = 0; i < 9; i++){ht->_inputReportBuffer[i] = hr->_inputReportBuffer[i];//printf("read data from device is:%d\n",ht->_inputReportBuffer[1]);}ht->processData();memset(hr->_inputReportBuffer,0,sizeof(hr->_inputReportBuffer));//printf("数据处理!\n");}int status = 0;//PHIDP_PREPARSED_DATA PreparsedData ;//status = HidD_GetPreparsedData(_hidDevice.HidDevice,&PreparsedData); status = HidD_GetAttributes(hr->getHidDevice()->HidDevice,&hr->getHidDevice()->Attributes);if(!status){hr->setUsbCommRunning(false);memset(ht->_inputReportBuffer,0,sizeof(ht->_inputReportBuffer));ht->_inputReportBuffer[2] = HID_DEVICE_REMOVE;ht->processData();printf("设备移走!");//return false;break;}//HidD_FreePreparsedData (PreparsedData);// PreparsedData = NULL;Sleep(100);}return 0;}4.mcdbox.h#ifndef MCDMAIN_H_INCLUDED#define MCDMAIN_H_INCLUDEDclass MCDHid;class MCDCallBack;class MCDBox{public:static MCDBox & getInstance(){static MCDBox mcdBox;return mcdBox;}~MCDBox();unsigned long deviceIOControl(unsigned long dwIoControlCode,void* lpInBuffer, unsigned long nInBufferSize,void* lpOutBuffer, unsigned long nOutBufferSize);void findDevice(void* lpInBuffer, unsigned long nInBufferSize,void* lpOutBuffer, unsigned long nOutBufferSize);unsigned long openDevice(void* lpInBuffer, unsigned long nInBufferSize, void* lpOutBuffer, unsigned long nOutBufferSize);void closeDevice();void processData();unsigned char _inputReportBuffer[9];unsigned char _outputReportBuffer[9];unsigned long _inputBufferByteLength;unsigned long _outputBufferByteLength;bool isDeviceOpen(){return _openDevice;}void setDeviceOpen(bool deviceOpen){_openDevice = deviceOpen;}private:MCDBox();char * _mcdHidName;unsigned long _mcdStatus;MCDHid & _mcdHid;MCDCallBack &_mcdCallback;bool _openDevice;//char _key;};/**定义回调函数*/typedef void (*CALLBACK_MCDBOX)(void* wParam, void* lParam, unsigned long ParameterOfApp);class MCDCallBack{public:static MCDCallBack & getInstance(){static MCDCallBack mcdCallback;return mcdCallback;}MCDCallBack(MCDCallBack & mcdCallback);MCDCallBack & operator=(MCDCallBack & mcdCallback);virtual ~MCDCallBack();void create(void* pCallBackFunction = 0, unsigned long dwParameterOfApplication = 0);void callBack(unsigned long wParam,void* lParam = 0);private:MCDCallBack();void copy(MCDCallBack & mcdCallback);struct {CALLBACK_MCDBOX func;unsigned long lParam;}_fCallBack;};//extern MCDCallBack mcdCallBack;#endif // MCDMAIN_H_INCLUDED5.cpp/*mcdbox.cppfunction description: 数据处理接口author:date:version:*/#ifndef MCDBOX_CPP_INCLUDED#define MCDBOX_CPP_INCLUDED#include <windows.h>#include <stdio.h>#include "mcdbox.h"#include "MCDInterface.h"#include "mcdhid.h"#include "pthread.h"void *findDeviceThread(void *param);unsigned long MCD_DeviceIoControl(unsigned long dwIoControlCode,void* lpInBuffer, unsigned long nInBufferSize,void* lpOutBuffer, unsigned long nOutBufferSize) {unsigned long br = 0;MCDBox *ht = (MCDBox *)&(MCDBox::getInstance());//MCDBox ht = getInstance();;try{br =ht->deviceIOControl(dwIoControlCode,lpInBuffer,nInBufferSize,lpOutBuffer,n OutBufferSize);}catch (unsigned long BytesReturned){br = BytesReturned;}return br;}MCDBox::MCDBox():_mcdHid(MCDHid::getInstance()),_mcdCallback(MCDCallBack::getInstance()){_openDevice =false;_inputBufferByteLength = 8;_outputBufferByteLength = 8;for (int i = 0; i < (int)_inputBufferByteLength; i++){_inputReportBuffer[i] = 0;}for (int j = 0;j < (int)_outputBufferByteLength; j++){_outputReportBuffer[j] = 0;}}MCDBox::~MCDBox(){}unsigned long MCDBox::deviceIOControl(unsigned long dwIoControlCode,void* lpInBuffer, unsigned long nInBufferSize,void* lpOutBuffer, unsigned long nOutBufferSize) {switch (dwIoControlCode){case MCD_IOCTRL_FIND_SIG:findDevice(lpInBuffer,nInBufferSize,lpOutBuffer,nOutBufferSize);break;case MCD_IOCTRL_CLOSE_SIG:if (_openDevice){closeDevice();}_mcdHid.closeMCDHid();_openDevice = false;return 0;case MCD_IOCTRL_OPEN_SIG:if (_openDevice)return MCD_RETURN_HID_IS_OPENED;openDevice(lpInBuffer,nInBufferSize,lpOutBuffer,nOutBufferSize);break;//case CLIENT_READY_WRITE_SIG://软件运行正常,通知硬件设备// _mcdHid.writeToHid();// return 0;default:if (!_openDevice) return MCD_RETURN_HID_NO_OPEN;break;}return 0;}void MCDBox::findDevice(void* lpInBuffer, unsigned long nInBufferS ize,void* lpOutBuffer, unsigned long nOutBufferSize) {pthread_t m_processT;int threadID;_mcdCallback.create(lpInBuffer,nInBufferSize);if((threadID=pthread_create(&m_processT, NULL, findDeviceThread, this) != 0)){return ;}}unsigned long MCDBox::openDevice(void* lpInBuffer, unsigned long nInBufferSize,void* lpOutBuffer, unsigned long nOutBufferSize) {_mcdCallback.create(lpInBuffer,nInBufferSize);unsigned long dwReturnValue = _mcdHid.openMCDHid();if(dwReturnValue == MCD_RETURN_SUCCESS){_openDevice = true;// _mcdCallback.create(lpInBuffer,nInBufferSize);_mcdStatus = MCD_IOCTRL_READY;//_mcdHid.writeToHid();//软件运行正常,通知硬件设备//_key = 0;_mcdHid.startComm(this);_mcdHidName = _mcdHid.getHidDeviceName();}else{_mcdHid.closeMCDHid();}return dwReturnValue;}void MCDBox::closeDevice(){_mcdHid.closeMCDHid();}/************************************************************* *******************/***读取缓冲区,第二个字节为有效数据,buffer size = 8bytes。

VC环境下 USB HID类说明

VC环境下 USB HID类说明

VC环境下 USB HID类说明1、头文件包含,库文件链接在VC中开发HID应用程序时,需要包含setupapi.h和hidsdi.h,包含方式必须为extern "C",如下所示:extern "C" {// Declare the C libraries used#include "setupapi.h" // Must link in setupapi.lib#include "hidsdi.h" // Must link in hid.lib};然后在setting—>Link—>object/libary modules 中添加setupapi.lib hid.lib 两个库文件。

void __stdcall HidD_GetHidGuid(__out LPGUID HidGuid //指针指向调用者分配的GUID的内存区域,通常返回HID设备的GUID );2.2 SetupDiGetClassDevsHDEVINFO SetupDiGetClassDevs(__in_opt const GUID *ClassGuid,// 一个特定类别GUID的指针__in_opt PCTSTR Enumerator, //过滤梅举的内容__in_opt HWND hwndParent, //用于关联到集合成员中的用户接口的顶层窗口句柄__in DWORD Flags //建立设备信息表的控制选项,DIGCF_PRESENT(当前存在的设备)DIGCF_ALLCLASSES(所有设备)DIGCF_PROFILE(当前硬件概况);) 如成功,返回包含所有与指定参数匹配的已经安装设备信息句柄,否则返回INV ALID_HANDLE_V ALUE 2.3 SetupDiEnumDeviceInterfacesBOOL SetupDiEnumDeviceInterfaces(__in HDEVINFO DeviceInfoSet, //一个指向设备信息集合的句柄,包含设备接口返回信息,通常是SetupDiGetClassDevs的返回值__in_opt PSP_DEVINFO_DATA DeviceInfoData, //指向特定设备的SP_DEVINFO_DATA类型的指针,__in const GUID *InterfaceClassGuid, //指向制定设备接口类的GUID指针__in DWORD MemberIndex, //设备信息中接口列表的索引值(初始值为0)__out PSP_DEVICE_INTERFACE_DA TA DeviceInterfaceData //指向调用者分配的SP_DEVICE_INTERFACE_DATA类型的内存区域的指针,调用前必须先配置DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DA TA)); 如成功,返回TRUE,否则返回FALSE,并可以调用GetLastError(void)获取错误信息2.4 SetupDiGetDeviceInterfaceDetailBOOL SetupDiGetDeviceInterfaceDetail(__in HDEVINFO DeviceInfoSet, //一个指向设备信息集合的句柄,包含设备接口返回信息,通常是SetupDiGetClassDevs的返回__in PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, //指向SP_DEVICE_INTERFACE_DA TA类型的内存区域的指针,SetupDiEnumDeviceInterfaces的返回 __out_opt PSP_DEVICE_INTERFACE_DETAIL_DATADeviceInterfaceDetailData,//SP_DEVICE_INTERFACE_DETAIL_DATA类型指针,用于获取路径,调用前必须先配置DeviceInterfaceDetailData.cbSize =sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)__in DWORD DeviceInterfaceDetailDataSize, //DeviceInterfaceDetailData 的长度,__out_opt PDWORD RequiredSize, //DeviceInterfaceDetailData 的实际长度__out_opt PSP_DEVINFO_DA TA DeviceInfoData //PSP_DEVINFO_DATA 类型的指针,存放支持的设备接口信息,DeviceInfoData.cbSize =sizeof(SP_DEVINFO_DATA) ); 如成功,返回TRUE,否则返回FALSE,并可以调用GetLastError(void)获取错误信息2.5 HidD_GetAttributesBOOLEAN __stdcall HidD_GetAttributes(__in HANDLE HidDeviceObject, //HID设备句柄__out PHIDD_ATTRIBUTES Attributes //HIDD_A TTRIBUTES类型指针);2.6 CreateFileHANDLE WINAPI CreateFile(__in LPCTSTR lpFileName, //已打开的设备名称__in DWORD dwDesiredAccess, //操作权限,GENERIC_READ, GENERIC_WRITE(写模式), 或者both__in DWORD dwShareMode, //共享模式,0(禁止访问),FILE_SHARE_DELETE(删除),FILE_SHARE_READ(读),FILE_SHARE_WRITE(写)__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, //SECURITY_A TTRIBUTES类型指针__in DWORD dwCreationDisposition, //打开方式,对于设备来说经常设为OPEN_EXISTING__in DWORD dwFlagsAndAttributes, //设备属性和标识,经常设为FILE_ATTRIBUTE_NORMAL__in_opt HANDLE hTemplateFile //模板文件句柄); 如成功,则返回一个文件或设备的句柄2.7 ReadFileBOOL WINAPI ReadFile(__in HANDLE hFile, //文件或设备的句柄__out LPVOID lpBuffer, //存放读取数据的指针__in DWORD nNumberOfBytesToRead, //读取数据长度的最大值__out_opt LPDWORD lpNumberOfBytesRead, //读取数据的实际长度__inout_opt LPOVERLAPPED lpOverlapped //OVERLAPPED类型指针,若设备或文件被重复打开,需此参数); 如成功,返回TRUE,否则返回FALSE,并可以调用GetLastError(void)获取错误信息2.8 WriteFileBOOL WINAPI WriteFile(__in HANDLE hFile, //文件或设备的句柄__in LPCVOID lpBuffer, //存放写入数据的指针__in DWORD nNumberOfBytesToWrite, //写入数据长度的最大值__out_opt LPDWORD lpNumberOfBytesWritten, //写入数据的实际长度__inout_opt LPOVERLAPPED lpOverlapped //OVERLAPPED类型指针,若设备/文件被重复打开,需此参数); 如成功,返回TRUE,否则返回FALSE,并可以调用GetLastError(void)获取错误信息2.9 SetupDiDestroyDeviceInfoListBOOL SetupDiDestroyDeviceInfoList( __in HDEVINFO DeviceInfoSet); //释放SetupDiGetClassDevs使用的资源3、代码示例3.1 打开一个指定V endorID和ProductID的HID设备PSP_DEVICE_INTERFACE_DETAIL_DATA HID_FindDevices(USHORT V_ID, USHORT P_ID, unsigned short *FIFO_Length){GUID HidGuid;HDEVINFO DevInfo;HIDD_A TTRIBUTES DevAttributes;SP_DEVICE_INTERFACE_DATA DevData;PSP_DEVICE_INTERFACE_DETAIL_DATA DevDetail;PHIDP_PREPARSED_DA TA PreparsedData;HIDP_CAPS Capabilities;ULONG Length;int Index;BOOL ok;HANDLE DevHandle;int DevCount = 0;/* Get GUID for all System HIDs */HidD_GetHidGuid(&HidGuid);/* Get Device Information for all present devices */DevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) );DevData.cbSize = sizeof(DevData);DevDetail = NULL;Index = -1;*FIFO_Length = 0;/* Scan all Devices */do {Index++;/* Device Interface Element of a Device Information set */ok = SetupDiEnumDeviceInterfaces(DevInfo, 0, &HidGuid, Index, &DevData);if (!ok) break;/* Get Device Interface Details - Get Length */ok = SetupDiGetDeviceInterfaceDetail(DevInfo, &DevData, NULL, 0, &Length, NULL);/* Allocate memory for Device Detailed Data */DevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(Length);/* Set cbSize in the DevDetail structure */DevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);/* Get Device Interface Details */ok = SetupDiGetDeviceInterfaceDetail(DevInfo, &DevData, DevDetail, Length, NULL, NULL);if (!ok){free(DevDetail);DevDetail = NULL;continue;}/* Create File for Device Read/Write */DevHandle = CreateFile(DevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);if (DevHandle == INV ALID_HANDLE_V ALUE){free(DevDetail);DevDetail = NULL;continue;}DevAttributes.Size = sizeof(DevAttributes);ok = HidD_GetAttributes(DevHandle,&DevAttributes);if(!ok){free(DevDetail);CloseHandle(DevHandle);DevDetail = NULL;continue;}if(DevAttributes.VendorID!=V_ID||DevAttributes.ProductID != P_ID){free(DevDetail);CloseHandle(DevHandle);DevDetail = NULL;continue;}/* Get Preparsed Data */ok = HidD_GetPreparsedData(DevHandle, &PreparsedData);if (!ok){free(DevDetail);CloseHandle(DevHandle);DevDetail = NULL;continue;}/* Get Device's Capabilities */HidP_GetCaps(PreparsedData, &Capabilities);*FIFO_Length = Capabilities.InputReportByteLength;CloseHandle (DevHandle);break;} while (DevCount < 20);SetupDiDestroyDeviceInfoList (DevInfo);return DevDetail;}3.2 发送过程(PC->Device)BOOL WINAPI WriteFile(__in HANDLE hFile, //文件或设备的句柄__in LPCVOID lpBuffer, //存放写入数据的指针__in DWORD nNumberOfBytesToWrite, //写入数据长度的最大值__out_opt LPDWORD lpNumberOfBytesWritten, //写入数据的实际长度__inout_opt LPOVERLAPPED lpOverlapped //OVERLAPPED类型指针,若设备/文件被重复打开,需此参数); 如成功,返回TRUE,否则返回FALSE,并可以调用GetLastError(void)获取错误信息此函数需要注意:(1)hFile是CreateFile创建的句柄;注意:CreateFile中的参数:GENERIC_READ | GENERIC_WRITE(2)lpBuffer是个全局型数值变量,且此数值一般要大于unsigned char [65],而且lpBuffer[0]需要赋予特定的值,用来存储REPORT ID(底层定义的特定值)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用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(m_sysversion);// 检索相关GUID的USB设备总设备个数if (!GetUSBList()){return 0;}// 取得一个该GUID相关的设备信息集句柄hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUIDNULL, // 无关键字NULL, // 不指定父窗口句柄DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备// 失败...if (hDevInfoSet == INVALID_HANDLE_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 = ::SetupDiEnumDeviceInterfaces(hDevInfoSet, // 设备信息集句柄NULL, // 不需额外的设备描述(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID(ULONG)nCount, // 设备信息集里的设备序号&ifdata); // 设备接口信息if (bResult){ULONG predictedLength = 0;ULONG requiredLength = 0;// 取得该设备接口的细节(设备路径)bResult = SetupDiGetInterfaceDeviceDetail(hDevInfoSet, // 设备信息集句柄&ifdata, // 设备接口信息NULL, // 设备接口细节(设备路径)0, // 输出缓冲区大小&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)NULL); // 不需额外的设备描述// 取得该设备接口的细节(设备路径)predictedLength=requiredLength;// if(pDetail)// {// pDetail =NULL;// }pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);bResult = SetupDiGetInterfaceDeviceDetail(hDevInfoSet, // 设备信息集句柄&ifdata, // 设备接口信息pDetail, // 设备接口细节(设备路径)predictedLength, // 输出缓冲区大小&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)NULL); // 不需额外的设备描述if (bResult){// 复制设备路径到输出缓冲区//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);if (strcmp(m_sysversion, "winnt")==0){char ch[18];for(i=0;i<17;i++){ch=*(pDetail->DevicePath+8+i);}ch[17]='\0';if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错{memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;READ_OS.hEvent = CreateEvent( NULL, // no securityTRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (READ_OS.hEvent == NULL){break;}WRITE_OS.hEvent = CreateEvent( NULL, // no securityTRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (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){// 比较定位找到的USB在哪个USB PORT上char id[30];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_USBList[j])==0){sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath); m_USBPositionMap[nCount] = j+1;break;}}CloseHandle(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 reqFALSE, // initial event resetNULL ) ; // no nameif (READ_OS.hEvent == NULL){break;}WRITE_OS.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset reqFALSE, // initial event resetNULL ) ; // no nameif (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){if(strcmp(pDetail->DevicePath, m_USBList[j])==0){sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath); m_USBPositionMap[nCount] = j+1;break;}CloseHandle(hUsb);nCount++;// 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 len, i, j, packet;div_t div_result;BYTE sendpacket[65];BYTE xorcode="0x00";if (m_gphdCom[index] == 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(sendpacket, 0, 65);if(i==packet-1){// end packetif (div_result.rem == 0){len = 58;}else{len = div_result.rem;}}else{len = 58;}sendpacket[0] = 0x13;sendpacket[1] = 3+len;sendpacket[2] = 0x01;sendpacket[3] = packet*16+i+1;memcpy(sendpacket+4, buf+(i*58), len);for(j=0;j<len+3;j++){xorcode^=sendpacket[j+1];}sendpacket[len+4] = (char)xorcode;sendpacket[len+5] = 0x23;PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);// Sleep(10);fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL); if (!fWriteStat){if(GetLastError() == ERROR_IO_PENDING){dwError = GetLastError();// an error occurred, try to recoverwsprintf( szError, "\n\r <CE-%u>", dwError ) ;OutputDebugString(szError);ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError);}}else{// some other error occurredClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags > 0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError);}return FALSE;}}if (i != packet-1){// should be receive ackif (ReceivePacketAnswer(index) != 0){return 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 queueClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;dwLength=nMaxLength;if (dwLength > 0){if (olap==TRUE){fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ; if (!fReadStat){if (GetLastError() == ERROR_IO_PENDING){OutputDebugString("\n\rIO Pending");while(!GetOverlappedResult(m_gphdCom[index], &READ_OS,&dwLength, TRUE )){dwError = GetLastError();if(dwError == ERROR_IO_INCOMPLETE) continue;else{// an error occurred, try to recoverClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;break;}}}else // end-----if (GetLastError() == ERROR_IO_PENDING){// some other error occurreddwLength = 0 ;ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;OutputDebugString(szError);}}} // end-----if (!fReadStat)} // end-----if (olap==TRUE)else{fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ; if (!fReadStat){dwError = GetLastError();ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;if (dwErrorFlags >0){wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;OutputDebugString(szError);}}PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);}}return dwLength;用VC++编写USB接口通讯程序摘要:详细介绍Visual C++ 6.0环境下利用Windows API(Application Program Interface)函数来实现与符合HID设备类的USB接口通讯,并给出了通信程序的部分代码。

相关文档
最新文档