用VC++实现USB接口读写数据的程序

使用一个GUIDguidHID_1查找并打开一个USB设备
extern "C" int PASCAL SearchUSBDevice()
{
  HANDLE hUsb;

	int nCount, i, j;//标记同一设备个数
	HDEVINFO hDevInfoSet;
	BOOL bResult;

	PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;

	memset(m_sysversion, 0, 20);
	GetSysVersion(m_sysversion);

	// 检索相关GUID的USB设备总设备个数
	if (!GetUSBList())
	{
	return 0;
	}
	// 取得一个该GUID相关的设备信息集句柄
	hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUID 
	NULL, // 无关键字 
	NULL, // 不指定父窗口句柄 
	DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
	
	// 失败...
	if (hDevInfoSet == INVALID_HANDLE_VALUE)
	{
	return NULL;
	}

	// 申请设备接口数据空间
	
	nCount = 0;
	bResult = TRUE;
	for (i=0; i< 34; i++)
	{
	bDeviceOpen[i] = FALSE;
	memset(m_DeviceDesc[i], 0, 256);
	}

	SP_DEVICE_INTERFACE_DATA ifdata;
	// 设备序号=0,1,2... 逐一测试设备接口,到失败为止
	while (bResult)
	{

		ifdata.cbSize = sizeof(ifdata);
		// 枚举符合该GUID的设备接口
		bResult = ::SetupDiEnumDeviceInterfaces(
		hDevInfoSet, // 设备信息集句柄
		NULL, // 不需额外的设备描述
		(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID
		(ULONG)nCount, // 设备信息集里的设备序号
		&ifdata); // 设备接口信息

		if (bResult)
		{
			ULONG predictedLength = 0;
			ULONG requiredLength = 0;
			// 取得该设备接口的细节(设备路径)
			bResult = SetupDiGetInterfaceDeviceDetail(
			hDevInfoSet, // 设备信息集句柄
			&ifdata, // 设备接口信息
			NULL, // 设备接口细节(设备路径)
			0, // 输出缓冲区大小
			&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
			NULL); // 不需额外的设备描述
			// 取得该设备接口的细节(设备路径)
			predictedLength=requiredLength;

		// if(pDetail)
		// {
		// pDetail =NULL;
		// }
		pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT,  predictedLength);
		pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		bResult = SetupDiGetInterfaceDeviceDetail(
		hDevInfoSet, // 设备信息集句柄
		&ifdata, // 设备接口信息
		pDetail, // 设备接口细节(设备路径)
		predictedLength, // 输出缓冲区大小
		&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
		NULL); // 不需额外的设备描述

		if (bResult)
		{
		// 复制设备路径到输出缓冲区
		//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
		if (strcmp(m_sysversion, "winnt")==0)
		{
			char ch[18];
			for(i=0;i<17;i++){
			ch[i]=*(pDetail->DevicePath+8+i);
		}
		ch[17]='\0';
		if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错
		{

			memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; 
			memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; 

			READ_OS.hEvent = CreateEvent( NULL, // no security
			TRUE, // explicit reset req
			FALSE, // initial event reset
			NULL ) ; // no name
			if (READ_OS.hEvent == NULL) 
			{
			break;
			}

			WRITE_OS.hEvent = CreateEvent( NULL, // no security
			TRUE, // explicit reset req
			FALSE, // initial event reset
			NULL ) ; // no name
			if (NULL == WRITE_OS.hEvent)
			{
			CloseHandle( READ_OS.hEvent );
			break;
			}

			hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
			GENERIC_READ|GENERIC_WRITE,
			FILE_SHARE_READ|FILE_SHARE_WRITE,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL/*|
			FILE_FLAG_OVERLAPPED*/,
			NULL);
			if (hUsb != NULL)
			{
			// 比较定位找到的USB在哪个USB PORT上
			char id[30];
			memset(id, 0, 30);
			i=0;
			do
			{
				id[i]=*(pDetail->DevicePath+26+i);
				i++;
			}
			while(id[i-1]!='#');
			id[i-1] = '\0';
			for (j=0; j<34; j++)
			{
			if(strcmp(id, m_USBList[j])==0)
			{
				sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
				m_USBPositionMap[nCount] = j+1;
				break;
			}
			}
			
			CloseHandle(hUsb);
			nCount++;
			// break;
			}
			}// 比较驱动版本
			}// 比较操作系统版本
			else
			{
			memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; 
			memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; 
			
			READ_OS.hEvent = CreateEvent( NULL, // no security
			TRUE, // explicit reset req
			FALSE, // initial event reset
			NULL ) ; // no name
			if (READ_OS.hEvent == NULL) 
			{
			break;
			}
			
			WRITE_OS.hEvent = CreateEvent( NULL, // no security
			TRUE, // explicit reset req
			FALSE, // initial event reset
			NULL ) ; // no name
			if (NULL == WRITE_OS.hEvent)
			{
			CloseHandle( READ_OS.hEvent );
			break;
			}

hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL/*|
FILE_FLAG_OVERLAPPED*/,
NULL);
if (hUsb != NULL)
{
if(strcmp(pDetail->DevicePath, m_USBList[j])==0)
{
sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
m_USBPositionMap[nCount] = j+1;
break;
}
CloseHandle(hUsb);
nCount++;
// break;
}
}
}
}
}
// 释放设备接口数据空间
::GlobalFree(pDetail);

// 关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);

iDeviceCount = nCount;

return nCount;
}


// 写
BOOL Writestr(char *buf,int buflen, int index)
{
BOOL fWriteStat;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
char szError[ 10 ] ;
DWORD ret;
int len, i, j, packet;
div_t div_result;
BYTE sendpacket[65];
BYTE xorcode="0x00";

if (m_gphdCom[index] == NULL) // no usb device(jk100c)
{
return -1;
}

div_result = div(buflen, 58);
if (div_result.rem == 0)
{
packet = div_result.quot;
}
else
{
packet = div_result.quot+1;
}
for (i=0; i<packet; i++)
{
memset(sendpacket, 0, 65);
if(i==packet-1)
{
// end packet
if (div_result.rem == 0)
{
len = 58;
}
else
{
len = div_result.rem;
}
}
else
{
len = 58;
}
sendpacket[0] = 0x13;
sendpacket[1] = 3+len;
sendpacket[2] = 0x01;
sendpacket[3] = packet*16+i+1;
memcpy(sendpacket+4, buf+(i*58), len);
for(j=0;j<len+3;j++)
{
xorcode^=sendpacket[j+1];
}
sendpacket[len+4] = (char)xorcode;
sendpacket[len+5] = 0x23;
PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
// Sleep(10);
fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL);
if (!fWriteStat) 
{
if(GetLastError() == ERROR_IO_PENDING)
{
dwError = GetLastError();
// an error occurred, try to recover
wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
OutputDebugString(szError);
ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags >0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
}
else
{ 
// some other error occurred
ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags > 0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
return FALSE;
}
}
if (i != packet-1)
{
// should be receive ack
if (ReceivePacketAnswer(index) != 0)
{
return FALSE;
}
}
}

return TRUE;
}

// 读
int Readstr(char *buf,int nMaxLength, int index)
{
	BOOL fReadStat ;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	DWORD dwLength;
	DWORD dwError;
	char szError[ 10 ];

	if (fCOMMOpened==0)
	{
	return FALSE; //串口未打开
	}

	// only try to read number of bytes in queue 
	ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;
	//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;

    dwLength=nMaxLength;
	if (dwLength > 0)
	{
		 if (olap==TRUE) 
		{
			fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ;
			if (!fReadStat)
			{
				if (GetLastError() == ERROR_IO_PENDING)
				{
					OutputDebugString("\n\rIO Pending");
					while(!GetOverlappedResult(m_gphdCom[index], &READ_OS, &dwLength, TRUE ))
					{
						dwError = GetLastError();
						if(dwError == ERROR_IO_INCOMPLETE) 
						continue;
						else
						{
								// an error occurred, try to recover
							ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;
							break;
						}
					}
				}
				else // end-----if (GetLastError() == ERROR_IO_PENDING)
				{
					// some other error occurred
					dwLength = 0 ;
					ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
					if (dwErrorFlags >0)
					{
						wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
						OutputDebugString(szError);
					}
				}
			} // end-----if (!fReadStat) 
	} // end-----if (olap==TRUE) 
	else
 	{
		fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ;
		if (!fReadStat)
		{
			dwError = GetLastError();
			ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;

			if (dwErrorFlags >0)
			{
					wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					OutputDebugString(szError);
			}
		}
		PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
		}
	}

	return dwLength;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网小镇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值