USB通讯的尝试

转载 2015年07月07日 15:40:15

转发的,受益匪浅,感谢原作者!!!

下载了一个不知道谁写的UsbPort代码,里面不相干的文件很多,有用的就几行(代码错误得一塌糊涂,必须初始化的变量没初始化,“==号”写成“=号”,……),历经多次失败终于运行正确,步骤如下:
1. 去微软网站下载WinDDK,现改名叫WDK,最新版本是GRMWDK_EN_7600_1.ISO,安装它。因为必须的文件hidsdi.h,hidpi.h,hidusage.h,hid.lib, hidclass.lib, hidparse.lib在VC中没自带。
2. 将WDK安装目录加入到VC设定中,加入到工程设定中是没用的
   menu:Tools/Options/Projects and Solutions/VC++ Directories,右边Show directories for中选择Include files,将两个目录添加进去,顺序如下:
   C:/WinDDK/7600.16385.1/inc/ddk
   $(VCInstallDir)include
   $(VCInstallDir)atlmfc/include
   C:/WinDDK/7600.16385.1/inc/api
   $(WindowsSdkDir)/include
   $(FrameworkSDKDir)include
   即保证 C:/WinDDK/7600.16385.1/inc/api 在 $(WindowsSdkDir)/include 前面,这样#include <windows.h>等才用的是WDK中的文件,否则不匹配导致编译失败。
   menu:Tools/Options/Projects and Solutions/VC++ Directories,右边Show directories for中选择Library files,添加 C:/WinDDK/7600.16385.1/lib/wxp/i386
3. 修改后的代码如下:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <setupapi.h>
#pragma comment( lib, "setupapi.lib" )
extern "C" {
#include <hidsdi.h>
}
#pragma comment( lib, "hid.lib" )

#define ShowError() ShowError_(_T(__FILE__),__LINE__)
void ShowError_(LPCTSTR file, long line)
{
    LPVOID lpMsgBuf;
    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS
        , NULL, GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, NULL );
    _tprintf( _T("---ERROR %s(%ld): %s/n"), file, line, (LPCTSTR)lpMsgBuf );
    LocalFree( lpMsgBuf );
}

int main()
{
    GUID guidHID;
    HidD_GetHidGuid( &guidHID );
    _tprintf( _T("HID GUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}/n")
        , guidHID.Data1, guidHID.Data2, guidHID.Data3
        , guidHID.Data4[0], guidHID.Data4[1], guidHID.Data4[2], guidHID.Data4[3], guidHID.Data4[4]
        , guidHID.Data4[5], guidHID.Data4[6], guidHID.Data4[7] );

    HDEVINFO hDevInfo = SetupDiGetClassDevs( &guidHID, NULL, 0, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE );
    if( INVALID_HANDLE_VALUE != hDevInfo )
    {
        SP_DEVICE_INTERFACE_DATA strtInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
        for( DWORD index=0; SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guidHID,index,&strtInterfaceData); ++index )
        {
            char buf[1000];
            SP_DEVICE_INTERFACE_DETAIL_DATA& strtDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA&)buf[0];
            strtDetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if( SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,&strtDetailData,_countof(buf),NULL,NULL) )
            {
                _tprintf( _T("[%d] path: %s/n"), index, strtDetailData.DevicePath );

                HANDLE hUsb = CreateFile( strtDetailData.DevicePath, 0//GENERIC_READ|GENERIC_WRITE
                    , FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
                if( INVALID_HANDLE_VALUE != hUsb )
                {
                    // 查询设备标识
                    HIDD_ATTRIBUTES strtAttrib = { sizeof(HIDD_ATTRIBUTES) };
                    if( HidD_GetAttributes(hUsb,&strtAttrib) )
                    {
                        _tprintf( _T("VendorID : %hX/n"), strtAttrib.VendorID );
                        _tprintf( _T("ProductID: %hX/n"), strtAttrib.ProductID );
                        _tprintf( _T("VerNumber: %hX/n"), strtAttrib.VersionNumber );
                    }
                    else
                        ShowError();

                    CloseHandle( hUsb );
                }
                else
                    ShowError();
            }
            else
                ShowError();
        }
        if( GetLastError() != ERROR_NO_MORE_ITEMS )
            ShowError();

        SetupDiDestroyDeviceInfoList( hDevInfo );
    }
    else
        ShowError();

    return 0;
}


假如不想下载庞大的WDK包,我打包了必须的文件(XP系统),连同测试工程,下载地址为:http://blog.vckbase.com/Files/bruceteen/USBTest.zip
使用API操作USB太麻烦了,[七猫]告诉我可以用LibUSB-Win32(http://sourceforge.net/apps/trac/libusb-win32/wiki
a. 调用usb_init函数,进行初始化
b. 调用usb_find_busses、usb_find_devices和usb_get_busses这三个函数获得已找到的USB总线序列;然后通过链表遍历所有的USB设备,根据已知的要打开USB设备的ID(VID/PID),找到相应的USB设备;最后调用usb_open函数打开该USB设备(在这里假设总线上没有相同VID和PID的USB设备。如果总线上存在着相同VID和PID的设备,还需要进行其他条件判断,比如设备名称,以保证是打开的是期望的USB设备)。
c. 使用usb_control_msg函数与USB设备进行通信,向USB设备读取数据或写入数据。
d. 关闭USB设备。

相关文章推荐

USB通讯的尝试

转载自http://blog.vckbase.com/bruceteen/archive/2010/12/17/52208.html 下载了一个不知道谁写的UsbPort代码,里面不相干的文件很...

如何使用CC2540 USB-Dongle进行抓取蓝牙通讯数据包

参考链接:http://blog.csdn.net/mzy202/article/details/32408223 一、实验目的 1、利用CC2540 USB-Dongle来抓取蓝牙主机与从机之间...

基于Linux的USB 主/从设备之间通讯的三种方式

转载:http://archive.eet-china.com/www.eet-china.com/ART_8800323770_617693_TA_eda530e7.HTM 随着简单易用的USB接口...
  • yyxyong
  • yyxyong
  • 2017年03月17日 18:49
  • 814

安卓开发中的USB转串口通讯

安卓开发中的USB转串口通讯本文使用GitHub上开源的”hoho.android.usbserial”USB串口库。该库基于“Android USB Host API”,驱动完全由java开发,无需...
  • STchaoL
  • STchaoL
  • 2017年05月24日 21:28
  • 530

USB协通讯议--深入理解

转自:http://blog.csdn.net/myarrow

Android与PC通过USB通讯

最近在调研Android和PC通过USB连接的相关项目,这里我们结合ADT插件的重要开发工具DDMS中的源码进行分析。在android git中的sdk.git文件中,可以找到ddmlib这个文件夹。...

如何通过xcode编程使MAC机器和HID的USB单片机设备进行通讯

之前大家会通过苹果IOKIT的框架里面的教程进行编程,但是z
  • czl0325
  • czl0325
  • 2014年09月03日 09:06
  • 3082

了解USB的通讯过程

USB的两根信号线负责与总线上的设备交换数据。这些电缆形成了所有设备必须共享的惟一的一条传输通路。 RS-232有一条Tx线用来传输一个方向的数据,一条Rx线用来传输另一个方向的数据。与RS-232不...

C# USB通讯

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:USB通讯的尝试
举报原因:
原因补充:

(最多只允许输入30个字)