2022年如何使用DELPHI与USB设备进行通讯 .pdf
下面是访问USB 设备的类单元文件:Usb 通讯操作助手Date:2008-7-10Version: 1.0Author:zlz ()unit TUsbUtil_U;interfaceusesWindows, Messages,SysUtils, Variants, Classes,StdCtrls,Dialogs,SetupApi;constMAX_PATH= 260;/文件名最大长度MAX_DATA_BUFFER= 1024;/缓冲区大小Type/数据缓存TDataBuffer = recordDataBuffer:array0.MAX_DATA_BUFFERof byte;/缓存数据DataSize :Integer;/缓存数据长度end;/串口操作助手TUsbUtil= class(TObject)publicfunction Open(usbguid:String) :boolean;/打开 USB 设备procedure Close();/关闭 USB 设备procedure WriteBytes(bs:TDataBuffer);/向 USB 设备发送字节数组function ReadBytes():TDataBuffer;/从 USB 设备读取数据privatehUsbHandle :THandle;/打开一个设备functionOpenOneDevice(hDvcInfo:HDEVINFO;DvcInfoData:PSPDeviceInterfaceData;sDevNameBuf:pchar) :THandle;/打开指定的USB 设备function OpenUsbDevice(pGuid :TGUID; sDevNameBuf :pchar):THandle;end;implementation TUsbUtil 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 5 页 - - - - - - - - - procedure TUsbUtil.Close;beginCloseHandle(hUsbHandle);end;function TUsbUtil.Open(usbguid:String): boolean;varDeviceName: array0.MAX_PATHof char;USB_GUID: TGUID;beginResult := false;USB_GUID := StringToGuid( + usbguid + );hUsbHandle := OpenUsbDevice(USB_GUID,DeviceName);if (hUsbHandle = INVALID_HANDLE_VALUE)thenbeginraise Exception.Create(无法打开指定的USB 设备 );end;Result := True;end;function TUsbUtil.OpenOneDevice(hDvcInfo:HDEVINFO;DvcInfoData: PSPDeviceInterfaceData; sDevNameBuf: pchar): THandle;variReqLen :pdword;iDevDataLen : DWord;pDevData : PSPDeviceInterfaceDetailDataA ;hOut: THandle;beginhOut := INVALID_HANDLE_VALUE;iReqLen := pdword(integer(0);SetupDiGetDeviceInterfaceDetail(hDvcInfo,DvcInfoData,nil, 0, iReqLen, nil);iDevDataLen := DWORD(integer(iReqLen);GetMem(pDevData, iDevDataLen);pDevData.cbSize := sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);if(SetupDiGetInterfaceDeviceDetail(hDvcInfo,DvcInfoData,pDevData,iDevDataLen,iReqLen, nil) thenbeginstrcopy(sDevNameBuf, pDevData.DevicePath);hOut:=CreateFile(pDevData.DevicePath,GENERIC_WRITEorGENERIC_READ,FILE_SHARE_WRITEor FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);end;FreeMem(pDevData);名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 5 页 - - - - - - - - - Result := hOut;end;function TUsbUtil.OpenUsbDevice(pGuid:TGUID; sDevNameBuf: pchar): THandle;varhDevInfo1 : HDEVINFO;deviceInfoData : TSPDeviceInterfaceData ;nGuessCount : Dword;iDevIndex :DWord;hOut: THandle;beginhDevInfo1:=SetupDiGetClassDevs(pGuid,nil,0,DIGCF_PRESENTorDIGCF_DEVICEINTERFACE);deviceInfoData.cbSize := sizeof(TSPDeviceInterfaceData);nGuessCount := MAXLONG;for iDevIndex :=0 to nGuessCount dobeginif(SetupDiEnumDeviceInterfaces(hDevInfo1,nil,pGuid,iDevIndex,deviceInfoData)thenbeginhOut := OpenOneDevice(hDevInfo1, deviceInfoData, sDevNameBuf);if (hOut INVALID_HANDLE_VALUE)thenbeginbreak;endelse if (GetLastError() = ERROR_NO_MORE_ITEMS)thenbeginbreak;end;end;end;SetupDiDestroyDeviceInfoList(hDevInfo1);Result := hOut;end;function TUsbUtil.ReadBytes: TDataBuffer;varnBytesReaded:LongWord;bs: TDataBuffer;beginReadFile(self.hUsbHandle,bs.DataBuffer,MAX_DATA_BUFFER,nBytesReaded,nil);bs.DataSize :=nBytesReaded;Result := bs;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 5 页 - - - - - - - - - end;procedure TUsbUtil.WriteBytes(bs:TDataBuffer);varnBytesWritten:LongWord;beginWriteFile(self.hUsbHandle,bs.DataBuffer, bs.DataSize,nBytesWritten, nil);end;end.有了上面的类就可以与USB 设备进行通讯了procedure TUsbUtil.Test;varbs:TDataBuffer;objUsb:TUsbUtil;beginobjUsb :=TUsbUtil.Create();/打开 USB 设备 ,参数是驱动程序的GUID 值, 这里我乱写的数objUsb.Open(A5DCBF10-6530-11D2-901F-00C04FB951ED);/写入数据bs.DataBuffer0 := $1B;bs.DataBuffer1 := $10;bs.DataBuffer2 := $00;bs.DataBuffer3 := $00;bs.DataBuffer4 := $05;bs.DataBuffer5 := $44;bs.DataBuffer6 := $D0;bs.DataSize := 7;objUsb.WriteBytes(bs);/读取数据bs := objUsb.ReadBytes();/关闭设备objUsb.Close();end;USB 设备、 USB 驱动、 USB 应用程序1.USB 设备硬件部分a.这个硬件的标识是用的Vender ID 和 Product ID, 即“厂家标识”和“产品标识”b. 这 个 硬 件 规 定 了 各 个End Point ( 端 点 )的 性 质 ,读 / 写及类 型(Control/Interrupt/Bulk/Isochronous)c.这个硬件的固件里面有DeviceIoControl的实现部分 , 规定了这个函数的具体参数和名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 5 页 - - - - - - - - - 动作2.USB 设备驱动硬件接口a.需要识别VenderID和 Product IDb.对每个EndPoint 的每个I/O 分配一个Pipe, 并且起一个名字作为软件接口c.做 DeviceIoControl的接口软件接口a.GUID,驱动程序的标识, 每个驱动程序使用不同的GUID, GUID是识别驱动的, 与硬件无关(驱动程序升级版本GUID不能修改 )b.硬件接口里面的b: Pipe 名字是软件接口, 这个Pipe 名字纯粹由驱动定义的, 和硬件无关 , 升级驱动不能改Pipe 的名字c.硬件接口里面的c 的各个参数也是软件的接口, 这些参数是由硬件带来的, 不是驱动规定的 , 当然也可以在驱动里面转义, 隐藏设备的真实情况这个驱动程序是用WinDDK编译的 , 可以用文本编辑器或其他开发工具的编辑器编程序代码 , 然后调用WinDDK编译3.读写USB 口的程序与驱动的接口a.利用驱动程序里面的GUID找出设备的文件名, 用 CreateFile 函数打开设备。我前面的程序里面的OpenUsbDevice 就是这个作用b.通过a.得到的设备文件名和驱动程序里面的Pipe 名打开Pipe, 访问这个Pipe 对应的 USB 端点(读写数据 )c.使用a.的 CreateFile 得到的句柄 , 通过DeviceIoControl实现设备规定的动作有关需要的资料a.Vender ID, Product ID和 GUID一般在驱动程序的.inf 文件里面能看到, 如果找不到就需要和厂家联系b.Pipe 的名字是驱动程序规定的, 需要有驱动程序的资料才能知道c.DeviceIoControl的参数需要有驱动程序的资料或者硬件资料才能知道这个程序一般用C/C+ 直接编写 , 如果使用其他语言(VB/PB 等)需要调用C/C+ 编的DLL其他相关内容 :USB 驱动程序可以到注册表里面找到:HKEY_LOCAL_MACHINESYSTEMControlSet001EnumUSBVid_厂 家 标 识 &Pid_ 产品标识驱动程序 里面的ClassGUID就是驱动程序的GUID标识,例如36FC9E60-C465-11CF-8056-444553540000相当于程序的:DEFINE_GUID(USB_DRIVER_GUID,0 x36FC9E60,0 xC465,0 x11CF,0 x80,0 x56,0 x44,0 x45,0 x53,0 x54,0 x00,0 x00);另外在这个注册表键里面还可找到有关设备的其他描述, 例如DeviceDesc = USB MassStorage Device 等名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 5 页 - - - - - - - - -