
《圈圈教你玩USB》 第五章 提到可以自己设计一个HID设备,于是,进行实验,刷新他的 Firmware 运行他的测试程序,在 Win7 3和64 下都不需要安装驱动程序,直接使用应用程序即可。

《圈圈教你玩USB》 第五章 带的 Firmware 程序和Windows下的应用程序:
用户自定义HID设备上位机应用程序及源代码包
用户自定义HID设备下位机固件源代码包
自己动手直接编写一个 VS2008 程序来对这个设备发送数据(主要是我一直没法再 VS2008下成功编译他的Application)
//http://blog.csdn.net/xuxinhua/article/details/6329182
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <setupapi.h>
extern "C" {
void __stdcall
HidD_GetHidGuid (
OUT LPGUID HidGuid
);
typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
//
// Vendor ids of this hid device
//
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
//
// Additional fields will be added to the end of this structure.
//
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
BOOLEAN __stdcall
HidD_GetAttributes (
IN HANDLE HidDeviceObject,
OUT PHIDD_ATTRIBUTES Attributes
);
}
#pragma comment( lib, "hid.lib" )
#pragma comment( lib, "setupapi.lib" )
int main(array<System::String ^> ^args)
{
GUID HidGuid;
BOOL Result;
//获取HID设备的接口类GUDI
HidD_GetHidGuid(&HidGuid);
//输出一下看看GUID
printf("HID GUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n"
, HidGuid.Data1, HidGuid.Data2, HidGuid.Data3
, HidGuid.Data4[0], HidGuid.Data4[1], HidGuid.Data4[2], HidGuid.Data4[3], HidGuid.Data4[4]
, HidGuid.Data4[5], HidGuid.Data4[6], HidGuid.Data4[7] );
//根据获得的GUID枚举HID设备
HDEVINFO hDevInfo = SetupDiGetClassDevs( &HidGuid, 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,&HidGuid,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) )
{
printf("[%d] path: %ls\n", index, strtDetailData.DevicePath);
//这里打开的有可能是USB键盘鼠标这样比较特别的设备(只能查询)
HANDLE hUsb = CreateFile( strtDetailData.DevicePath,
NULL, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL );
// 查询设备标识
HIDD_ATTRIBUTES strtAttrib = { sizeof(HIDD_ATTRIBUTES) };
Result=HidD_GetAttributes(hUsb,&strtAttrib);
//所以这里要关闭一下,后面找到我们自己的设备确定可以写入再打开一次
CloseHandle( hUsb );
if(TRUE==Result)
{
if ((0x8888==strtAttrib.VendorID) &&
(0x6==strtAttrib.ProductID)) //找到我们自己的设备
{
printf("VendorID : %hX\n", strtAttrib.VendorID );
printf("ProductID: %hX\n", strtAttrib.ProductID );
printf("VerNumber: %hX\n", strtAttrib.VersionNumber );
//确定是我们自己的设备,再打开一次,注意我们这里使用的是同步发送
hUsb = CreateFile( strtDetailData.DevicePath,
GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );
//发送报告的缓冲区,1字节报告ID+8字节报告数据。
UCHAR WriteReportBuffer[9];
DWORD lpNumberOfBytesWritten;
UINT LastError;
WriteReportBuffer[0]=0x00;
WriteReportBuffer[1]=0x75;
//调用WriteFile函数发送数据
Result=WriteFile(hUsb,
WriteReportBuffer,
9,
&lpNumberOfBytesWritten,
NULL);
//如果函数返回失败,则可能是真的失败,也可能是IO挂起
if(Result==FALSE)
{
//获取最后错误代码
LastError=GetLastError();
//看是否是真的IO挂
if((LastError==ERROR_IO_PENDING)||(LastError==ERROR_SUCCESS))
{ return TRUE; }
//否则,是函数调用时发生错误,显示错误代码
else
{
printf("Sending error:%d \n",LastError);
//如果最后错误为1,说明该设备不支持该函数。
if(LastError==1)
{printf("This device doesn't support WriteFile function \n");}
}
}
CloseHandle( hUsb );
}//if ((0x8888==strtAttrib.VendorID) &&
} //if(TRUE==Result)
} // if( SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,&strtDetailData,_countof(buf),NULL,NULL) )
} //for( DWORD index=0;
if( GetLastError() != ERROR_NO_MORE_ITEMS )
{printf("No more items!\n"); }
SetupDiDestroyDeviceInfoList( hDevInfo );
} //if( INVALID_HANDLE_VALUE != hDevInfo )
system("PAUSE");
return 0;
}
运行结果:

程序下载
HidSend