USB通讯
要做一个USB通讯,vc的,该先从何处入手?以前做过串口通讯的,用的vc控件。
[解决办法]
枚举设备,再打开设备。我这有一段代码,可以参考一下,网上也可以搜得到。USB设备有很多种,要与USB设备通信,就要先获取你的USB设备类的GUID标识,然后再根据GUID来枚举该类的设备。,然后从中找到你的设备。要与USB设备通信,还得先安装DDK,把相应的头文件和库包含进去。
//获取本系统中HID类的GUID标识
HidD_GetHidGuid(&HidGuid);
HDEVINFOhDevInfo;
HANDLE
// 准备查找符合HID规范的USB设备
hDevInfo=SetupDiGetClassDevs
(&HidGuid,
NULL,
NULL,
DIGCF_PRESENT
[解决办法]
DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
MessageBox("符合HID规范的USB设备发生错误");
SetupDiDestroyDeviceInfoList(hDevInfo);
return false;
}
DWORDMemberIndex = 0;
BOOLbSuccess = false;
SP_DEVICE_INTERFACE_DATADeviceInterfaceData;
DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
do
{
bSuccess = SetupDiEnumDeviceInterfaces
(hDevInfo,//已安装的HID设备的信息集的句柄
NULL,
&HidGuid,//HID类设备的GUID
MemberIndex,//起始索引号,函数会自动增加
&DeviceInterfaceData);//用以保存单个设备的信息
if ((!bSuccess) && (GetLastError() == ERROR_NO_MORE_ITEMS))
{
//if(MemberIndex == 0)
//MessageBox("抱歉,未找到可用的USB HID设备!");
//else
//MessageBox("没有更多的可用的USB HID设备!");
SetupDiDestroyDeviceInfoList(hDevInfo);
hHidHandle=NULL;
bIsHIDCon=false;
return false;
}
//若找到了一个USB设备,则获取该设备的细节信息
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData;
DWORD Length = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo,
&DeviceInterfaceData,
NULL,
0,
&Length,
NULL);
pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //MUST BE!!!
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,
&DeviceInterfaceData,
pDeviceInterfaceDetailData,
Length,
NULL,
NULL))
{
MessageBox("查找路径设备时出错!");
DisplayError();
free(pDeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
}
else
//先以查询的方式打开设备句柄
hHidHandle = CreateFile(pDeviceInterfaceDetailData->DevicePath ,
0, //0为查询方式,GENERIC_READ
[解决办法]
GENERIC_WRITE为读写
FILE_SHARE_READ
[解决办法]
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hHidHandle == INVALID_HANDLE_VALUE)
{
MessageBox("无法打开设备");
DisplayError();
free(pDeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return false;
}
else
{
HIDD_ATTRIBUTES Attributes;
HidD_GetAttributes(hHidHandle,&Attributes);
//将有关该设备的标识显示出来
HIDP_CAPShidPCaps;
if (Attributes.VendorID == VendorID && Attributes.ProductID == ProductID)
{
//获取设备的权能信息Capabilities.
PHIDP_PREPARSED_DATA pHidpPreparsedData;
/*****************************************************
API函数: HidD_GetPreparsedData
返回: 一个指向缓存区指针,该缓存区包含有设备的权能信息
条件: 由CreateFile返回的句柄.
不需要直接访问缓存区,但HidP_GetCaps和其它API函数需要一个.
********************************************************/
if (!HidD_GetPreparsedData(hHidHandle,&pHidpPreparsedData))
{
MessageBox("获取 HID PREPARED DATA 失败!");
MessageBox("获取 HID 错误!");
DisplayError();
free(pDeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return false;
}
NTSTATUS status = HidP_GetCaps(pHidpPreparsedData,&hidPCaps);
if (status == HIDP_STATUS_SUCCESS)
{
//以UsagePage和Usage ID判断,这个需要先定出来
if( hidPCaps.UsagePage==UsagePage && hidPCaps.Usage==UsageID )
{
//找到设备后则以读写的方式打开以进行操作
CloseHandle(hHidHandle);
hHidHandle = CreateFile(pDeviceInterfaceDetailData->DevicePath ,
GENERIC_READ
[解决办法]
GENERIC_WRITE, //0为查询方式,GENERIC_READ
[解决办法]
GENERIC_WRITE为读写
FILE_SHARE_READ
[解决办法]
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
strHIDPath=pDeviceInterfaceDetailData->DevicePath;
/*
此处进行操作
*/
free(pDeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return true;
}
}
}
//释放句柄资源
CloseHandle(hHidHandle);
}
MemberIndex++;
} while(bSuccess);
[解决办法]
.
[解决办法]
可以看一下USB Complete,写得很详细,但是英文的。有中文版,但是翻译各很差,有不少错漏。你可以看一下关于人机接口设备的应用程序的那章。你的下位机应该也是写成HID类。最重要的是先把设备枚举出来。
[解决办法]
看你怎么用USB,难在硬件选型上。看你是做设备还是做一个简单的接口,是采用带内核的芯片,还是不带内核的外围芯片。
一般地,芯片选定之后,芯片厂家都会提供一个驱动程序,或者DLL,直接与之接口即可。
[解决办法]
用SETUPAPI
[解决办法]
USB通讯其实麻烦的下位机固件程序,虽然芯片厂商一般会提供一个框架程序,但数据的传输机制还得自己定义
上位机设备驱动相对简单,因为usbd.sys总线驱动已经为我们完成了很多工作,第一次做可以参照ddk例子改个~
个人经验觉得首要还需理解usb2.0协议,USB Complete有时间也最好看看,对usb相关的GUID,注册表讲得很好~
[解决办法]
顶一下