打印
[USB编程]

STM32 USB-HID请教

[复制链接]
935|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
19840312|  楼主 | 2019-10-21 12:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   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;
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎咨询: 需要 步进电机 驱动器,找我!专业的一体化步进电机驱动控制器 www.bj7te.com 承接电机控制相关项目 承接光电相关项目 承接单片机相关项目

28

主题

137

帖子

0

粉丝