您现在的位置: USB开发网 > USB技术文档 > USB专题 > USB HID协议中文版
USB HID协议中文版

6、HID主机程序实例(VB)

------分隔线----------------------------

  本节介绍通过高级接口实验台进行的一个HID编程实例。

  在USB设备软件的开发过程中,借助于一些工具软件的测试会对USB设备的信息获取和通信过程又更深入的理解。USB测试软件有很多,如USBView、BusHound等,下面针对一个具体的HID设备的API通信软件的开发,对这两个工具软件作一简单介绍。

  高级接口实验台中,有一个HID实验,在该实验中,实验台通过固件软件设计了一个简单的HID仿真设备,在PC的API通信软件的开发过程中,可以借助USB工具软件对实验台的HID设备进行测试。

6.1 获得描述符
将高级接口实验台通过USB电缆与PC连接后,在实验台上通过菜单选择HID实验,实验台显示器显示器上会显示HID实验界面。

  实验台的HID实验是一个为了学习HID编程而专门设计的一个简单的HID仿真设备,设备中设计了8个寄存器(R1~R8),可以通过USB接口与主机交换数据。其中R1和R2两个寄存器只是数据存储单元,主机可以对这两个寄存器进行附值,也可以读取寄存器的值。寄存器R3~R8构成了一个日期和时钟,6个寄存器的值分别表示年、月、日、时、分、秒。时钟在当前值的基础上运行,可以通过主机对时钟进行设置,也可以读取当前的时钟值。

  在实验台上设计了自动回传功能,如果自动回传打开,时钟每一秒向主机传送一次报表。实验台可以显示发送和接收的有效数据字节数。

 

高级接口实验台HID实验界面

图6-1  高级接口实验台HID实验界面

  

  USBView是Microsoft提供的一个简单的USB测试软件,该工具软件是一个完全的绿色软件,只有一个EXE程序文将,不需要安装,在Windows环境下直接运行。
USBView其主要功能是获得USB设备的各个描述符。
  可以运行USBView获得实验台仿真的HID设备的描述符,运行USBView后显示以下程序界面。

 

USBView运行界面

图6-2 USBView运行界面

  窗口的左侧显示全部的USB设备连接树,在其中找到一个显示“USB人体工程学设备”的分支,选中后右侧窗口显示全部的(报表描述符除外)描述符。USBView显示的高级接口实验台的HID仿真设备的描述符如下。


  1. Device Descriptor: 
  2. bcdUSB:                         0x0110 
  3. bDeviceClass:               0x00 
  4. bDeviceSubClass:            0x00 
  5. bDeviceProtocol:            0x00 
  6. bMaxPacketSize0:            0x10 (16) 
  7. idVendor:                       0x045E (Microsoft Corporation) 
  8. idProduct:                  0x930A 
  9. bcdDevice:                  0x0100 
  10. iManufacturer:              0x01 
  11. iProduct:                   0x02 
  12. iSerialNumber:              0x03 
  13. bNumConfigurations:     0x01 
  14.  
  15. ConnectionStatus: DeviceConnected 
  16. Current Config Value:       0x01 
  17. Device Bus Speed:           Full 
  18. Device Address:             0x02 
  19. Open Pipes:                 4 
  20.  
  21. Endpoint Descriptor: 
  22. bEndpointAddress:           0x81 
  23. Transfer Type:              Bulk 
  24. wMaxPacketSize:             0x0010 (16) 
  25. bInterval:                  0x0A 
  26.  
  27. Endpoint Descriptor: 
  28. bEndpointAddress:           0x01 
  29. Transfer Type:              Bulk 
  30. wMaxPacketSize:             0x0010 (16) 
  31. bInterval:                  0x0A 
  32.  
  33. Endpoint Descriptor: 
  34. bEndpointAddress:           0x82 
  35. Transfer Type:              Interrupt 
  36. wMaxPacketSize:             0x0040 (64) 
  37. bInterval:                  0x01 
  38.  
  39. Endpoint Descriptor: 
  40. bEndpointAddress:           0x02 
  41. Transfer Type:              Interrupt 
  42. wMaxPacketSize:             0x0040 (64) 
  43. bInterval:                  0x01 

6.2 设备的初始化
在将高级接口实验台连接到计算机并操作实验台进入HID接口实验后,Windows系统会发现设备并读取设备的各种描述符,可以通过一个USB工具软件截取Windows和设备之间的请求应答过程。工具软件BusHound可以实现这个功能。

  BunHound是一个功能全面的总线分析仪软件,可以实现对计算机通过各种接口连接的设备的通信过程进行截取和分析。图8-9是BusHound的设备连接树(Devices)界面。

  当高级接口实验台与计算机通过USB接口连接并操作实验台进入HID实验,可以在BusHound的设备连接树中找到一个“USB人体工程学设备”项目。选中该项目可以实现对设备的通信过程的截取。

  选中高级接口实验台的HID设备项,进入到采集(Capture)界面,先控制实验台退出HID实验,按BusHound的采集界面的Stop按钮,再按Run按钮,然后控制实验台进入HID实验界面。Windows系统发现设备并请求设备的各种描述符,然后完成对设备的必要的设置,BusHound可以采集到以上通信过程。

 

BusHound的设备树显示界面
图6-3 BusHound的设备树显示界面

 

BusHound的采集显示界面
6-4 BusHound的采集显示界面

下面分析BusHound截取的数据内容。
• 主机发送:80 06 00 01 00 00 12 00
Get_Descriptor请求,请求设备回传设备描述符。
• 设备发送:12 01 10 01 00 00 00 10 5e 04 0a 93 00 01 01 02 03 01
设备描述符内容:USB版本=1.1、类别/协议码=0、EP0的最大包尺寸=10、VID=045E、PID=930A、版本=1.0、厂商、产品和序列号字符串索引、配置数=1。
• 主机发送:80 06 00 02 00 00 09 00
Get_Descriptor请求,请求设备回传配置描述符。
• 设备发送:09 02 37 00 01 01 04 80 32
配置描述符内容:该描述符及后续描述符总长度=55、支持接口数=1、配置标示符=1、总线供电、最大100mA。
• 主机发送:80 06 00 02 00 00 37 00
Get_Descriptor请求,请求设备回传配置、接口、HID和端点描述符。
• 设备发送:09 02 37 00 01 01 04 80 32 09 04 00 00 04 03 00 00 05 09 21 01 01 00 01 22 34 00 07 05 81 02 10 00 0a 07 05 01 02 10 00 0a 07 05 82 03 40 00 01 07 05 02 03 40 00 01 按顺序为:
9字节配置描述符:含义同上。
9字节接口描述符:标示符=0、支持的端点=4、类别=HID。
9字节HID描述符:版本=1.01、有1个报表描述符(长度为52)
7字节端点描述符:1号批量输入,包尺寸=16。
7字节端点描述符:1号批量输出,包尺寸=16。
7字节端点描述符:2号中断输入,包尺寸=64、1ms轮询。
7字节端点描述符:2号中断输出,包尺寸=64、1ms轮询。
• 主机发送:00 09 01 00 00 00 00 00
Set_Configuation请求,配置号=1。
• 主机发送:21 0a 00 00 00 00 00 00
Set_Idle请求,设定间隔时间为0。
• 设备发送:04 00 00 c0
STALL,不支持请求。
• 主机发送:81 06 00 22 00 00 74 00
Get_Descriptor请求,请求设备回传报表描述符。
• 设备发送:06 a0 ff 09 01 a1 01 09 02 a1 00 06 a1 ff 09 03 09 04 15 80 25 7f 35 00 45 ff 75 08 95 40 81 02 09 05 09 06 15 80 25 7f 35 00 45 ff 75 08 95 40 91 02 c0 c0
报表描述符。

6.3 HID测试程序的实现
使用Visual Basic编写一个针对高级接口实验台的应用程序,实现与设备的通信。该测试程序实现以下功能:

• 查找设备:根据指定的VID和PID实现设备查找;
• 获得设备能力:调用相应的API,获得设备的能力;
• 发送报表:将界面输入的R1~R8的数值按照报表的指定格式传送到设备;
• 接收报表:将设备的界面显示的R1~R8的数值读取到应用程序;
• 显示API函数调用信息:显示每一个API函数的调用结果;
• 关闭设备。

  下图是程序运行的界面显示:

针对实验台的HID测试程序显示界面
图6-5 针对实验台的HID测试程序显示界面(VB)

  在获得能力的API函数的调用结果中,输入报表和输出报表的长度为65字节,在发送和接收报表时的长度设定都需要设为65。但在该实验中真正用到的有效数据只有8个寄存器的数据,占用其中的8个字节,报表的首字节(第0个)为0,表示Report ID。第1、2个字节分别55h、AAh为用户定义的标示字。第3、4字节为用户定义命令编码,输出报表中为01、08,输入报表中为02、08。从第5到第12字节顺序为R1、R2、…R8的值。之后的数据为保留字节。

 

  1. 'HID查找、能力检测、输入报表、输出报表演示程序 
  2. '修改自许永和的《介面设计与实习 使用Bisual Basic》 
  3.  
  4.  
  5. Option Explicit 
  6.  
  7. '变量定义 ****************************************************************************** 
  8. Dim Capabilities As HIDP_CAPS 
  9. Dim DataString As String 
  10. Dim DetailData As Long 
  11. Dim DetailDataBuffer() As Byte 
  12. Dim DeviceAttributes As HIDD_ATTRIBUTES 
  13. Dim DevicePathName As String 
  14. Dim DeviceInfoSet As Long 
  15. Dim ErrorString As String 
  16. Dim HidDevice As Long 
  17. Dim LastDevice As Boolean 
  18. Dim MyDeviceDetected As Boolean 
  19. Dim MyDeviceInfoData As SP_DEVINFO_DATA 
  20. Dim MyDeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA 
  21. Dim MyDeviceInterfaceData As SP_DEVICE_INTERFACE_DATA 
  22. Dim Needed As Long 
  23. Dim OutputReportData(7) As Byte 
  24. Dim PreparsedData As Long 
  25. Dim Result As Long 
  26. Dim Timeout As Boolean 
  27.  
  28. Dim MyVendorID As Long          'VID、PID 
  29. Dim MyProductID As Long 
  30.  
  31. '************************************************************************************** 
  32. '查找全部的HID设备,直到找到VID、PID符合的一个HID 
  33. '如果找到,MyDeviceDetected为True 
  34. '************************************************************************************** 
  35.  
  36. Function FindTheHid() As Boolean 
  37.  
  38. Dim Count As Integer 
  39. Dim GUIDString As String 
  40. Dim HidGuid As GUID 
  41. Dim MemberIndex As Long 
  42.  
  43. LastDevice = False 
  44. MyDeviceDetected = False 
  45.  
  46. '调用 HidD_GetHidGuid 函数获得GUID 
  47.  
  48. Result = HidD_GetHidGuid(HidGuid) 
  49. Call DisplayResultOfAPICall("GetHidGuid"
  50.  
  51. GUIDString = Hex$(HidGuid.Data1) & "-" & Hex$(HidGuid.Data2) & "-" & Hex$(HidGuid.Data3) & "-" 
  52.  
  53. For Count = 0 To 7 
  54.     If HidGuid.Data4(Count) >= &H10 Then 
  55.         GUIDString = GUIDString & Hex$(HidGuid.Data4(Count)) & " " 
  56.     Else 
  57.         GUIDString = GUIDString & "0" & Hex$(HidGuid.Data4(Count)) & " " 
  58.     End If 
  59. Next Count 
  60.  
  61. lstResults.AddItem "  GUID for system HIDs: " 
  62. lstResults.AddItem "  " & GUIDString 
  63.  
  64. '调用 SetupDiGetClassDevs 函数获得指向HID信息集的指针 
  65.  
  66. DeviceInfoSet = SetupDiGetClassDevs(HidGuid, vbNullString, 0, (DIGCF_PRESENT Or DIGCF_DEVICEINTERFACE)) 
  67.      
  68. Call DisplayResultOfAPICall("SetupDiClassDevs"
  69. DataString = GetDataString(DeviceInfoSet, 32) 
  70. lstResults.AddItem "  DeviceInfoSet:" & DeviceInfoSet 
  71.  
  72.  
  73. '下面循环,从MemberIndex=0开始,查找指定HID 
  74. MemberIndex = 0 
  75.  
  76. Do 
  77.     '调用 SetupDiEnumDeviceInterfaces 函数获得 SP_DEVICE_INTERFACE_DATA 结构指针 
  78.  
  79.     MyDeviceInterfaceData.cbSize = LenB(MyDeviceInterfaceData) 
  80.     Result = SetupDiEnumDeviceInterfaces(DeviceInfoSet, 0, HidGuid, MemberIndex, MyDeviceInterfaceData) 
  81.      
  82.     Call DisplayResultOfAPICall("SetupDiEnumDeviceInterfaces"
  83.     If Result = 0 Then LastDevice = True 
  84.      
  85.     '如果调用成功 
  86.     If Result <> 0 Then 
  87.         '显示获得的信息 
  88.         lstResults.AddItem "  DeviceInfoSet for device #" & CStr(MemberIndex) & ": " 
  89.         lstResults.AddItem "  cbSize = " & CStr(MyDeviceInterfaceData.cbSize) 
  90.         lstResults.AddItem "  InterfaceClassGuid.Data1 _ 
  91.                 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data1) 
  92.         lstResults.AddItem "  InterfaceClassGuid.Data2 _ 
  93.                 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data2) 
  94.         lstResults.AddItem "  InterfaceClassGuid.Data3 _ 
  95.                  = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data3) 
  96.         lstResults.AddItem "  Flags = " & Hex$(MyDeviceInterfaceData.Flags) 
  97.  
  98.          
  99.         '调用 SetupDiGetDeviceInterfaceDetail函数,获得SP_DEVICE_INTERFACE_DETAIL_DATA结构 
  100.         '注意:该函数需要调用两次,最后获得设备路径 
  101.          
  102.         MyDeviceInfoData.cbSize = Len(MyDeviceInfoData) 
  103.         Result = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, MyDeviceInterfaceData, 0, 0, Needed, 0) 
  104.          
  105.         DetailData = Needed 
  106.              
  107.         Call DisplayResultOfAPICall("SetupDiGetDeviceInterfaceDetail"
  108.         lstResults.AddItem "  (OK to say too small)" 
  109.         lstResults.AddItem "  Required buffer size for the data: " & Needed 
  110.          
  111.         '存储结构的长度 
  112.         MyDeviceInterfaceDetailData.cbSize = Len(MyDeviceInterfaceDetailData) 
  113.          
  114.         ReDim DetailDataBuffer(Needed) 
  115.          
  116.         '存储结构的前4和字节,cbSize 
  117.         Call RtlMoveMemory(DetailDataBuffer(0), MyDeviceInterfaceDetailData, 4) 
  118.          
  119.         '再一次调用 
  120.         Result = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, _ 
  121.              MyDeviceInterfaceData, VarPtr(DetailDataBuffer(0)), DetailData, Needed, 0) 
  122.          
  123.         Call DisplayResultOfAPICall(" Result of second call: "
  124.         lstResults.AddItem "  MyDeviceInterfaceDetailData.cbSize: " & CStr(MyDeviceInterfaceDetailData.cbSize) 
  125.          
  126.         DevicePathName = CStr(DetailDataBuffer()) 
  127.         DevicePathName = StrConv(DevicePathName, vbUnicode)              '转换成Unicode 
  128.         DevicePathName = Right$(DevicePathName, Len(DevicePathName) - 4)    '删除4个字节 
  129.         lstResults.AddItem "  Device pathname: " 
  130.         lstResults.AddItem "    " & DevicePathName 
  131.                  
  132.         '调用 CreateFile 函数,获得设备句柄:HidDevice 
  133.  
  134.         HidDevice = CreateFile(DevicePathName, GENERIC_READ Or GENERIC_WRITE, _ 
  135.                 (FILE_SHARE_READ Or FILE_SHARE_WRITE), 0, OPEN_EXISTING, 0, 0) 
  136.              
  137.         Call DisplayResultOfAPICall("CreateFile"
  138.         lstResults.AddItem "  Returned handle: " & Hex$(HidDevice) & "h" 
  139.          
  140.         '调用 HidD_GetAttributes 获得HID的VID、PID 
  141.          
  142.         DeviceAttributes.Size = LenB(DeviceAttributes) 
  143.         Result = HidD_GetAttributes(HidDevice, DeviceAttributes) 
  144.              
  145.         Call DisplayResultOfAPICall("HidD_GetAttributes"
  146.         If Result <> 0 Then 
  147.             lstResults.AddItem "  HIDD_ATTRIBUTES structure filled without error." 
  148.         Else 
  149.             lstResults.AddItem "  Error in filling HIDD_ATTRIBUTES structure." 
  150.         End If 
  151.      
  152.         lstResults.AddItem "  Structure size: " & DeviceAttributes.Size 
  153.         lstResults.AddItem "  Vendor ID: " & Hex$(DeviceAttributes.VendorID) 
  154.         lstResults.AddItem "  Product ID: " & Hex$(DeviceAttributes.ProductID) 
  155.         lstResults.AddItem "  Version Number: " & Hex$(DeviceAttributes.VersionNumber) 
  156.          
  157.         '看看是不是指定的VID、PID 
  158.         If (DeviceAttributes.VendorID = MyVendorID) And (DeviceAttributes.ProductID = MyProductID) Then 
  159.             lstResults.AddItem "  My device detected " 
  160.             lstResults.AddItem "  -------------------------------------------------------------------------------------------" 
  161.             lblHID.Caption = "HID Find" 
  162.             MyDeviceDetected = True 
  163.             cmdGetCaps.Enabled = True 
  164.             cmdClose.Enabled = True 
  165.             txtVendorID.Enabled = False 
  166.             txtProductID.Enabled = False 
  167.         Else 
  168.             MyDeviceDetected = False 
  169.             Result = CloseHandle(HidDevice) 
  170.             DisplayResultOfAPICall ("CloseHandle"
  171.         End If 
  172.     End If 
  173.  
  174.     MemberIndex = MemberIndex + 1    '准备查找下一个 
  175.      
  176. Loop Until (LastDevice = TrueOr (MyDeviceDetected = True
  177.      
  178. End Function 
  179.  
  180. '************************************************************************************** 
  181. '获得上一个API函数的执行信息 
  182. '************************************************************************************** 
  183.  
  184. Private Function GetErrorString(ByVal LastError As LongAs String 
  185.  
  186. Dim Bytes As Long 
  187. Dim ErrorString As String 
  188. ErrorString = String$(129, 0) 
  189. Bytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0&, LastError, 0, ErrorString$, 128, 0) 
  190.      
  191. If Bytes > 2 Then       '去掉其中的回车 
  192.     GetErrorString = Left$(ErrorString, Bytes - 2) 
  193. End If 
  194.  
  195. End Function 
  196.  
  197. '************************************************************************************** 
  198. '清除数据域显示 
  199. '************************************************************************************** 
  200.  
  201. Private Sub cmdClear_Click() 
  202.  
  203. txtR1.Text = "" 
  204. txtR2.Text = "" 
  205. txtYear.Text = "" 
  206. txtMonth.Text = "" 
  207. txtDay.Text = "" 
  208. txtHour.Text = "" 
  209. txtMinute.Text = "" 
  210. txtSecond.Text = "" 
  211. End Sub 
  212.  
  213. '************************************************************************************** 
  214. '查找HID 
  215. '************************************************************************************** 
  216.  
  217. Private Sub cmdFindHID_Click() 
  218. Call FindTheHid 
  219. End Sub 
  220.  
  221. '************************************************************************************** 
  222. '显示API函数的执行结果 
  223. '************************************************************************************** 
  224.  
  225. Private Sub DisplayResultOfAPICall(FunctionName As String
  226.  
  227. Dim ErrorString As String 
  228. lstResults.AddItem "" 
  229. ErrorString = GetErrorString(Err.LastDllError) 
  230. lstResults.AddItem FunctionName 
  231. lstResults.AddItem "  Result = " & ErrorString 
  232. End Sub 
  233.  
  234. '************************************************************************************** 
  235. '程序初始化 
  236. '************************************************************************************** 
  237.  
  238. Private Sub Form_Load() 
  239. frmMain.Show 
  240. tmrDelay.Enabled = False 
  241. lstResults.Clear 
  242. MyVendorID = &H45E 
  243. MyProductID = &H930A 
  244. End Sub 
  245.  
  246. '************************************************************************************** 
  247. '获得HID的能力信息 
  248. '************************************************************************************** 
  249.  
  250. Private Sub cmdGetCaps_click() 
  251.  
  252. Dim ppData(29) As Byte 
  253. Dim ppDataString As Variant 
  254.  
  255. '调用 HidD_GetPreparsedData 获得一个缓冲区指针 
  256.  
  257. Result = HidD_GetPreparsedData(HidDevice, PreparsedData) 
  258. Call DisplayResultOfAPICall("HidD_GetPreparsedData"
  259.  
  260. Result = RtlMoveMemory(ppData(0), PreparsedData, 30) 
  261. Call DisplayResultOfAPICall("RtlMoveMemory"
  262.  
  263. ppDataString = ppData() 
  264. ppDataString = StrConv(ppDataString, vbUnicode) 
  265.  
  266. '调用 HidP_GetCaps 获得HID_CAPS 结构数据 
  267.  
  268. Result = HidP_GetCaps(PreparsedData, Capabilities) 
  269.  
  270. Call DisplayResultOfAPICall("HidP_GetCaps"
  271. lstResults.AddItem "  Last error: " & ErrorString 
  272. lstResults.AddItem "  Usage: " & Hex$(Capabilities.Usage) 
  273. lstResults.AddItem "  Usage Page: " & Hex$(Capabilities.UsagePage) 
  274. lstResults.AddItem "  Input Report Byte Length: " & Capabilities.InputReportByteLength 
  275. lstResults.AddItem "  Output Report Byte Length: " & Capabilities.OutputReportByteLength 
  276. lstResults.AddItem "  Feature Report Byte Length: " & Capabilities.FeatureReportByteLength 
  277. lstResults.AddItem "  Number of Link Collection Nodes: " & Capabilities.NumberLinkCollectionNodes 
  278. lstResults.AddItem "  Number of Input Button Caps: " & Capabilities.NumberInputButtonCaps 
  279. lstResults.AddItem "  Number of Input Value Caps: " & Capabilities.NumberInputValueCaps 
  280. lstResults.AddItem "  Number of Input Data Indices: " & Capabilities.NumberInputDataIndices 
  281. lstResults.AddItem "  Number of Output Button Caps: " & Capabilities.NumberOutputButtonCaps 
  282. lstResults.AddItem "  Number of Output Value Caps: " & Capabilities.NumberOutputValueCaps 
  283. lstResults.AddItem "  Number of Output Data Indices: " & Capabilities.NumberOutputDataIndices 
  284. lstResults.AddItem "  Number of Feature Button Caps: " & Capabilities.NumberFeatureButtonCaps 
  285. lstResults.AddItem "  Number of Feature Value Caps: " & Capabilities.NumberFeatureValueCaps 
  286. lstResults.AddItem "  Number of Feature Data Indices: " & Capabilities.NumberFeatureDataIndices 
  287.  
  288. '调用 HidP_GetValueCaps 获得HID能力的数值 
  289.  
  290. Dim ValueCaps(1023) As Byte 
  291.  
  292. Result = HidP_GetValueCaps(HidP_Input, ValueCaps(0), Capabilities.NumberInputValueCaps, PreparsedData) 
  293.    
  294. Call DisplayResultOfAPICall("HidP_GetValueCaps"
  295. lstResults.AddItem "  -------------------------------------------------------------------------------------------" 
  296. lblCaps.Caption = "Get Caps Ok" 
  297.  
  298. cmdTrans.Enabled = True 
  299. cmdReceive.Enabled = True 
  300. End Sub 
  301.  
  302. '************************************************************************************** 
  303. '输出报表到HID 
  304. '************************************************************************************** 
  305.  
  306. Private Sub cmdTrans_Click() 
  307.  
  308.  
  309. Dim Count As Integer 
  310. Dim NumberOfBytesToSend As Long 
  311. Dim NumberOfBytesWritten As Long 
  312. Dim SendBuffer() As Byte 
  313. ReDim SendBuffer(Capabilities.OutputReportByteLength - 1) 
  314.  
  315. '填写报表数据到数组SendBuffer 
  316. Count = 0 
  317. SendBuffer(Count) = 0       '第一個位元組是Report ID 
  318. Count = Count + 1 
  319. SendBuffer(Count) = &H55 
  320. Count = Count + 1 
  321. SendBuffer(Count) = &HAA 
  322. Count = Count + 1 
  323. SendBuffer(Count) = &H1 
  324. Count = Count + 1 
  325. SendBuffer(Count) = &H8 
  326. Count = Count + 1 
  327. SendBuffer(Count) = Val("&H" + txtR1.Text) 
  328. Count = Count + 1 
  329. SendBuffer(Count) = Val("&H" + txtR2.Text) 
  330. Count = Count + 1 
  331. SendBuffer(Count) = Val(txtYear.Text) 
  332. Count = Count + 1 
  333. SendBuffer(Count) = Val(txtMonth.Text) 
  334. Count = Count + 1 
  335. SendBuffer(Count) = Val(txtDay.Text) 
  336. Count = Count + 1 
  337. SendBuffer(Count) = Val(txtHour.Text) 
  338. Count = Count + 1 
  339. SendBuffer(Count) = Val(txtMinute.Text) 
  340. Count = Count + 1 
  341. SendBuffer(Count) = Val(txtSecond.Text) 
  342. Count = Count + 1 
  343.  
  344. '调用 WriteFile 函数,发送报表 
  345.  
  346. NumberOfBytesWritten = 0 
  347. Result = WriteFile(HidDevice, SendBuffer(0), CLng(Capabilities.OutputReportByteLength), NumberOfBytesWritten, 0) 
  348.  
  349. Call DisplayResultOfAPICall("WriteFile"
  350. lstResults.AddItem "  Output Report" + Str(NumberOfBytesWritten) + " bytes" 
  351. End Sub 
  352.  
  353. '************************************************************************************** 
  354. '从HID读取报表 
  355. '注意:以下代码为非重叠调用,必须保证HID输出报表 
  356. '************************************************************************************** 
  357.  
  358. Private Sub cmdReceive_click() 
  359.  
  360. Dim Count 
  361. Dim NumberOfBytesRead As Long 
  362. Dim ReadBuffer() As Byte 
  363. ReDim ReadBuffer(Capabilities.InputReportByteLength - 1) 
  364.      
  365. '调用 ReadFile 函数,读取报表 
  366. Result = ReadFile(HidDevice, ReadBuffer(0), CLng(Capabilities.InputReportByteLength), NumberOfBytesRead, 0) 
  367.  
  368. Call DisplayResultOfAPICall("ReadFile"
  369. lstResults.AddItem "  Input Report" + Str(NumberOfBytesRead) + " bytes" 
  370.  
  371. '将输入报表的数据填写到显示介面的相应数据域 
  372. txtR1.Text = Hex$(ReadBuffer(5)) 
  373. txtR2.Text = Hex$(ReadBuffer(6)) 
  374. txtYear.Text = IIf(ReadBuffer(7) < 10, "0" + Trim(Str$(ReadBuffer(7))), Trim(Str$(ReadBuffer(7)))) 
  375. txtMonth.Text = IIf(ReadBuffer(8) < 10, "0" + Trim(Str$(ReadBuffer(8))), Trim(Str$(ReadBuffer(8)))) 
  376. txtDay.Text = IIf(ReadBuffer(9) < 10, "0" + Trim(Str$(ReadBuffer(9))), Trim(Str$(ReadBuffer(9)))) 
  377. txtHour.Text = IIf(ReadBuffer(10) < 10, "0" + Trim(Str$(ReadBuffer(10))), Trim(Str$(ReadBuffer(10)))) 
  378. txtMinute.Text = IIf(ReadBuffer(11) < 10, "0" + Trim(Str$(ReadBuffer(11))), Trim(Str$(ReadBuffer(11)))) 
  379. txtSecond.Text = IIf(ReadBuffer(12) < 10, "0" + Trim(Str$(ReadBuffer(12))), Trim(Str$(ReadBuffer(12)))) 
  380. End Sub 
  381.  
  382. '************************************************************************************** 
  383. '关闭设备,释放资源 
  384. '************************************************************************************** 
  385.  
  386. Private Sub cmdClose_Click() 
  387.  
  388.  
  389. '调用 CloseHandle 关闭HID 
  390.  
  391. Result = CloseHandle(HidDevice) 
  392. Call DisplayResultOfAPICall("CloseHandle (HidDevice)"
  393.  
  394. '调用 SetupDiDestroyDeviceInfoList和HidD_FreePreparsedData 释放占用的资源 
  395.  
  396. Result = SetupDiDestroyDeviceInfoList(DeviceInfoSet) 
  397. Call DisplayResultOfAPICall("DestroyDeviceInfoList"
  398. Result = HidD_FreePreparsedData(PreparsedData) 
  399. Call DisplayResultOfAPICall("HidD_FreePreparsedData"
  400.  
  401. lstResults.Clear 
  402. cmdClose.Enabled = False 
  403. cmdGetCaps.Enabled = False 
  404. cmdTrans.Enabled = False 
  405. cmdReceive.Enabled = False 
  406. lblHID.Caption = "" 
  407. lblCaps.Caption = "" 
  408. txtVendorID.Enabled = True 
  409. txtProductID.Enabled = True 
  410. End Sub 
  411.  
  412. '************************************************************************************** 
  413. '将当前日期和时间填写到界面的数据域 
  414. '************************************************************************************** 
  415.  
  416. Private Sub cmdNow_Click() 
  417.  
  418. txtHour.Text = IIf(Hour(Now()) < 10, "0" + Hour(Now()), Hour(Now())) 
  419. txtMinute.Text = IIf(Minute(Now()) < 10, "0" + Trim(Str(Minute(Now()))), Minute(Now())) 
  420. txtSecond.Text = IIf(Second(Now()) < 10, "0" + Trim(Str(Second(Now()))), Second(Now())) 
  421. txtYear.Text = IIf((Year(Now()) - 2000) < 10, "0" + Trim(Str(Year(Now()) - 2000)), Str(Year(Now()) - 2000)) 
  422. txtMonth.Text = IIf(Month(Now()) < 10, "0" + Trim(Str(Month(Now()))), Str(Month(Now()))) 
  423. txtDay.Text = IIf(Day(Now()) < 10, "0" + Trim(Str(Day(Now()))), Day(Now())) 
  424. End Sub 
  425.  
  426. '************************************************************************************** 
  427. '获得信息字符串 
  428. '************************************************************************************** 
  429.  
  430. Private Function GetDataString(Address As Long, Bytes As LongAs String 
  431.  
  432. Dim Offset As Integer 
  433. Dim Result$ 
  434. Dim ThisByte As Byte 
  435.  
  436. For Offset = 0 To Bytes - 1 
  437.     Call RtlMoveMemory(ByVal VarPtr(ThisByte), ByVal Address + Offset, 1) 
  438.     If (ThisByte And &HF0) = 0 Then 
  439.         Result$ = Result$ & "0" 
  440.     End If 
  441.     Result$ = Result$ & Hex$(ThisByte) & " " 
  442. Next Offset 
  443.  
  444. GetDataString = Result$ 
  445. End Function 

 

------分隔线----------------------------
USB开源项目
联系我们
  • Q Q: 1148374829 点击这里给我发消息
  • 旺旺:jhoneqhsieh 点击这里给我发消息
  • 电话:(0)15923141204
  • 淘宝网店