分类: 嵌入式
2010-02-22 15:10:38
经过上述三节的描述,对USB应该已经有了初步的认识,其中具体的协议(比如各个描述符的定义什么的)这里不做描述了,网上一搜一大堆。下面我以一个实例来详细说明快速开发USB设备的步骤,
一,设定规划
凡事预则立,不预则费,所以开发一个小小的USB也要稍微规划一下,比如想象要实现什么功能,传输的数据协议什么的。
二,固件编程,
固件编程说白了就是写单片机程序,要实现USB一般可以使用带USB功能的单片机,再个就是加一个专用的USB芯片。这里以内部集成USB功能单片机为例
固件的USB开发一般就是先使能USB,使能USB时钟,使能各个USB控制中断(挂起,复位,标准请求,写入,写出等)然后USB就能正常工作了,这时候不如不写别的东西,电脑就可以检测出有USB设备插入了,具体的反应是在设备管理器里会发现闪了一下说明发现了新的USB设备,接下来电脑会发送各种标准请求,因为这个时候你的程序还没写完整,对这些请求不会有反应,所以电脑不可能识别出是什么东西。
接下来的工作就是在中断中响应电脑传来的各种标准请求。当必要的请求都被正确的响应的话,这个时候如果电脑里有正确的驱动,电脑就会去加载这个驱动,如果是第一次插入这个设备,还要把驱动安装一下,然后设备就进入正常工作了,电脑会显示“这个USB已经成功安装并可以应用了”。
这里捎带着说一下端点(endpoint)的概念,一般一个USB设备都会有数个端点,端点就是一个数据缓冲控制区(FIFO),每个缓冲区相当于有一个出口一个进口的池子,数据通过进口进入到池子,然后你再在固件里去用这些数据。固件往电脑写数据,也是把数据先放到池子里,然后打开出口,就可以干自己的事情,不用一个个的把数据发出了,池子的出口自动把数据流出。
一般的端口0是用来做标准请求响应用的,也就是在枚举阶段用到。我一般把端口1定义为出(OUT),端口2定义为入(IN)(注意,这个OUT和IN是相对与电脑的,也就是说OUT是数据从电脑出去到设备,IN是设备的数据进入电脑)。这些定义也是在标准请求中去告诉电脑的。
接下来就可以实现与电脑的通讯了,你把数据放到相应的池子里就行了。下面就可以自己定义通讯的数据格式了。比如控制开发板上的8个LED的第一个灯亮,那么上位机发送数据0x55,0x01,0x80,0xaa。我们就可以规定第一个数据是启示位,遇到这个表明开始一次控制指令,0x01表示这个是控制灯亮暗的指令,0x80表示LED的控制数据,最高位是1,表示第一个亮,其他位是0,表示都暗。最后一个数据是0xaa,表示这是结束。其实所谓的数据协议不过就是自己定义的一套让通讯双方都能正确理解对方的数据格式。电脑比较是电脑,什么都要规定好了,它才能正确的工作。
二驱动程序
对于快速开发用Driverstudio就可以了,我先装了VC6.0,然后装了DDK2600,最后装了Driverstudio,网上有说这个顺序不容易出问题,我也没时间去试别的顺序会出怎么样的特效,姑且不管他是否在忽悠,先这样按了没坏处。
我一开始比较新潮的装了DriverStudio3.2版本,然后按网上的方法破解了,生成了驱动是能打开设备,但是就是传输不了数据,搞了两天还是不行,后来想到是不是3.2版本太新了?或者破解没完整?然后卸载了3.2装了3.1,果然可以了,真不知道是Compuware做了手脚故意玩我还是本人愚笨弄错了哪里。
驱动生成的步骤可以在百度,Google里搜“10分钟完成一个USB驱动程序”能出来一
大堆,要是你嫌搜索麻烦就直接点这个算了按那个步骤操作就可以了,根据向导操作完了以后,VC就会出来一个驱动程序框架了,如果你在这个时候编译一下就可你会碰到很多问题,我的操作是这样的。首先把DDK的库编译一下,操作网上有,网上有云:
1.启动Visual C++ 。
2.选择菜单 File|Open Workspace。打开位于DriverStudio/DriverWorks/Source/vdwlibs.dsw的工作空间文件。
3.选择菜单 Build|Batch Build,在弹出的对话框中选择你想编译的库。
4.点击Build编译你选择的库。
然后在VC的Driverstudio的工具条点击“change environment variables”,在第一个选型卡把DDK的路径选上,我的是C:\WINDDK\2600。然后点OK,接下来点DriverStudio工具条的编译,就可以了,如果你还是碰到问题,你可以把VC显示的错误复制到百度。