如何使用DELPHI与USB设备进行通讯

下面是访问USB设备的类单元文件:
{
Usb通讯操作助手
Date:2008-7-10
Version:1.0
Author:zlz(47953@163)
}
unit TUsbUtil_U;
interface
uses Windows,Messages,SysUtils,Variants,Classes,
StdCtrls,Dialogs,SetupApi;
const
MAX_PATH=260;//文件名最大长度
MAX_DATA_BUFFER=1024;//缓冲区大小
Type
//数据缓存
TDataBuffer=record
DataBuffer:array[0..MAX_DATA_BUFFER]of byte;//缓存数据
DataSize:Integer;//缓存数据长度
end;
//串口操作助手
TUsbUtil=class(TObject)
public
function Open(usbguid:String):boolean;//打开USB设备
procedure Close();//关闭USB设备
procedure WriteBytes(bs:TDataBuffer);//向USB设备发送字节数组
function ReadBytes():TDataBuffer;//从USB设备读取数据
private
hUsbHandle:THandle;
//打开一个设备
function OpenOneDevice(hDvcInfo:HDEVINFO;DvcInfoData:PSPDeviceInterfaceData; sDevNameBuf:pchar):THandle;
//打开指定的USB设备
function OpenUsbDevice(pGuid:TGUID;sDevNameBuf:pchar):THandle;
end;
implementation
{TUsbUtil}
procedure TUsbUtil.Close;
begin
CloseHandle(hUsbHandle);
end;
function TUsbUtil.Open(usbguid:String):boolean;
var
DeviceName:array[0..MAX_PATH]of char;
USB_GUID:TGUID;
begin
Result:=false;
USB_GUID:=StringToGuid('{'+usbguid+'}');
hUsbHandle:=OpenUsbDevice(USB_GUID,DeviceName);
if(hUsbHandle=INVALID_HANDLE_VALUE)then
begin
raise Exception.Create('无法打开指定的USB设备');
end;
Result:=True;
end;
function TUsbUtil.OpenOneDevice(hDvcInfo:HDEVINFO;
DvcInfoData:PSPDeviceInterfaceData;sDevNameBuf:pchar):THandle;丰年虫
var
iReqLen:pdword;
iDevDataLen:DWord;
pDevData:PSPDeviceInterfaceDetailDataA;
hOut:THandle;
begin
hOut:=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))then
begin
strcopy(sDevNameBuf,pDevData.DevicePath);
hOut:=CreateFile(pDevData.DevicePath,GENERIC_WRITE or GENERIC_READ, FILE_SHARE_WRITE or FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
end;
FreeMem(pDevData);
Result:=hOut;
end;
function TUsbUtil.OpenUsbDevice(pGuid:TGUID;sDevNameBuf:pchar):THandle;
var
hDevInfo1:HDEVINFO;
deviceInfoData:TSPDeviceInterfaceData;
nGuessCount:Dword;
iDevIndex:DWord;
hOut:THandle;
begin
hDevInfo1:=SetupDiGetClassDevs(@pGuid,nil,0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
deviceInfoData.cbSize:=sizeof(TSPDeviceInterfaceData);
nGuessCount:=MAXLONG;
for iDevIndex:=0to nGuessCount do
begin
if(SetupDiEnumDeviceInterfaces(hDevInfo1,nil,pGuid,iDevIndex,deviceInfoData))then
begin
hOut:=OpenOneDevice(hDevInfo1,@deviceInfoData,sDevNameBuf);
if(hOut<>INVALID_HANDLE_VALUE)then
begin
break;
end
else if(GetLastError()=ERROR_NO_MORE_ITEMS)then
begin
break;
end;
end;
end;
SetupDiDestroyDeviceInfoList(hDevInfo1);
Result:=hOut;
end;
function TUsbUtil.ReadBytes:TDataBuffer;
var
nBytesReaded:LongWord;
ktp晶体
bs:TDataBuffer;
begin
ReadFile(self.hUsbHandle,bs.DataBuffer,MAX_DATA_BUFFER,nBytesReaded,nil);
江杨清
bs.DataSize:=nBytesReaded;
Result:=bs;
procedure TUsbUtil.WriteBytes(bs:TDataBuffer);
var
nBytesWritten:LongWord;
begin
WriteFile(self.hUsbHandle,bs.DataBuffer,bs.DataSize,nBytesWritten,nil);
end;
end.
有了上面的类就可以与USB设备进行通讯了
procedure TUsbUtil.Test;
var
bs:TDataBuffer;
objUsb:TUsbUtil;
begin
objUsb:=TUsbUtil.Create();
乔伊斯
//打开USB设备,参数是驱动程序的GUID值,这里我乱写的数
objUsb.Open('A5DCBF10-6530-11D2-901F-00C04FB951ED');
//写入数据
bs.DataBuffer[0]:=$1B;
bs.DataBuffer[1]:=$10;
bs.DataBuffer[2]:=$00;
bs.DataBuffer[3]:=$00;
bs.DataBuffer[4]:=$05;
电子商务安全bs.DataBuffer[5]:=$44;
bs.DataBuffer[6]:=$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的实现部分,规定了这个函数的具体参数和
2.USB设备驱动
①硬件接口
a.需要识别Vender ID和Product ID
b.对每个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_MACHINE\\SYSTEM\\ControlSet001\\Enum\\USB\\Vid_厂家标识&Pid_产品标识\\驱动程序"
王劲屹里面的ClassGUID就是驱动程序的GUID标识,例如{36FC9E60-C465-11CF-8056-444553540000}
相当于程序的:DEFINE_GUID(USB_DRIVER_GUID, 0x36FC9E60,0xC465,0x11CF,0x80,0x56,0x44,0x45,0x53,0x54,0x00,0x00);
另外在这个注册表键里面还可到有关设备的其他描述,例如DeviceDesc="USB Mass Storage Device"等

本文发布于:2024-09-25 02:27:29,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/233307.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:设备   驱动程序   硬件   驱动
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议