求教:BCB如何与USB通信(有例子)

sam200401 2010-03-09 10:35:03

我想与USB设备通信,在网上找到很多文件都没能实现,下面程式是我在网上抄来在BCB中试验,编译可以通过,但还是打不开USB设备。请大虾们帮忙看看那里出错,我只想要打开USB的句柄,并向其他指令(后面要做的事)。


//##Unit1.h中的定义开始##
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

//#define WINVER 0x0500
#include <windows.h>
#include <setupapi.h>
#include <basetyps.h>
#include <D:\C++\usb.h\usbdi.h>
#include <initguid.h>
#include <stdio.h>

#pragma comment(lib,"C:\Program Files\Borland\CBuilder6\Lib\Psdk\setupapi.lib")
#pragma comment(lib,"D:\C++\上位机程序1.2\hid.lib")
#pragma comment(lib,"C:\Program Files\Borland\CBuilder6\Lib\Psdk\comctl32.lib")

#ifndef BULKUSBH_INC
#define BULKUSBH_INC
#endif

#define BULKUSB_IOCTL_INDEX 0x0000


#define IOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, \
BULKUSB_IOCTL_INDEX,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

#define IOCTL_BULKUSB_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, \
BULKUSB_IOCTL_INDEX+1,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

#define IOCTL_BULKUSB_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, \
BULKUSB_IOCTL_INDEX+2,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)


extern HANDLE open_file(char *filename);
extern int GetUsbPath(char *path);
extern int WriteUsb(HANDLE hUsb,char *Outbuff, int len);
extern int ReadUsb(HANDLE hUsb,BYTE inbuff[],DWORD &nBytesRead,int nToRead);



//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


//##Unit1.h完##


///##Unit1.cpp内容开始##
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

//8a3bf75d-83c7-440e-8276-5ae3f3ea6e77
//DEFINE_GUID(GUID_CLASS_I82930_BULK,0x8a3bf75d, 0x83c7, 0x440e,0x82, 0x76, 0x5a, 0xe3, 0xf3, 0xea, 0x6e, 0x77);

//{d6c5066e-72c1-11d2-9755-0000f8004788}
//DEFINE_GUID(GUID_CLASS_I82930_BULK,0xd6c5066e, 0x72c1, 0x11d2,0x97, 0x55, 0x00, 0x00, 0xf8, 0x00, 0x47, 0x88);

//{4D36E96B-E325-11CE-BFC1-08002BE10318} 标准键盘
DEFINE_GUID(GUID_CLASS_I82930_BULK,0x4D36E96b, 0xE325, 0x11CE,0xbf,0xc1,0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18);


BOOL GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf);
HANDLE OpenUsbDevice( LPGUID pGuid, char *outNameBuf);
//HANDLE OpenOneDevice (HDEVINFO HardwareDeviceInfo, PSP_INTE
HANDLE OpenOneDevice ( IN HDEVINFO HardwareDeviceInfo, IN PSP_INTERFACE_DEVICE_DATA DeviceInfoData, IN char *devName );
int WriteUsb(HANDLE hUsb,char *Outbuff, int len);
//int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead),RFACE_DEVICE_DATA DeviceInfoData,char *devName);
int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead) ;

int GetUsbPath(char *path);





//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

/*名称:open_file
功能:打开USB设备
参数:filename 定义为”PIPE00” pipe name for bulk input pipe on our test board ,”PIPE01” pipe name for bulk output pipe on our test board。
PIPE00 和 PIPE01 是参考src\usb\bulkusb,我实际在用时这两个效果一样,为了避免USB异常引起的死机,我文件打开采用非阻塞模式。
*/
HANDLE open_file( char *filename)
{

int success = 1;
HANDLE h;
char completeDeviceName[256] = ""; //generated from the GUID registered by the driver itself

if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_I82930_BULK,completeDeviceName) )
{
//NOISY(("Failed to GetUsbDeviceFileName\n", GetLastError()));
ShowMessage("Failed to GetUsbDeviceFileName");
return INVALID_HANDLE_VALUE;
}

strcat (completeDeviceName, "\\");

strcat (completeDeviceName, filename);

//printf("completeDeviceName = (%s)\n", completeDeviceName);

h = CreateFile(completeDeviceName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);

if (h == INVALID_HANDLE_VALUE) {
//NOISY(("Failed to open (%s) = %d", completeDeviceName, GetLastError()));
success = 0;
} else {
//NOISY(("Opened successfully.\n"));
}

return h;
}




/*名称:GetUsbDeviceFileName
 功能:获取USB设备路径
 参数:pGUID
返回:outNameBuf USB设备路径
*/
BOOL GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf)
{
HANDLE hDev = OpenUsbDevice( pGuid, outNameBuf );
if ( hDev != INVALID_HANDLE_VALUE )
{
ShowMessage("open usb device ok!");
CloseHandle( hDev );
return TRUE;
}
ShowMessage("open usb device ng!");
return FALSE;

}

//下面所有
...全文
1591 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
cptang 2010-11-21
  • 打赏
  • 举报
回复
用nrcomm控件
一步到位

这个控件,www.ccrun.com上貌似有下载

williamsong997 2010-08-31
  • 打赏
  • 举报
回复
楼主这贴分太少了,那些大侠们怎么感兴趣呢?

妖哥一定就可以搞定!
laowang2 2010-07-28
  • 打赏
  • 举报
回复
编译通不过啊
Undefined symbol 'PUSB_DEVICE_DESCRIPTOR'
laowang2 2010-07-28
  • 打赏
  • 举报
回复
我看看,试一试。
lzkyz 2010-07-28
  • 打赏
  • 举报
回复
我也遇到同样的问题,此前这个LIB我在VC里用没有问题,并且下位机USB部分也调试通过,使用C++Builder是因为做曲线方便,但没想到遇到这种问题,正在调试有谁有好办法,谢谢!
sam200401 2010-03-30
  • 打赏
  • 举报
回复
道理容易说,但实操还是不行。
我的程序有什么问题,我只是打开个USB键盘,为什么都不行?

[Quote=引用 8 楼 waiting4you 的回复:]
只要知道USB管道名或GUID,直接CreateFile,然后WriteFile或ReadFile就可以了呀。
其它的一些控制命令用DeviceIoControl。
管道名和控制命令由USB的驱动决定,这个由查你的USB设备资料才行。
你肯定是“PIPE00”吗?
[/Quote]
Waiting4you 2010-03-15
  • 打赏
  • 举报
回复
只要知道USB管道名或GUID,直接CreateFile,然后WriteFile或ReadFile就可以了呀。
其它的一些控制命令用DeviceIoControl。
管道名和控制命令由USB的驱动决定,这个由查你的USB设备资料才行。
你肯定是“PIPE00”吗?
sam200401 2010-03-15
  • 打赏
  • 举报
回复
天啊,没人会啊!
sam200401 2010-03-12
  • 打赏
  • 举报
回复
没人会吗?BCB就这样没落了吗?
xjq2003 2010-03-10
  • 打赏
  • 举报
回复
收藏
引用 4 楼 yeyanbin 的回复:
顶一个!希望楼主下次贴代码的时候插入下面的格式,这样看起来比较爽
C/C++ code//##Unit1.h中的定义开始###ifndef Unit1H#define Unit1H//---------------------------------------------------------------------------#include<Classes.hpp>
#include<Controls.hpp>
#include<StdCtrls.hpp>
#include<Forms.hpp>//#define WINVER 0x0500#include<windows.h>
#include<setupapi.h>
#include<basetyps.h>
#include<D:\C++\usb.h\usbdi.h>
#include<initguid.h>
#include<stdio.h>
.....................
sam200401 2010-03-09
  • 打赏
  • 举报
回复
///##Unit1.cpp内容完##

上面的是程式的全部内容,
我要的是打开设备并"ShowMessage("找到硬件!"); "可以成功。
sam200401 2010-03-09
  • 打赏
  • 举报
回复

//接上


/*名称:GetUsbPath
功能:返回USB设备路径
参数:pGUID
返回:path 路径
*/
int GetUsbPath(char *path)
{
if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_I82930_BULK,path) )
{
return 0;
}
return 1;
}


/*名称:WriteUsb
功能:向USB写数据
参数:hUsb USB句柄,Outbut 数据指针,len 数据长度
*/
int WriteUsb(HANDLE hUsb,char *Outbuff, int len)
{
DWORD nBytesWrite,endtime,lrc;
static OVERLAPPED ol;
DWORD dwErrorMask,dwError;
COMSTAT comstat;
if(hUsb==NULL)
return 0;
ol.Offset=0; //设备使用指定0
ol.OffsetHigh=0; //设备使用指定0
ol.hEvent=NULL; //标识事件为非信号状态,数据传送完成时,它将被设为信号状态
ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!WriteFile(hUsb,Outbuff,len,&nBytesWrite,&ol))
{
//出错信息处理--------------------------------
if((lrc=GetLastError())==ERROR_IO_PENDING)
{
endtime=GetTickCount()+1000;
while(!GetOverlappedResult(hUsb,&ol,&nBytesWrite,FALSE))
{
dwError=GetLastError();
if(GetTickCount()>endtime)
{
MessageBox(NULL,"写串口时间过长,目前串口发送缓冲区中的数据数目为空",NULL,NULL);
break;
}
if(dwError=ERROR_IO_INCOMPLETE)
continue; //未完全读完时的正常返回结果
else
{
// 发生错误,尝试恢复!
break;
}
}
}
//-------------------------------------------------//
}
CloseHandle(ol.hEvent);
FlushFileBuffers(hUsb);
return 1;
}


/*名称:ReadUsb
功能:读取USB设备发来的数据
参数:hUsb USB句柄,nToRead读取的长度
返回:inbuff 读到的数据,nBytesRead 读到的长度
*/
int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead)
{
DWORD lrc; ///纵向冗余校验
DWORD endtime; /////////jiesuo
static OVERLAPPED ol;
int ReadNumber=0;
int numCount=0 ; //控制读取的数目
DWORD dwErrorMask;
DWORD dwEvtMask=0 ;
DWORD ntoread;
int ReadTime;

ReadTime=2000;
ntoread=nToRead;
ol.Offset=0; ///相对文件开始的字节偏移量
ol.OffsetHigh=0; ///开始传送数据的字节偏移量的高位字,管道和通信时调用进程可忽略。
ol.hEvent=NULL; ///标识事件,数据传送完成时设为信号状态
ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!ReadFile(hUsb,inbuff,ntoread,&nBytesRead,&ol))
{
if((lrc=GetLastError())==ERROR_IO_PENDING)
{
///////////////////
endtime=GetTickCount()+ReadTime;//GetTickCount()取回系统开始至此所用的时间(毫秒)
while(!GetOverlappedResult(hUsb,&ol,&nBytesRead,FALSE))//该函数取回重叠操作的结果
{
if(GetTickCount()>endtime)
break;
}
}
}
CloseHandle(ol.hEvent);
return 1;
}










void __fastcall TForm1::Button1Click(TObject *Sender)
{
open_file("PIPE00");
}
//---------------------------------------------------------------------------
sam200401 2010-03-09
  • 打赏
  • 举报
回复

/*名称:OpenUsbDevice
功能:获取USB设备路径
参数:pGUID 设备GUID
返回:outNameBuf USB设备路径
*/
HANDLE OpenUsbDevice( LPGUID pGuid, char *outNameBuf)
{
ULONG NumberDevices;
HANDLE hOut = INVALID_HANDLE_VALUE;
HDEVINFO hardwareDeviceInfo;
SP_INTERFACE_DEVICE_DATA deviceInfoData;
ULONG i;
BOOLEAN done;
PUSB_DEVICE_DESCRIPTOR usbDeviceInst;
PUSB_DEVICE_DESCRIPTOR *UsbDevices = &usbDeviceInst;

*UsbDevices = NULL;
NumberDevices = 0;

//
// Open a handle to the plug and play dev node.
// SetupDiGetClassDevs() returns a device information set that contains info on all
// installed devices of a specified class.
//
hardwareDeviceInfo = SetupDiGetClassDevs (
pGuid,
NULL, // Define no enumerator (global)
NULL, // Define no
(DIGCF_PRESENT | // Only Devices present
DIGCF_INTERFACEDEVICE)); // Function class devices.

//
// Take a wild guess at the number of devices we have;
// Be prepared to realloc and retry if there are more than we guessed
//

if(hardwareDeviceInfo==INVALID_HANDLE_VALUE)
ShowMessage("INVALID_HANDLE_VALUE==hardwareDeviceInfo") ;


NumberDevices = 4;
done = FALSE;
deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

i=0;
while (!done)
{
NumberDevices *= 2;

if (*UsbDevices)
{
*UsbDevices = (PUSB_DEVICE_DESCRIPTOR)realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
}
else
{
*UsbDevices = (PUSB_DEVICE_DESCRIPTOR)calloc (NumberDevices, sizeof (USB_DEVICE_DESCRIPTOR));
}

if (NULL == *UsbDevices)
{

// SetupDiDestroyDeviceInfoList destroys a device information set
// and frees all associated memory.
ShowMessage("OpenUsbDevice ng 1");
SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
return INVALID_HANDLE_VALUE;
}
ShowMessage("OpenUsbDevice ok 1,NumberDevices:="+IntToStr(NumberDevices));
usbDeviceInst = *UsbDevices + i;

for (; i < NumberDevices; i++)
{
ShowMessage(i);
// SetupDiEnumDeviceInterfaces() returns information about device interfaces
// exposed by one or more devices. Each call returns information about one interface;
// the routine can be called repeatedly to get information about several interfaces
// exposed by one or more devices.

if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
0, // We don't care about specific PDOs
pGuid,
i,
&deviceInfoData)) {

hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, outNameBuf);
if ( hOut != INVALID_HANDLE_VALUE )
{
done = TRUE;
ShowMessage("找到硬件!");
break;
}
}
else
{
// ShowMessage("hout ng");
if (ERROR_NO_MORE_ITEMS == GetLastError())
{
done = TRUE;
// ShowMessage(i);
break;
}
}
}
}

NumberDevices = i;

// SetupDiDestroyDeviceInfoList() destroys a device information set
// and frees all associated memory.

SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
free ( *UsbDevices );

return hOut;
}


HANDLE OpenOneDevice (
IN HDEVINFO HardwareDeviceInfo,
IN PSP_INTERFACE_DEVICE_DATA DeviceInfoData,
IN char *devName
)
{
PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = NULL;
ULONG predictedLength = 0;
ULONG requiredLength = 0;
HANDLE hOut = INVALID_HANDLE_VALUE;

//
// allocate a function class device data structure to receive the
// goods about this particular device.
//
SetupDiGetInterfaceDeviceDetail (
HardwareDeviceInfo,
DeviceInfoData,
NULL, // probing so no output buffer yet
0, // probing so output buffer length of zero
&requiredLength,
NULL); // not interested in the specific dev-node


predictedLength = requiredLength;
// sizeof (SP_FNCLASS_DEVICE_DATA) + 512;

functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc (predictedLength);
functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);

//
// Retrieve the information from Plug and Play.
//
if (! SetupDiGetInterfaceDeviceDetail (
HardwareDeviceInfo,
DeviceInfoData,
functionClassDeviceData,
predictedLength,
&requiredLength,
NULL)) {
free( functionClassDeviceData );
return INVALID_HANDLE_VALUE;
}

strcpy( devName,functionClassDeviceData->DevicePath) ;
//printf( "Attempting to open %s\n", devName );

hOut = CreateFile (
functionClassDeviceData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // no SECURITY_ATTRIBUTES structure
OPEN_EXISTING, // No special create flags
0, // No special attributes
NULL); // No template file

if (INVALID_HANDLE_VALUE == hOut)
{
//printf( "FAILED to open %s\n", devName );
}
free( functionClassDeviceData );
return hOut;
}
YeBinYe 2010-03-09
  • 打赏
  • 举报
回复
顶一个!希望楼主下次贴代码的时候插入下面的格式,这样看起来比较爽

//##Unit1.h中的定义开始##
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

//#define WINVER 0x0500
#include <windows.h>
#include <setupapi.h>
#include <basetyps.h>
#include <D:\C++\usb.h\usbdi.h>
#include <initguid.h>
#include <stdio.h>
.....................

1,222

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧