usb设备是用的stm32f105,HID协议,上位机软件在WIN7,xp系统都能正常工作,并且做了HID设备插拔监测,重新插上后会自动找HID设备,再连上,继续工作。
现在的问题,上位机软件在Win10系统下,软件打开,能发数据到hid设备,hid设备的数据到电脑端,电脑端
收不到,但是把hid设备的usb从电脑拔掉重新插上,收发数据就能正常了,下面附上查找设备的代码
BOOL CUsbHidToolDlg::FindHIDDevice(void)
{
//
GUID HidGuid;
HANDLE hDevInfo;
SP_DEVICE_INTERFACE_DATA DevInterfaceData;
//------从操作系统中获取HID的磁盘信息
HidD_GetHidGuid(&HidGuid); //setupapi.h
//------枚举系统中所有的HID设备信息 link中添加 setupapi.lib hid.lib 其中hid.lib注意目录
hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if (hDevInfo != NULL) printf("找到HID设备:\r\n");
else{
printf("没有找到HID设备:\r\n");
return FALSE;
}
//------
DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
hEventObject = NULL;//事件句柄清零
//------
for (int index = 0;; index++)
{//遍历所有的HID设备
//---获取HID设备, 如果返回0,则没有更多的HID
BOOL bSuccess = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, index, &DevInterfaceData);
if (bSuccess == FALSE){//
printf("-->没有找到 VID=%x PID =%x设备", mHIDVendorID, mHIDProductID);
return FALSE;
}
//---获取当前HID设备的详细信息需要占用的内存空间
DWORD RequiredLength;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, NULL, 0, &RequiredLength, NULL);
mHidDeviceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(RequiredLength);
mHidDeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
//---获取当前HID设备的详细信息(将分配的内存空间去获取信息)
bSuccess = SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, mHidDeviceDetailData, RequiredLength, NULL, NULL);
if (bSuccess == FALSE)
{
delete mHidDeviceDetailData;
continue;
}
printf("-->设备路径:%S\r\n", mHidDeviceDetailData->DevicePath);
HANDLE m_DeviceHandle;
HIDD_ATTRIBUTES HidAttributes;
m_DeviceHandle = CreateFile(mHidDeviceDetailData->DevicePath,//CreateFile((LPCSTR)mHidDeviceDetailData->DevicePath,
0,//零,表示只允许获取与一个设备有关的信息
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,//
NULL);
if (m_DeviceHandle == INVALID_HANDLE_VALUE)
{
printf(" -->:无效HID设备");
CloseHandle(m_DeviceHandle);
delete mHidDeviceDetailData;
continue;
}//end if (m_DeviceHandle ==INVALID_HANDLE_VALUE)
if (!HidD_GetAttributes(m_DeviceHandle, &HidAttributes))
{//HID属性
printf(" -->:无效HID设备属性");
CloseHandle(m_DeviceHandle);
delete mHidDeviceDetailData;
continue;
}
if ((mHIDProductID != HidAttributes.ProductID) || (mHIDVendorID != HidAttributes.VendorID))
{
CloseHandle(m_DeviceHandle);
delete mHidDeviceDetailData;
continue;
}
//...........找到需要的PID VID 显示PID VID
mDevicePathName = mHidDeviceDetailData->DevicePath;
printf("找到HID设备:\r\n");
printf(" -->设备路径:"); printf("%S\r\n" ,mDevicePathName);
printf(" -->设备信息:PID=[0x%x] VID=[0x%x] 版本[%x]\r\n",mHIDProductID,mHIDVendorID,HidAttributes.VersionNumber);
//获取设备厂家
wchar_t mChar[128]; char CharBuffer[256];
HidD_GetManufacturerString(m_DeviceHandle, mChar, 128);
WideCharToMultiByte(CP_ACP, NULL, mChar, 128, CharBuffer, 256, NULL, NULL);
mManufacturer.Format(_T("%s"), mChar); //DisplayInfor(_T(" -->设备厂家:") + mManufacturer);
SetDlgItemText(IDC_STATIC_MANUFACT, _T("设备厂家:") + mManufacturer);
printf(" -->设备厂家:%s\r\n", CharBuffer);
//获取产品名称
HidD_GetProductString(m_DeviceHandle, mChar, 128);
WideCharToMultiByte(CP_ACP, NULL, mChar, 128, CharBuffer, 256, NULL, NULL);
ProductString.Format(_T("%s"), mChar); //DisplayInfor(_T(" -->产品名称:") + ProductString);
SetDlgItemText(IDC_STATIC_PRODUCT, _T("产品名称:") + ProductString);
printf(" -->设备厂家:%s\r\n", CharBuffer);
//获取HID Report相关信息
HidD_GetPreparsedData(m_DeviceHandle, &m_HidPreparsedData);
NTSTATUS status = HidP_GetCaps(m_HidPreparsedData, &m_HidpCaps);
if (status == HIDP_STATUS_SUCCESS)
{
printf(" -->输入报告长度:%d\r\n",m_HidpCaps.InputReportByteLength);
printf(" -->输出报告长度:%d\r\n",m_HidpCaps.OutputReportByteLength);
}
CloseHandle(m_DeviceHandle);
//....创建 输入输出报告的 读取句柄
m_USBDeviceWriteHandle = CreateFile(mHidDeviceDetailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,//FILE_FLAG_OVERLAPPED
NULL);
DWORD erro = GetLastError();
printf(" -->m_USBDeviceWriteHandle:%d erro[%d]\r\n",m_USBDeviceWriteHandle, erro);
//....Get a handle to the device for the overlapped ReadFiles.
m_USBDeviceReadHandle = CreateFile(mHidDeviceDetailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0, //FILE_FLAG_OVERLAPPED:允许对文件进行重叠操作
NULL);
unsigned long mNumInputBuffers=0;
unsigned char Res;
Res = HidD_GetNumInputBuffers(m_USBDeviceReadHandle, &mNumInputBuffers);
erro = GetLastError();
printf(" -->m_USBDeviceReadHandle:%d erro[%d]\r\n",m_USBDeviceReadHandle, erro);
//--创建 HID设备的事件句柄
if (hEventObject == NULL)
{
hEventObject = CreateEvent(NULL,TRUE,TRUE,NULL);
HIDOverlapped.hEvent = hEventObject;// 在转移完成时处理一个事件设置为有信号状态
HIDOverlapped.Offset = 0;
HIDOverlapped.OffsetHigh = 0;
}
//--注册设备
HDEVNOTIFY DeviceNotificationHandle;
DevBroadcastDeviceInterface.dbcc_size = sizeof(DevBroadcastDeviceInterface);
DevBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
DevBroadcastDeviceInterface.dbcc_classguid = HidGuid;
DeviceNotificationHandle = RegisterDeviceNotification(m_hWnd, &DevBroadcastDeviceInterface, DEVICE_NOTIFY_WINDOW_HANDLE);
//--获取HID设备的事件句柄
SetupDiDestroyDeviceInfoList(hDevInfo);
delete mHidDeviceDetailData;
break;
}//end for(int index=0;;index++)
//------
return TRUE;
}
|