USB接口程序編寫
copy from http://blog.csdn.net/luckywang1103/article/details/12393889#
HID是Human Interface Devices的縮寫,即人機接口設備。HID設備的一大優勢就是操作系統已經內置了HID設備驅動,一般不需要安裝驅動程序。通用的HID設備可以直接使用HID設備類驅動程序(hidclass.sys)和HID小驅動程序(hidusb.sys).
在應用程序內引入頭文件
extern "C"
{
#include "hidsdi.h"
#include <setupapi.h>
}
1:查找設備
在應用程序能與HID設備交換數據之前,它先要找到設備,獲取關於它的報告信息。
1)HidD_GetHidGuid(&guidHID);來獲取HID設備的標示,HID類設備是通過GUID類型值作為標示的。GUID是16字節大小的結構,用來標示通信接口及類對象,他的定義為:
2)還需要調用其他與硬件相關的API函數,這些函數都在setupapi.h 中定義。
SetupDiGetClassDevs函數用來獲得一類硬件設備的信息,設備信息集句柄hDevInfo
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&guidHID,//這類設備配置或接口類GUID
NULL,// 特定的字符串,用來選擇合適條件的蛇別
0,// 與獲得信息相關的頂層窗體句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE //給出了設置信息的方式
);
3)SetupDiEnumDeviceInterface函數得到設備接口信息,反復調用得到所有設備接口信息strInterfaceData,若要找到特定設備,可在循環語句內調用該函數,直到找到預期設備或函數返回False值,定義為:
Bool bSuccess = SetupDiEnumDeviceInterface(
hDevInfo, //感興趣的接口句柄
NULL, //指向SP_DEVINFO_DATA類型結構的指針,該結構定義額特定接口
&guidHID, //確定了接口的GUID標示
Index, //所關心的索引號,以0為起點
&strInterfaceData, //指向SP_DEVICE_INTERFACE_DATA類型的指針,他所指向的內容就是調用函數的目的所在,當函數返回時,strInterfaceData指向的結構就存在相關接口信息 );
}
其中SP_DEVINFO_DATA結構定義為:
typedef struct SP_DEVINFO_DATA{
DWORD cbsize;//指向結構的大小
GUID calssGUID; //設備的GUID標誌
DWORD DevInst;//用來訪問設備的句柄
ULONG_PTR Reserved;
}SP_DEVINFO_DATA,*PSP_DEVINFO_DATA;
SP_DEVICE_INTERFACE_DATA結構的定義如下:
typedef struct SP_DEVICE_INTERFACE_DATA{
DWORD cssize; //是SP_DEVICE_INTERFACE_DATA結構的大小
GUID InterfaceClassGuid; //指定了接口的GUID標示
DWORD Flags; //接口所處狀態
ULONG_PTR Reserved;
}SP_DEVICE_INTERFACE_DATA,*PSP_DEVICE_INTERFACE_DATA;
4) SetupDiGetDeviceInterfaceDetail()
long Result = SetupDiGetDeviceInterfaceDetail(
hDevInfo, //設備信息集句柄
&strInterfaceData, //設備接口信息
NULL,
0,
&Length,
NULL);
再次調用為了得到strInterfaceDetailData
long Result = SetupDiGetDeviceInterfaceDetail(
hDeviceInfo,
&strInterfaceData,
strInterfaceDetailData,
Length,
&Required,
NULL);
2,與USB設備交換數據
在Windows中,讀寫端口與讀寫文件都是調用同樣的API函數,打開或創建端口用CreateFile,從端口讀取數據ReadFile,用WriteFile向端口寫入數據
1) 設備的打開與關閉
用API函數CreateFIle來打開或者創建設備
HANDLE hCom = CreateFile(
strInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL,
);
如果調用成功,函數則返回文件的句柄,如果調用失敗,則返回INVALID_HANDLE_VALUE,在打開通信設備是,應該以獨占方式打開,不再使用設備句柄時,應該調用CloseHandle(hCom)函數來關閉。
2)Bool Result = HidD_GetAttributes(hCom,&strAttrib);
其中hCom是對應於選定設備的句柄,strAttribute則是指向HIDD_ATTRIBUTES類型的指針,當函數返回時即得到了指定設備的屬性
typedef struct _HIDD_ATTRIBUTES{
ULONG Size;
USHORT VendorID;
USHORT VersionNumber;
}HIDD_ATTRIBUTES,*PHIDD_ATTRIBUTES;
3) 設備的讀寫操作,讀寫通信設備可用同步方式執行
HANDEL hCom;
void *pBuffer;
DWORD iLength;
DWORD pReadFace;
Bool ReadFile(hCom,pBuffer,iLength,&pReadFact,NULL);
讀取刀的數據放在pBuffer中,pBuffer要先申請內存空間,iLength為需要讀的數據長度,pReadFact存放實際的數據長度。讀寫設備前,應該調用ClearCommError函數清除,該函數負責報告指定的設備的當前狀態,調用PrugeComm函數可以更改正在進行的讀寫操作方式
USB接口程序編寫