Chinaunix首页 | 论坛 | 博客
  • 博客访问: 131057
  • 博文数量: 22
  • 博客积分: 949
  • 博客等级: 准尉
  • 技术积分: 266
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-10 22:31
文章分类

全部博文(22)

文章存档

2012年(1)

2011年(2)

2010年(19)

分类: 嵌入式

2010-09-26 19:31:18

其实我对USB还是很有感情的,第一个USB是2005年给航天智通的彩票机做一个客户显示系统,就是彩票机上那个给买彩票的人看的小显示器。之前他们用的是串口,后来很多机器串口少了,而且串口一般还要给POS机之类的其他终端使用,因此需要做这么一个模块。不过当时由于初次做USB, 而且还要写Linux和Windows下的驱动,当时觉得还是用自定义的设备,使用Bulk传输比较简单,最后在AN2131(Cypress)上做了这个项目,大概卖了一千多套,后来被人山寨了,前前后后也赚了点钱,也算是为清苦的研究生生活添加了一点精彩。
其实这个项目完全可以使用HID来实现,估计这样驱动的工作还会更简单些,至少不用下载WinDriver和DDK这种庞然大物了。其实很多MSP430和8051F的仿真器就有使用HID协议的,使用这个协议最大的优点就是不用写驱动,用Windows和Linux自带的驱动即可。其实HID的枚举方式和自定义的差别并不是很大,一般都是先Get Device Descriptor,然后是Get Configuration Descriptor,然后可能会发起多个重复的Device Descriptor和Configuration Descriptor,不过长度可能有点差异,总之就是从Descriptor开头取需要的长度返回就OK了。 如果有String的话还会发起Get String Descriptor。对于HID来讲,跟HID Class相关的是会发起Get HID Report的请求,其大概过程如下(........... 表示省略):
(图片显示太小,不知如何放大,保存到本机查看即可看清)
最后一行发完以后基本上就OK了,在设备管理器里面就应该能够看到HID-Compliant Device了
HID Report Descriptor应该是USB HID的最重要的部分了,俺的理解就是一个
Global
{
     Local
     {
        Main
      }
 }
Global是全局的,一直起作用,直到被另外的Global代替
Local项目不作用于下一个Main
Main一般就是实际的定义了,比如多少I/O点之类的。还是国外论坛的一个老兄讲的比较清楚,在此引用一下:(图片显示太小,不知如何放大,保存到本机查看即可看清)
比如俺的Report Descriptor就是这个样子的:
    0x05, 0x01, // USAGE_PAGE (Generic Desktop)
    0x09, 0x00, // USAGE (0)
    0xa1, 0x01, // COLLECTION (Application)
    0x15, 0x00, //     LOGICAL_MINIMUM (0)
    0x25, 0xff, //     LOGICAL_MAXIMUM (255)
    0x19, 0x01, //     USAGE_MINIMUM (1)
    0x29, 0x08, //     USAGE_MAXIMUM (8)
    0x95, 0x08, //     REPORT_COUNT (8)
    0x75, 0x08, //     REPORT_SIZE (8)
    0x81, 0x02, //     INPUT (Data,Var,Abs)
    0x19, 0x01, //     USAGE_MINIMUM (1)
    0x29, 0x08, //     USAGE_MAXIMUM (8)
    0x91, 0x02, //   OUTPUT (Data,Var,Abs)
    0xc0            // END_COLLECTION
其实就是定义了八个字节的输入和八个字节的输出而已。
当一切Descriptor都回复妥当以后,就需要测试一下了,使用的测试程序是Jan Axelson的测试程序,风别有VB6和VC6两个版本,对其进行了一点点修改,VB的增加了直接在界面输入Vendor ID和Product ID,把接收数据显示也改了一下,原版的显示光标在最后,给人感觉就像数据收错了。VC的把接收的ReportID在显示的时候去掉了,不然看起来比下位机发的多出了一个0x00,怪怪的,此外还把hid.lid,setupapi.lib以及几个头文件放在了包里面并做了部分修改,这样下载就可以直接编译了,如果遇到以下错误:
“DBT_DEVTYP_DEVICEINTERFACE, PDEV_BROADCAST_DEVICEINTERFACE, HDEVNOTIFY, DEVICE_NOTIFY_WINDOW_HANDLE undeclared”
则需要在stdafx.h里面增加#define WINVER 0x0500就OK了。
现在就可以进行测试了,在测试程序的VID和PID中输入正确的数字(16进制的),点击Once就可以看到一次收发了,如果TimeOut的话肯定是下位机有点问题,比如没有不断的往上传IN的数据,或者OUT数据没有读走阻塞住了。
测试程序及其源码下载地址:
VB6:
VC6:

 
 
 
阅读(1834) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~