您的当前位置:首页正文

VC编程实现与USB设备通信

2023-02-16 来源:好走旅游网


第1章 绪论

1.1 USB简介

USB是由世界著名计算机和通信公司等共同推出的新一代接口标准,全称为Universal Serial Bus(通用串行总线)[1],是一种快速、灵活的总线接口。它是为了解决日益增加的PC外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准。USB应用十分广泛,并具有下述优点:

1、适用于多种外设,使它不需要为不同的外设准备不同的接口和协议;

2、Windows能自动检测到USB设备的热插拔,并自动配置;

3、PC机上的接口线非常紧缺,而USB设备并不需要用户设置端口故无论从用户使用方便性,或从对资源的占用方面看,USB都很优秀;

4、当接入一个USB设备时,全速USB接口可达12Mbit/s。考虑到状态、控制和出错信息,最大理论速度仍可达到9.6Mbit/s,这是其他串行接口协议所不能比拟的,且USB也支持1.5Mbit/s的低速传输。

5、USB接口芯片价格低廉,这也大大促进USB设备的开发与应用。

1

在USB出现之前,计算机典型接口有并行口、串行口、鼠标口、键盘口、显示器口,及各种卡式接口等,与这些接口对应的有各种不同的电缆,在传输速度方面,这些接口都存在速度偏低的问题。在技术方面,这种设计容易产生I/O冲突,中断不够用,以及对于每一种新的外设都必须设计新的接口卡等缺点。当今的计算机外部设备,都在追求高速度和高通用性。USB接口适应了这种要求,并以其速度快、使用方便、成本低等优点,迅速得到了众多PC厂商和半导体厂商的大力支持,外设向USB过度成为必然趋势。

1.2 USB驱动程序的意义

如果PC主机不知道如何与USB外设通信,那么这个USB外设一点用处都没有,人机接口设备(HID)[2]类是Windows完全支持的USB设备类型中的一种,应用程序可以使用操作系统内设置的驱动与HID通信,但与HID通信不像打开一个端口,设定几个参数,然后就可以读写数据那么简单,在应用程序能与HID交换数据之前,它先要找到设备,获取有关它的报告信息。为做到这些,应用程序必须通过访问通信API函数,使位于上层的应用程序与位于下层的设备驱动程序进行数据交换。应用程序可以使用任何能访问API函数的程序语言,VC++是一种能访问API函数的功能强大的语言,因此,我们应用Visual C++6.0环境下编写与USB设备通信的Windows程序。

1.3 VC++软件的介绍

应用基于MFC AppWizard的应用程序。MFC (Microsoft Foundation Class

2

Library) 中的各种类结合起来构成了一个应用程序框架,它的目的就是在此基础上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。因为总体上,MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。Microsoft Visual C++提供了相应的工具来完成这个工作:AppWizard可以用来生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;ClassWizard用来协助添加代码到框架文件;最后,编译,则通过类库实现了应用程序特定的逻辑。

1.4 系统方案设计

上位机界面应用VC++6.0软件来编写,为了简单适用,在创建工程时采用对话框类型。一个好的应用程序首先要有好的用户界面,看起来赏心悦目,使用起来简单、方便。显示界面上的各个元素需要和USB设备上的元件摆放位置相对应。把要完成的一系列功能的显示元素分成不同的模块来进行程序的编写,每一个模块分别完成一种功能,这样既方便检查程序,也方便在通信发生错误时的对错误进行分析。

为了实现PC机对USB设备的识别,上位机端需要有一个USB设备的驱动程序来识别和支持USB设备,否则PC机将无法识别USB设备。这里选用DriverStudio软件来编写,它能生成一个简单的驱动程序的框架,根据需要,可以在此基础上进行更深层的开发。

1.5 预期结果

3

通过上位机软件和驱动程序的编写实现以下功能:

1、完成上位机软件的编写,并可以在设备没有连接时显示连接错误。

2、完成驱动程序的编写,实现上位机能发现USB设备,并使上位机能正确配置设备。同时在显示界面上显示出找到设备。

3、实现双向传输。在上位机软件中可以控制USB设备中的相应显示,同时可以接收到USB设备传回的消息,并在显示界面上显示。达到一个PC机与USB设备信息的交互,完成通信。

4、利用VC编程实现对计算机底层硬件的操作,培养在此方面工程开发的能力。

4

第2章 USB协议

2.1 USB系统的使用分类及系统的描述

USB设计的初衷是针对桌面电脑而不是应用于可移动的环境下的。软件体系通过对各种主机控制器提供支持以保证将来对USB的扩充[3]。USB是一种电缆总线,支持在主机和各式各样的即插即用的外设之间进行数据传输。由主机预定的标准的协议使各种设备分享USB带宽,当其它设备和主机在运行时,总线允许添加、设置、使用以及拆除外设。

USB系统的描述:

一个USB系统主要被定义为三个部分:USB的互连、USB的设备、USB的主机。

USB的互连是指USB设备与主机之间进行连接和通信的操作,主要包括以下几方面:

(1)总线的拓扑结构:USB设备与主机之间的各种连接方式;

(2)内部层次关系:根据性能叠置,USB的任务被分配到系统的每一个层次;

(3)数据流模式:描述了数据在系统中通过USB从产生方到使用方的流动方式;

5

(4)USB的调度:USB提供了一个共享的连接。对可以使用的连接进行了调度以支持同步数据传输,并且避免的优先级判别的开销。

USB的设备如下所示:

(1)网络集线器,向USB提供了更多的连接点;

(2)功能器件:为系统提供具体功能,如ISDN的连接,数字的游戏杆或扬声器。

USB设备提供的USB标准接口的主要依据:

(1)对USB协议的运用;

(2)对标准USB操作的反馈,如设置和复位;

(3)标准性能的描述性信息;

USB传输方式:

USB总线属一种轮讯方式的总线,主机控制端口初始化所有的数据传输。每一总线执行动作最多传送三个数据包。按照传输前制定好的原则,在每次传送开始时,主机控制器发送一个描述传输运作的种类、方向,USB设备地址和终端号的USB数据包,这

6

个数据包通常称为标志包(token packet)。USB设备从解码后的数据包的适当位置取出属于自己的数据。数据传输方向不是从主机到设备就是从设备到主机。在传输开始时,由标志包来标志数据的传输方向,然后发送端开始发送包含信息的数据包或表明没有数据传送。接收端也要相应发送一个握手的数据包表明是否传送成功。发送端和接收端之间的USB数据传输,在主机和设备的端口之间,可视为一个通道。存在两种类型的通道:流和消息。流的数据不像消息的数据,它没有USB所定义的结构,而且通道与数据带宽、传送服务类型,端口特性(如方向和缓冲区大小)有关。USB中有一个特殊的通道——缺省控制通道,它属于消息通道,当设备一启动即存在,从而为设备的设置、查询状况和输入控制信息提供一个入口。

2.2 USB物理接口的电器特性

2.2.1 USB物理接口

USB传送信号和电源是通过一种四线的电缆,两根线是用于发送信号。存在两种数据传输率:

7

图2.1 USB物理接口

(1)USB的高速信号的比特率定为12Mbps;

(2)低速信号传送的模式定为1.5Mbps;

电缆中包括VBUS、GND二条线,向设备提供电源。VBUS使用+5V电源。USB对电缆长度的要求很宽,最长可为几米。通过选择合适的导线长度以匹配指定的IR drop和其它一些特性,如设备能源预算和电缆适应度。为了保证足够的输入电压和终端阻抗。重要的终端设备应位于电缆的尾部。在每个端口都可检测终端是否连接或分离,并区分出高速,或低速设备。

2.2.2 电源

主要包括两方面:

(1)电源分配:即USB的设备如何通过USB分配得到由主计算机提供的能源。每个USB单元通过电缆只能提供有限的能源。主机对那种直接相连的USB设备提供电源供其使用。并且每个USB设备都可能有自己的电源。那些完全依靠电缆提供能源的设备称作“总线供能”设备。相反,那些可选择能源来源的设备称作“自供电”设备。而且,集线器也可由与之相连的USB设备提供电源。

8

(2)电源管理:即通过电源管理系统,USB的系统软件和设备如何与主机协调工作。USB主机与USB系统有相互独立的电源管理系统。USB的系统软件可以与主机的能源管理系统结合共同处理各种电子元件如挂起、唤醒,并且有特色的是,USB设备应用特有的电源管理特性,可让系统软件和控制其电源管理。

2.2.3 总线协议

主机控制端口初始化所有的数据传输。每一总线执行动作最多传送三个数据包。按照传输前制定好的原则,在每次传送开始时,主机控制器发送一个描述传输运作的种类、方向,USB设备地址和终端号的USB数据包,这个数据包通常称为标志包(token packet)。USB设备从解码后的数据包的适当位置取出属于自己的数据。数据传输方向不是从主机到设备就是从设备到主机。在传输开始时,由标志包来标志数据的传输方向,然后发送端开始发送包含信息的数据包或表明没有数据传送。接收端也要相应发送一个握手的数据包表明是否传送成功。发送端和接收端之间的USB数据传输,在主机和设备的端口之间,可视为一个通道。存在两种类型的通道:流和消息。流的数据不像消息的数据,它没有USB所定义的结构,而且通道与数据带宽、传送服务类型,端口特性(如方向和缓冲区大小)有关。多数通道在USB设备设置完成后即存在。USB中有一个特殊的通道——缺省控制通道,它属于消息通道,当设备一启动即存在,从而为设备的设置、查询状况和输入控制信息提供一个入口。

事务预处理允许对一些数据流的通道进行控制,从而在硬件级上防止了对缓冲区的

9

高估或低估,通过发送不确认握手信号从而阻塞了数据的传输速度。当不确认信号发过后,若总线有空闲,数据传输将再做一次。这种流控制机制允许灵活的任务安排,可使不同性质的流通道同时正常工作,这样多种流通常可在不同间隔进行工作,传送不同大小的数据包。

1、USB设备的安装

所有的USB设备都是通过端口接在USB上,网络集线器知道这些指定的USB设备,集线器有一个状态指示器指明在其某个端口上,USB设备是否被安装或拆除了,主机将所有的集线器排成队列以取回其状态指示。在USB设备安装后,主机通过设备控制通道激活该端口并以预设的地址值给USB设备。

主机对每个设备指定唯一的USB地址。并检测这种新装的USB设备是集线器还是功能部件。主机为USB设备建立了控制通道,使用指定的USB的地址和零号端口。

如果安装的USB设备是集线器,并且USB设备连在其端口上,上述过程对每个USB设备的安装都要做一遍。

如果安装的设备是功能部件,那么主机中关于该设备的软件将因设备的连接而被引发。

2、USB设备的拆卸

10

当USB设备从集线器的端口拆除后,集线器关闭该端口,并且向主机报告该设备已不存在。USB的系统软件将准确进行处理,如果去除的USB设备上集线器,USB的系统软件将对集线器反连在其上的所有设备进行处理。

3、总线标号

总线标号就是对连接在总线上的设备指定唯一的地址的一种动作,因为USB允许USB设备在任何时刻从USB上安装或拆卸,所以总线标号是USB的系统软件始终要作的动作,而且总线标号还包括对拆除设备的检测和处理。

4、数据流种类

数据和控制信号在主机和USB设备间的交换存在两种通道:单向和双向。USB的数据传送是在主机软件和一个USB设备的指定端口之间。这种主机软件和USB设备的端口间的联系称作通道。总的来说,各通道之间的数据流动是相互独立的。一个指定的USB设备可有许多通道。例如,一个USB设备存在一个端口,可建立一个向其它USB设备的端口,发送数据的通道,它可建立一个从其它USB设备的端口接收数据的通道。

USB的结构包含四种基本的数据传输类型:

(1)控制数据传送:在设备连接时用来对设备进行设置,还可对指定设备进行控制,如通道控制;

11

(2)批量数据传送:大批量产生并使用的数据,在传输约束下,具有很广的动态范围;

(3)中断数据的传送:用来描述或匹配人的感觉或对特征反应的回馈。

(4)同步数据的传送:由预先确定的传送延迟来填满预定的USB带宽。

对于任何对定的设备进行设置时一种通道只能支持上述一种方式的数据传输,数据流模式的更多细节在第四章中详述。

5、控制数据传送

当USB设备初次安装时,USB系统软件使用控制数据对设备进行设置,设备驱动程序通过特定的方式使用控制数据来传送,数据传送是无损性的。

6、批量数据传送

批量数据是由大量的数据组成,如使用打印机和扫描仪时,批量数据是连续的。在硬件级上可使用错误检测可以保证可靠的数据传输,并在硬件级上引入了数据的多次传送。此外根据其它一些总线动作,被大量数据占用的带宽可以相应的进行改变。

7、中断数据传输

中断数据是少量的,且其数据延迟时间也是有限范围的。这种数据可由设备在任何

12

时刻发送,并且以不慢于设备指定的速度在USB上传送。

中断数据一般由事件通告,特征及座标号组成,只有一个或几个字节。匹配定点设备的座标即为一例,虽然精确指定的传输率不必要,但USB必须对交互数据提供一个反应时间的最低界限。

8、同步传输

同步数据的建立、传送和使用时是连续且实时的,同步数据是以稳定的速率发送和接收实时的信息,同步数据要使接收者与发送者保持相同的时间安排,除了传输速率,同步数据对传送延迟非常敏感。所以同步通道的带宽的确定,必须满足对相关功能部件的取样特性。不可避免的信号延迟与每个端口的可用缓冲区数有关。

一个典型的同步数据的例子是语音,如果数据流的传送率不能保持,数据流是否丢失将取决于缓冲区的大小和损坏的程度。即使数据在USB硬件上以合适的速率传送,软件造成的传送延迟将对那些如电话会议等实时系统的应用造成损害。

实时的传送同步数据肯定会发生潜在瞬时的数据流丢失现象,换句话说,即使许多硬件机制,如重传的引入也不能避免错误的产生。实际应用中,USB的数据出错率小到几乎可以忽略不计。从USB的带宽中,给USB同步数据流分配了专有的一部分以满足所想得到的传速率,USB还为同步数据的传送设计了最少延迟时间。

13

9、指定USB带宽

USB的带宽分配给各个通道,当一个通道建立后,USB就分配给它一定的带宽,USB设备需要提供一些数据缓冲区。若USB提供了更多带宽,则需更多的缓冲区。USB的体系要保证缓冲引导的硬件的延迟限定在几毫秒内。

USB的带宽容量可以容纳多种不同的数据流,因此保证USB上可以连接大量设备,如可以容纳从1B+D直到T1速率范围的电信设备。同时USB支持在同一时刻不同设备具有不同比特率,并具有一个动态变动的范围。

2.3 USB设备

USB设备分为诸如集线器、分配器或文本设备等种类。集线器类指的是一种提供USB连接点的设备,USB设备需要提供自检和属性设置的信息,USB设备必须在任何时刻执行与所定义的USB设备的状态相一致的动态。

2.3.1 设备特性

当设备被连接、编号后,该设备就拥有一个唯一的USB地址。设备就是通过该USB地址被操作的,每一个USB设备通过一个或多个通道与主机通讯。所有USB设备必须在零号端口上有一指定的通道,每个USB设备的USB控制通道将与之相连。通过此控制通道,所有的USB设备都列入一个共同的准入机制,以获得控制操作的信息。

14

在零号端口上,控制通道中的信息应完整的描述USB设备、此类信息主要有以下几类:

(1)标准信息:这类信息是对所有USB设备的共同性的定义,包括一些如厂商识别、设备种类、电源管理等的项目。设备设置、接口及终端的描述在此给出。

(2)类别信息:此类信息给出了不同USB的设备类的定义,主要反映其不同点。

(3)USB厂商信息:USB设备的厂商可自由的提供各种有关信息,其格式不受该规范制约。此外,每个USB设备均提供USB的控制和状态信息。

2.3.2 设备描述

主要分为两种设备类:集线器和功能部件。只有集线器可以提供更多的USB的连接点,功能部件为主机提供了具体的功能。

USB设备可被划分三层:

(1)底层是传送和接收数据包的总线接口;

(2)中间层处理总线接口与不同端点之间的数据路由端节点是数据的终结提供处或使用处,它可被看作数据源或数据接收端(Sink);

15

(3)最上层的功能由串行总线设备提供,比如鼠标,或ISDN接口。

2.3.3 设备状态

USB设备有若干可能的状态,其中一些对于USB与主机(host)来说是外置的,而另外一些对USB设备来说是内置的。

(1)连接状态

USB设备可被连接到USB接口上或从接口断开。

(2)加电状态

USB设备的电源可来自外部电源,也可从USB接口的集线器而来。电源来自外部电源的USB设备被称作自给电源式的(self-powered)。尽管自给电源式的USB设备可能在连接上USB接口以前可能已经带电,但它们直到连线上USB接口后才能被看作是加电状态(Powered state)。而这时候VBUS已经对设备产生作用了。

一个设备可能有既支持自给电源的,同时也支持总线电源式的配置。有一些支持其中的一种,而另一些设备配置可能只有在自给电源下才能被使用。设备对电源支持的能力是通过配置描述表(configuration descriptor)来反映的。当前的电源供给形式被作为设备状态的一部分被反映出来。设备可在任何时候改变它们的供电来源,比如说:

16

从自给式向总线式改变,如果一个配置同时支持两种模式,那此状态的最大电源需求就是指设备在两种模式下从VBUS上获取电能的最大值。设备必须以此最大电源作为参照,而究竟处于何状态是不考虑的。如果有一配置仅支持一种电源模式,那么电源模式的改变会使得设备失去当前配置与地址,返回加电状态。如果一个设备是自给电源式,并且当前配置需要大于100mA电流,那么如果此设备转到了总线电源式,它必须返回地址状态(Address state)。自给电源式集线器使用VBUS来为集线控制器(Hub controller)提供电源,因而可以仍然保持配置状态(Configured state),尽管自给电源停止提供电源。

(3)缺省状态

设备加电以后,在它从总线接收到复位信号之前不应对总线传输发生响应。在接收到复位信号之后,设备才在缺省地址处变得可寻址。

(4)地址状态

所有的USB设备在加电复位以后都使用缺省地址。每一设备在连接或复位后由主机分配一个唯一的地址。当USB设备处于挂起状态时,它保持这个地址不变。

USB设备只对缺省通道(Pipe)请求发生响应,而不管设备是否已经被分配地址或在使用缺省地址。

17

(5)中止状态

为节省电源,USB设备在探测不到总线传输时自动进入中止状态。当中止时,USB设备保持本身的内部状态,包括它的地址及配置。

所有的设备在一段特定的时间内探测不到总线活动时必须进入中止态。不管设备是被分配了非缺省的地址或者是被配置了,已经连接的设备必须在任何加电的时刻随时准备中止。总线活动的中止可能是因为主机本身进入了中止状态。另外,USB设备必须在所连接的集线器端口失效时进入中止态。这就是所指的选择性中止(Selective suspend)。

USB设备在总线活动来到时结束中止态。USB设备也可以远程唤醒的电流信号来请求主机退出中止态或选择性中止态。具体设备具有的远程唤醒的能力是可选的,也就是说,如果一个设备有远程唤醒的能力,此设备必须能让主机控制此能力的有效与否。当设备复位时,远程唤醒能力必须被禁止。

2.4 Bus Enumeration总线标号

当USB设备接上或从USB设备移开的时候,主机启动一个被称作总线标识(bus enumeration)的进程,来标识并管理设备状态的改变,当USB设备接上一个加电端口时,系统当采取以下操作:

18

(1)USB设备所连的集线器通过其通向主机的状态改变通道向主机,汇报本USB设备已连接上。此时,USB设备处于加电状态,它所连接的端口是无效的。

(2)主机通过寻问集线器决定此次状态改变的确切含义。

(3)主机一旦得知新设备已连上以后,它至少等待100ms以使得插入操作的完成以及设备电源稳定工作。然后主机发出端口使能及复位命令给那个端口。

(4)集线器将发向端口的复位信号持续10ms当复位信号撤消后,端口已经有效了。这时USB设备处于缺省状态,并且可从VBUS汲取小于100mA的电能,所有设备寄存器及状态已经被复位,设备可对缺省地址产生响应。

(5)主机给设备分配一个唯一的地址,设备转向编址状态。(Address state)。

(6)在USB设备接受设备地址之前,它的缺省控制通道(Default Control Pipe)在缺省地址处自然是可寻址的,主机通过读取设备描述表,判决设备缺省通道的实际净数据负载。

(7)主机从设备读取配置信息要从配置0读到配置n-1,其中n为配置个数,此操作须花费几个毫秒。

(8)基于从设备取来的配置信息及设备如何被使用的信息,主机给设备一个配置

19

值,此刻,设备就处于配置状态(Configured state)并此配置有关的所有端节点,都按照配置各就各位,USB设备现在可以从VBUS得到描述中所要求的电量了。从设备的角度来讲,它已经准备就绪了。

当UBS设备被取走时,集线器同样会通知主机,断开一个设备连接会使得设备所连接的端口无效,一收到断开通知后,主机就会更新的拓扑信息。

2.5 通用USB设备操作

1、动态插接与拔开

USB设备必须在任意时刻允许被插接与拔开。提供连接点或端口的集线器应当负责汇报端口的状态改变情况。

当主机探测到连接操作后,会使得所连的集线器端口生效,设备也会因此而复位,一个被复位了的USB设备有如下特性:

(1)对缺省USB地址发生响应;

(2)没有被配置;

(3)初始状态不是挂起。

20

当设备从一个集线器端口移去时,集线器会使得原来连接的端口失效,并且通知主机设备已移去。

2、地址分配

当USB设备连接以后,由主机负责给此设备分配一个唯一的地址,这个操作是在设备复位及端口使能操作以后。

3、配置

USB设备在正常被使用以前,必须被配置,由主机负责配置设备。主机一般会从USB设备获取配置信息后再准定此设备有哪些功能。

作为配置操作的一部分,主机会设置设备的配置值,并且,如果必要的话会选择合适的接口的备选设置。

只须一个简单配置,一个设备可能支持多重接口。一个接口是一组端结点集合,它们代表了设备向主机提供的单一的功能或特性,用来与这组相关端结点通信的协议以及接口内各端结点的目的可以作为一个设备类的一部分或者由厂商制定具体定义。

另外,一个配置中的接口可能有备选设置。这些备选设置会重定义相关端结点的数目或特性。如果是这样的话,设备必须支持GetInterface(接口请求)与Set Interface(接口设置)请求,来汇报及选择指定的接口的设备选设置。

21

在每个设备配置下,每个接口描述表可能包括用来标识接口的及备选设置的域,接口被从0~N-1编号。n为配置所支持的能同时使用的接口数目,类似的设置的编号也从0开始。当设备初始化配置后,缺省设置是备选设置0。

了支持通用的设备驱动程序管理一组相关的BUS设备,设备与接口描述表中包含了类(Class),子类(Sub class),及协议(Protocol)域。这些域用来标识一个设备的功能及用于通信的协议。

一个类值被分配给一组按照特性划分成USB类说明一部分的设备。一个类的设备可进一步划分成子类,并且在一个类或子类中,一个协议代值可定义主机软件是怎样与设备通信的。

4、数据传送

数据可能以四种方式在USB设备端结点与主机之间传送。在不同设置下,一个终端结点可能被用于不同的传输方式,但一旦设置选定,传送方式就选定了。

5、复位/继续及恢复时间

当一个端口被复位或从中止态继续的时候,USB系统软件应当等待一个10ms的恢复时间才能确保端口对数据传输产生响应。

一旦恢复时间段结束(从reset信号结束,或resume信号结尾的EOP结束开始

22

计时)设备必须在任意时刻都能对数据传输作出响应。

6、设置地址的处理

在reset/resume恢复时间段以后,如果设备收到SetAddress()请求,设备必须能在50ms内完成请求的处理,并完成状态的转换,在SetAddress()的请求下,当设备发出0长度的状态数据包或设备收到状态数据包的响应信号ACK就表明状态转换结束了。

在状态转换结束后,设备有2ms的SetAddress()恢复时间。在这段时间结束以后,设备必须能在新地址处接受Setup数据包,并且,必须确保此时设备不对旧地址的信号产生响应。

7、请求错误

如果一设备收到一个请求,它或是在设备中无定义,或是不适用于当前设置,或是数值不对,这时就会产生一个请求错误。设备在下一个数据传输阶段或状态交换阶段(Status stage)返回一个表明错误的STALL PID信号,一般在下一个数据传输返回更好,这样可减少不必要的总线活动。

2.6 USB主机

USB的互连支持数据在USB主机与USB设备之间的流动。为了简化主机上的客户

23

软件(Software client)与设备的功能部件(function)之间的通信而必须的主机接口(host interface)。只要USB设备并不感觉到主机行为的改变,USB主机完全可以提供一个不同的软件系统实现方法。图2.2展示了USB通信模型之间基本的信息流与互连关系:

图2.2 通信模型层次关系图

由图2.2可见,主机与设备都被划分成不同的层次。主机上垂直的箭头是实际的信息流。设备上对应的接口是基于不同实现的。在主机与设备之间的所有通信最终都是通过USB的电缆进行,然而,在上层的水平层之间存在逻辑的主机—设备信息流。主机上的客户软件和设备功能部件之间的通信是基于实际的应用需求及设备所能提供的能力。

客户软件与功能部件之间的透明通信的要求,决定主机和设备下层部件的功能以及

24

它们的界面(interface)。

主机在整个USB系统中是唯一的,它包括USB总线接口、USB系统(USB System)、USB客户(Client)。

其中,USB总线接口处理电气及协议层的互连。从互连的角度看,USB设备和USB主机都提供类似的USB总线接口,如串行接口引擎(Serial Interface Engine SIE)。由于主机在USB系统中的特殊性,USB主机上的总线接口还必须具备主机控制器的功能(Host Controller),主机控制器具有一个内集成的集线器(根集线器)提供与USB电缆的连接。

USB系统(USB System)使用主机控制器来管理主机与USB设备的数据传输。USB系统与主机控制器之间的界面基于主机控制器的硬件特性。USB系统层相对于主机控制器而言,处理的是以客户观点见到的数据传输及客户与设备的交互。这包括附加的USB信息,比如协议头(Protocol Wrappers)。USB系统还必须管理USB的系统资源,以使得客户的访问成为可能。

USB系统有三个主要组成部份:主机控制器驱动(Host Controller Driver)、USB驱动(USB Driver)和主机软件(host software)。

主机控制器驱动的存在,方便地将各种不同的主机控制器实现映射到USB系统,客户可以不必知道设备到底接在哪个主机控制器上就能同设备进行通信。USB驱动提供

25

了基本的面向客户的主机界面。在HCD与USB之间的接口称为主机控制器驱动接口(Host Controller Driver Interface HCDI)。这层接口不能被客户直接访问,所以也不是由USB具体来完成的。一个典型的HCDI是由支撑各种不同主机控制器的操作系统来定义的。

USBD提供I/O请求包(I/O Request Packets)形式的数据传输,以某一特定通道来传输数据。另外,USBD为它的客户提供一个容易被支配及配置的抽象的设备。作为这种抽象的一部份,USBD拥有标准通道对设备进行一些标准的控制。这标准通道实现了USBD与抽象设备之间的逻辑通信。

在有些操作系统中,提供了额外的非USB系统软件以支持设备的配置及设备驱动程序的加载。在这样的操作系统中,设备驱动程序应使用提供的主机软件接口而不是直接访问USBDI。

客户层描述的是直接与USB设备进行交互所需要的软件包。当所有的设备都已连上系统时,这些客户就可以直接通设备进行通信。一个客户不能直接访问设备的硬件。主机可提供如下的功能:

(1)检测USB设备的连接与断开;

(2)管理主机与设备之间的标准控制流;

26

(3)管理主机与设备之间的数据流;

(4)收集状态及一些活动的统计数字。

控制主机控制器与USB设备的电气接口,包括提供有限的能源。所有的集线器都通过状态改变通道报告它的状态的改变,其中包括设备的连上与断开等。USBD的一类特殊客户即:集线器驱动器拥有这些状态改变通道,接收这些状态的改变。对于像设备连结这种状态改变,集线器驱动器将加载设备的驱动程序。在有些系统中,这种集线器驱动程序是操作系统提供的主机软件的一部份,它用来管理设备。

2.7 USB分组标识

USB的分组标识(PID)用来标识操作的属性,PID指出了数据分组的类型,并可由此推断出分组格式和改组所用的校验方法。USB的通信结构一般是以PID开始的,后面紧跟着数据或控制信息,最后是CRC校验。

PID是由一个四位的分组类型码加上该四位类型码的反码组成,其格式如图2.3所示:

图2.3 PID分组码格式

27

2.8 USB的数据流包格式

USB的数据流以包的形式进行传输,根据PID的不同,将包分为四种,令牌包(Token Package),数据包(Data Package),握手包(Handshake Package),和特殊类型包(Special Package)。

2.8.1 令牌包

如图2.4所示为令牌包的格式。它由PID字段,ADDR(Address地址)字段,ENDP(End point,端点)字段和CRC(cyclic Redundancy Check,循环冗余校验),字段构成。PID包指定了包是输入输出还是建立类型,对于输出和建立事务,地址和端点字段唯一确定了哪个设备和端点接受数据包。对于输入事务,这些字段唯一确定了哪个端点应该传输数据包。只有主机能发出标记包。输入PID定义了从外设到主机的数据时务。格式如图2.4所示:

图2.4 令牌包格式

2.8.2 数据包

28

数据包由PID,大于或等于0个字节的数据的数据区和CRC构成。有两种类型的数据包,其中PID分别为DATA0和DATA1。这两种数据包是为了支持数据切换同步(DATA Toggle Synchronization)而定义的。格式如图2.5所示:

图2.5 数据包格式

2.8.3 握手包

握手包仅由PID构成。握手包用来报告数据事务的状态,能表示数据成功接受,命令的接受或拒绝,流控制和终止条件。如图2.6所示:

图2.6 握手包格式

2.8.4 特殊包

这个特殊前导(Special Preamble)封包拥有独自的PID类型名称PRE,仅用于主机想要从高速传输变成低速传输时,主机在想要送出低速的封包与低速设备通信之前,

29

先送出的PRE包,其格式如图2.7所示:

图2.7 握手包格式

2.9 本章小结

在本章中,重点研究与本文内容相关的USB1.0协议以及USB通信传诵数据包内容,包括拓扑结构、USB接口特性、编码方式与传输出类型、数据域及数据封包格式以及时数据格式等内容。它们是开发USB设备,完成与上位机软件通信的必要基础。

30

第3章 USB设备驱动程序的开发

3.1 USB驱动程序简介

在Windows环境下,不允许用户在应用程序中直接访问硬件设备,应用程序必须通过一个中间桥梁才能访问硬件设备,这个中间桥梁就是设备驱动程序。

驱动程序是一个软件,是连接应用程序、硬件以及操作系统的桥梁,装入后成为操作系统内核的一部分[4]。USB设备驱动程序为WDM模型,WDM引入了功能设备对象FDO和物理设备对象PDO两个新类来描述对象,一个真实硬件只能有一个PDO,但可以有多个FDO,在驱动程序中直接操作的是硬件的PDO和FDO[5]。WDM是通过设备的全局唯一标识符GUID来识别硬件设备。选取合适的开发工具后就可以根据实际情况编写USB设备驱动程序,然后还要编写和驱动程序通信的应用程序。USB设备与PC机之间的通信,除了读写数据外还有很多种类型,但读写数据是最基本的。所以把主要研究问题放在对USB接口的读与写方面。

在这里应用DriverStudio软件来编写驱动程序,DriverStudio把那些每个驱动程序都需要的代码都封装成类库。库代码自动地处理例行的操作,这极大地简小了任务的复杂度。而且,C++编译器提供了ANSIC 所不具备的优点:包括改进的类型安全检查,内连函数优化,以及更好的代码组织。

DriverWizard——DriverWorks 的代码向导,与微软的Visual C++紧密的集成。

31

超过1500行的驱动程序源代码框架只需几次鼠标点击就可完成。这些代码还包含了详细的注释。另外,DriverWizard还能生成专为特殊设备定制的代码,比如:USB设备,PCI设备,即插即用设备,ISA设备,等等。

3.2 USB驱动程序的开发过程

下面为用DriverStudio开发一个USB驱动程序的过程。写这个驱动程序只要用到DriverWorks[6]。

首先打开VC++6.0软件在菜单中选择DriverStudio选项中的DriverWorks则会出现如图的对话框(图3.1)。

图3.1 建立新工程

选择其中的Start aNew Driver Project选项,创建一个新工程。(图3.2)

32

图3.2 设置工程名称及保存位置

在这里,将这个工程称为:ForUsb,所在的目录为E:\\我的文档\\毕业设计\\driver。然后单击按钮“Next”。

33

图3.3 选择工程类型

在(图3.3)这个对话框中,需要选择驱动程序的类型。由于USB设备驱动程序是WDM类型的,所以选择第一项,并在下边选择Driverworks C++语言框架点击按钮“Next”。

34

图3.4 选择驱动程序的类型

图3.4对话框为选择类型,由于的USB设备驱动是要控制的硬件设备的,所以我们选择第一项,单击“Next”。

35

图3.5 设置设备的总线

在图3.5的对话框中,选择的驱动程序所操作的总线类型。这里选择USB。在USB Vendor ID和USB Product ID中填入USB设备的VID和PID。USB设备的VID和PID分别是16进制的0471和0677。点击“Next”。

点击对话框中的,可以选择电脑中连接的USB设备。在这里可以找到要识别的

USB实验板,可以点击select来选择这个硬件。

在接下来的对话框中,需要加入Endpoint1和Endpoint2的定义。由于在USB中规定Endpoint0是必须存在的,所以不需要对Endpoint0进行定义. 点“Add”按

36

钮,弹出一个的对话框,设置好如图所示。其中,按照USB的规定,对于端点,它的地址是1;按照前面说明的设备的特点,Endpoint1的最大的包大小为16字节,因此在“Max Transer Size”中填入16;Endpoint Name可以通过“Suggest Name”得到。按照这些原则,继续设置其他的配置,接下来继续按“Next”按钮。

图3.6 添加输入与输出信息

37

图3.7 设置接口信息

在对话框中,因为不需要给其他的驱动程序提供接口,也不需要提供Flush功能,所以不需要任何修改,直接按“Next”按钮。

38

图3.8 设置对其他设备的接口

如图3.9所示的对话框中,是给驱动程序增加一些IOCTL接口。如利用IOCTL来控制USB设备的LED灯、数码管显示等功能的接口。然后点击“Next”按钮。

39

图3.9 设置驱动的接口

在如图的对话框中,不需要创建任何注册表项,所以直接按“Next”按钮。

40

图3.10 创建注册表选项

接下来为电源设置,由于USB实验板不能自行供电,只能靠USB传输线供电。所以选择第1项,按“Next”按钮。

图3.11 电源设置

下图为设置本驱动程序的提供商,厂商的名字及设备描述,服务描述等。按“Next”按钮。

41

图3.12 驱动程序的各个信息

附加选项,直接点“Next”按钮。

42

图3.13 附加选项

43

图3.14 确认框图

最后得到确认框图,确认无误后选择“Finish”完成了USB设备的驱动程序的初步设置。

3.3 本章小结

DriverStudio软件可以快速地产生一个驱动程序。即使是写一个比较复杂的USB驱动程序,只要专注于自己的特定应用就可以了。

所以Windows环境下开发USB应用程序可以归结如下:在应用程序可以开始与HID交换数据前,应用程序必须先识别该设备并且读取它的报表信息,这些动作需要调用一堆API函数。应用程序首先需要寻找连接到系统上的是哪些HID设备,然后检验每个信息直到找到所需的属性。如果是客户化的设备,应用程序可以寻找特定的厂商与产品ID。或者应用程序可以寻找特定类型的设备。

44

第4章 上位机界面

4.1 上位机显示界面

为了简单适用,在创建工程时采用基于对话框的类型。

首先打开Visual C++软件,选择新建,在弹出的对话框中选择工程中的MFC AppWizard(exe)工程名为MFCApp,找到放置文件的位置后点击确定按钮,进入MFCAppWizard。

在MFC AppWizard应用程序向导第1步中,选择程序类型为对话框类型,之后单击确定按钮,弹出新建工程信息窗口,如果检查完全正确后,单击确定按钮生成应用程序所需的全部文件。

通过上述操作边生成了基于对话框的工程MFCApp[7]。首先在对话框中把原来的项目都删除,右键单击对话框选择属性,把标题改为USB实验板。在控件栏中,选择相应控件添加到对话框中,对其进行编辑代码,就可以通过对控件的操作来完成对程序的调用。

下面分别介绍各个控件完成的功能,并对控件内的代码进行描述与分析。

4.2 LED流水灯

45

图4.1 LED流水灯

1、预计完成的功能

当用鼠标点击LED框内的相应按钮时,在USB实验板相应位置上的流水灯会有亮灭的交替变化。如:当所有的流水灯都为灭的状态时,点击LED0按钮,流水灯1会变亮,再点击此按钮,灯1会变灭。点击其他按钮,相应的流水灯会有亮与灭的变化。界面显示如图4.1。

2、完成功能编写的程序

void CMFCAppDlg::OnLed0()

{

46

if(led&0x01)

led&=0xfe;//led=led&0xfe

else

led|=0x01;

OnLed();

}

3、完成功能的思想

在程序中事先定义了全局字符型变量led,在控件选项中选择按钮控件,首先添加8个按钮控件到到对话框中,把每个控件的属性名改为规定的LED0到LED7。每个按钮控件分别控制8位流水灯的亮和灭。然后打开Class Wizard 在CMFCAPPDlg类中,由于按键的单击属于通告消息,在object IDs中选择按钮的ID号IDC_BUTTON1所以选择BN_CLICKED,增加函数在弹出的对话框中添加OnLed0,编辑代码。在括号中,添加程序来完成对相应按钮的操作。其他按钮的内容同以上对按钮LED0的操作。

例如,当单击LED0按钮时,就调用 OnLed0这个函数的内容,这个函数的功能

47

就是要改变当前灯的状态。led&0x01的意思是led的值与16进制数0x01按位求与,就是取最后一位的值,这里用到了if语句,如果为1就执行led&=0xfe,为0就执行led|=0x01。led&=0xfe的与led=led&0xfe是相等的,意思是把原来led中的值与0xFE按位求与之后再赋给变量led,同理led|=0x01的意思就是把led的值与0x01按位取或之后再赋给led[8]。所以,当led最后一位原来为1,执行过这个函数后最后一位变为0,当led最后一位为0时执行过这个函数最后一位变为了0。之后执行OnLed()这个函数,OnLed()函数即为控制USB实验板上LED流水灯的语句。OnLed0()只对led最后一位进行操作,OnLed1()到OnLed7()对其它7位进行相应的转换。

void CMFCAppDlg::OnLed()

{

char buff[16];

char bufOutput[16];

ULONG nOutput;

buff[0]=0x01;

buff[1]=led;

48

if (!DeviceIoControl(hDevice,

FORUSB_IOCTL_Write,

buff,

16,

bufOutput,

0,

&nOutput,

NULL)

)

{

m_Mes=\"ERROR: DeviceIoControl returns .\";

49

UpdateData(FALSE);

}

}

在OnLed()函数中,首先创建了2个16位的字符数组buff[16]和bufOutput[16],前边的为向USB验板发送的数据,后边的为从USB设备接受的信息。还有1个无符号的长整型变量nOutput,把向实验板发送数据的第一位表示为元件的名称,从第2位开始为具体的传输内容,控制相应的元件完成其功能。这里16位字符数组的第1位为1,即表示控制LED流水灯,当USB实验板接受到这样的16位字符数组的时候先检查第1位的数字,就知道是要连接到相应的设备来完成响应的功能,第2位为变量led即为控制流水灯的程序。来完成流水灯相应的功能。否则如果连接不成功,则在状态显示编辑框中显示ERROR: DeviceIoControl returns。

4.3 矩阵键盘显示

50

图4.2 矩阵键盘

1、预计完成的功能

用鼠标点击矩阵键盘中的按钮,把16个矩阵键盘分别定义为16个数,在USB实验板数码管上会有相应的十六进制数显示。如点sw0按钮时数码管会显示0,点sw15按钮数码管会显示F。界面显示如图4.2。

2、完成功能需要编写的程序

void CMFCAppDlg::Onsw0()

{

sw=0;

Onsw();

}

3、完成功能的思想

51

首先创建16个按钮控件,分别把各个按钮的属性标题标注为sw0到sw15,然后打开Class Wizard 在CMFCAPPDlg类中,按钮的单击属于通告消息,所以选择sw0的ID号IDC_BUTTON10,在右边的Messages选项中选择BN_CLICKED,选择增加函数在弹出的对话框中输入函数名Onsw0,编辑代码。在括号中,可以添加相应的程序来完成对按钮的操作[9]。对于sw1到sw15这些按钮,如同sw0按钮的方法相同。

举sw0这个按钮为例,当点击sw0按钮时,程序会自动调用Onsw0这个函数,这个函数首先把0赋值给了字符变量sw,然后执行Onsw()这个函数。当然在程序中需要首先定义字符变量sw,否则程序无法识别sw0,会出现错误。

void CMFCAppDlg::Onsw()

{

char buff[16];

char bufOutput[16]; // Output from device

ULONG nOutput;

buff[0]=0x02;

52

buff[1]=sw;

if (!DeviceIoControl(hDevice,

FORUSB_IOCTL_Write,

buff,

16,

bufOutput,

0,

&nOutput,

NULL)

)

{

53

m_Mes=\"ERROR: DeviceIoControl returns .\";

UpdateData(FALSE);

}

}

具体格式与函数OnLed()相同,只是对传送字符数组变量值有所区别,在这里数组的第1位附值为十六进制的0x02,表示这个消息从矩阵键盘发出,为了控制USB实验板上数码管显示的[10]。第2位值为字符变量sw,即把相应的按钮信息传给了USB实验板。得到了按钮信息之后,USB实验板把对数码管显示的控制设置好,就可以完成相应的通信,实现数码管显示上位机按键信息的功能。

4.4 蜂鸣器

图4.3 蜂鸣器

1、预计完成的功能

54

用鼠标点击蜂鸣器按钮,蜂鸣器会出现响与不响的交替变化。界面显示如图4.3。

2、完成功能所编写的程序

void CMFCAppDlg::OnBuzzer() {

UpdateData(TRUE);

char buff[16];

ULONG nOutput;

buff[0]=0x03;

buff[1]=!m_buzzer;

if (!DeviceIoControl(hDevice,

FORUSB_IOCTL_Write,

55

buff,

16,

NULL,

0,

&nOutput,

NULL)

)

{

m_Mes=\"ERROR: DeviceIoControl returns .\";

UpdateData(FALSE);

}

56

}

3、完成功能的思想

首先创建按钮控件,把按钮的属性标题改为蜂鸣器,然后打开Class Wizard 在CMFCAPPDlg类中,选则BN_CLICKED,增加一个函数OnBuzzer,编辑代码。由于是按钮控件,并且也是按钮实现蜂鸣器响与不响的相互转换,这与对流水灯的控制很相似,首先定义了一个16位的字符数组变量buff[16],与对流水灯的控制相同,字符数组的第一位表示控制的是蜂鸣器,选择了十六进制的0x03,第2位为具体对蜂鸣器的操作,首先对按钮设置了一个成员变量m_buzzer,对m_buzzer的操作就相当与对蜂鸣器按钮的操作[11]。因此第2位的意思为前一次操作的逆操作,故可以控制蜂鸣器的响与不响。

在此需要声明一下,3个函数中都定义了一个16位的字符数组buff[16],但是它们是没有直接关系的,每一个函数都为局部变量,都仅在函数内部有效而在函数外部无效[12]。只有全局变量在任何部分都会发生作用,但是在函数内部一旦出现与全局变量同名的局部变量时,在函数内部调用用局部变量,而在函数外部继续使用全局变量。

4.5 数码管显示

57

图4.4 数码管显示

1、预计完成的功能

在数码管显示区编辑框内输入数字,当6个编辑框内同时有数字输入时,在USB实验板上的数码管会有相应的数字显示,每个编辑框内的字符长度仅为一位且必须为数字。界面显示如图4.4。

2、完成功能所编写的程序

void CMFCAppDlg::OnChangeLeft()

{

UpdateData();

if(m_left.GetLength()==0||m_right.GetLength()==0||

m_edit6.GetLength()==0||m_edit7.GetLength()==0||

m_edit8.GetLength()==0||m_edit9.GetLength()==0)

58

return;

char buff[16];

ULONG nOutput;

buff[0]=0x04;

buff[1]=m_left.GetAt(0)-'0';

buff[2]=m_right.GetAt(0)-'0';

buff[3]=m_edit6.GetAt(0)-'0';

buff[4]=m_edit7.GetAt(0)-'0';

buff[5]=m_edit8.GetAt(0)-'0';

buff[6]=m_edit9.GetAt(0)-'0';

if (!DeviceIoControl(hDevice,

59

FORUSB_IOCTL_Write,

buff,

16,

NULL,

0,

&nOutput,

NULL)

)

{

m_Mes=\"ERROR: DeviceIoControl returns .\";

UpdateData(FALSE);

60

}

}

完成其他编辑框的代码为调用OnChangeRight()、OnChangeEdit6()、OnChangeEdit7()、OnChangeEdit8()、OnChangeEdit9()函数,与调用OnChangeLeft() 函数相同。

3、完整功能编写代码的作用

首先在对话框中添加6两个编辑框控件,在属性表单的样式中选择数字,这样我们在编辑框中就只能输入数字,然后打开Class Wizard 在CMFCAPPDlg类中找到编辑框的ID号IDC_EDIT1,选则EN_CHANGE,意思为在编辑框中输入字符时调用函数,增加函数在弹出的对话框中添加函数名OnChangeLeft,编辑代码。先把编辑框控件分别关联成员变量m_left、m_right、m_edit6、m_edit7、m_edit8、m_edit9可以分别用成员变量来控制相应编辑框的数据。先从编辑框中获取数据,只有6个编辑框中的字符长度都不为0时才调用以下的函数,否则6个编辑框中有一个为空,则跳出此程序。由于完成这个函数也是向USB实验板发送消息,所以完成这个消息的框架跟完成流水灯的相同,第1位依然为控制元件的消息代码,这里应用了16进制数0x04来表示消息由数码管显示元素编辑框发出,告诉这个消息是控制数码管的,第2位为取ID号为IDC_EDIT1编辑框中的值,第3位为取ID号为IDC_EDIT2编辑框中的值。第4位为取ID号为IDC_EDIT6编辑框中的值,第5位为取ID号为IDC_EDIT7编辑框中的值,

61

第6位为取ID号为IDC_EDIT8编辑框中的值,第7位为取ID号为IDC_EDIT9编辑框中的值,USB实验板得到这个16位消息后按位控制,得到对数码管的显示控制。

4.6 液晶显示

图4.5 液晶显示

1、预计完成的功能

在显示界面上的两个编辑框中输入数字或者字母,在USB实验板上的液晶显示器就会显示出来。如果编辑框中输入的为汉字信息,则会弹出提示对话框(只能输入英文字母和数字)。界面显示如图4.5。

2、完成功能所编写的程序

void CMFCAppDlg::OnChangelcd1()

{

62

UpdateData();

if(!IsE(&m_lcd1))

{

MessageBox(\"只能输入英文字符\");

m_lcd1=\"\";

UpdateData(FALSE);

}

char buff[18];

ULONG nWritten;

memset(buff,' ',18*sizeof(char));

buff[0]=1;

63

buff[1]=1;

for(int i=0;i!=m_lcd1.GetLength();i++)buff[i+2]=m_lcd1.GetAt(i);

WriteFile(hDevice, buff, 18, &nWritten, NULL);

}

BOOL CMFCAppDlg::IsE(CString * str)

{

for(int i=0;i!=str->GetLength();i++)

if(str->GetAt(i)>255||str->GetAt(i)<0)return FALSE;

return TRUE;

}

3、完整功能编写代码的作用

64

首先创建两个编辑框控件,打开Class Wizard为其添加成员变量m_lcd1、m_lcd2,之后为其添加一个函数OnChangelcd1,在编辑框中有输入的时候调用这个函数。然后添加一个查错的布尔型函数IsE,当在编辑框中输入大于255或小于0的字符时就会显示错误,否则显示正确[13]。在调用函数中,首先把编辑框中的数据传送到变量中,调用查错函数,看输入的是否符合标准,如果输入的为汉字,则弹出对话框提示“只能输入英文字符”。之后声明一个18位的字符数组,用来发送消息,然后根据输入的字符长度来决定发送字符数组的内容[14]。USB设备接收到信息就会在液晶显示器上显示在编辑框中所输入的字符[15]。

4.7 温度显示区

图4.6 温度显示区

1、预计完成的功能

在显示界面上的编辑框中可以正确显示USB实验板上温度传感器收到的室内温度。界面显示如图4.6。

65

2、完成功能所编写的程序

void CMFCAppDlg::wendu()

{

char wen; // Output from device

ULONG nOutput;

if (!DeviceIoControl(hDevice,

FORUSB_IOCTL_Read,

NULL,

0,

&wen,

1,

66

&nOutput,

NULL)

)

{

m_Mes=\"ERROR: DeviceIoControl returns .\";

UpdateData(FALSE);

}

m_wendu=wen;

UpdateData(FALSE);

}

3、完成功能编写代码的作用

67

首先创建一个编辑框控件,打开Class Wizard为其添加一个成员变量m_wendu,之后对m_wendu的操作即为对这个编辑框的操作。在CMFCAppDlg类中添加成员变量,返回值为void,函数名为wendu。在函数中编写程序。先定义一个字符型变量wen,无符号的长整型变量nOutput,之后执行传输函数,由于是要从USB设备接受消息,所以调用函数为FORUSB_IOCTL_Read[16],前两个参数为从PC机向USB设备发送的消息变量名和格式,中间的为从USB设备接受的消息变量的名称和格式。把接受到的信息赋给成员变量m_wendu,最后将变量中的参数传诵到编辑框中显示出来就完成了此功能[17]。

4.8 本章小结

本章主要讨论了上位机软件的显示部分,分别介绍了LED流水灯,矩阵键盘按键显示,蜂鸣器,数码管显示,液晶显示,温度显示区等显示界面元素的编辑代码,需要完成的主要功能。全面地介绍了上位机软件编写的整个过程,完成了上位机显示界面的编写,并可以与USB实验板连接,完成相应的功能。

结 论

本文将USB协议和传输方式做了很详细的介绍,相互通信就需要对通信双方的传输格式有相应的了解。在相互发送的数据包中,规定第1位为控制显示元件的种类,从第2位开始为控制该元件的具体操作,这样在通信过程中USB设备或者PC机首先检测第1

68

位,收到消息知道对方要控制哪一个元件,确定元件之后,继续读消息,知道具体的控制信息,这样就完成了PC机与USB设备的相互通信。

对于USB设备的驱动程序,使用DriverStudio软件进行开发,由于是头一次进行驱动程序的开发所以不免有很多地方存在问题,出现不识别USB设备、识别后不能连接等问题。在不断地学习与修改中驱动程序可以完成对USB设备的识别。设备配置的不同,驱动程序也将有所不同,因此需要开发满足自己硬件要求的驱动程序。

利用VC编程,控制对计算机底层硬件的操作,利用驱动程序这个“翻译”,把VC++程序中的数组代码转换成USB设备可以识别的数据传输到单片机中,对USB设备进行控制。

利用VC++环境下的MFC应用程序框架,开发虚拟显示界面。它能够对USB实验板进行相应的按钮控制,同时,可以接受到USB发送的消息,并显示在相应的编辑框中。完成主机与设备之间的交互。

本文成功实现了PC机与USB设备的数据传输。随着USB技术的推广和普及,将会有越来越多的计算机外围设备采用这种总线技术,USB设备的软硬件设计技术有着广泛的应用前景。

参考文献

69

[1] 陈逸.USB大全[M],北京:中国电力出版社,2001:110-115.

[2] 邱罡,王伟.用VC++编写USB人机接口类通信程序[J].平顶山学院学报,2005,20(5):76-78.

[3] 王成儒,李英伟.USB1.0协议原理与工程开发[M].北京:国防工业出版社,2004.

[4] (美)坎特,C著.孙义译.Windows设备驱动开发指南[M] .北京:机械工业出版社,2000.

[5] Art Baker,Jemry Lozano著.施诺译.Window XP设备驱动程序设计指南[M] .北京:机械工业出版社,2003.

[6] DriverStudio开发USB驱动程序

[EB] .http://blog.csdn.net/luckysolar/archive/2007/01/09/1478508.aspx

[7] 甘玲,邱劲.面向对象技术与Visual C++[M] .北京:清华大学出版社,2004.

[8] 陈火旺.C++面向对象程序设计[M].中南大学出版社,2005.

[9] 朱晴婷,黄还鹰,陈莲君.Visual C++程序设计——基础与实例分析[M].北京:清华大学出版社,2004.

70

[10] 孙鑫,余安萍.VC++深入祥解[M] .北京:电子工业出版社,2006.

[11] 谭浩强.C语言程序设计[M].北京:清华大学出版社,2003.

[12] Ion Bates .Tim Tompkins著.何健辉等译.实用Visual c++6.0教程[M] .北京:清华大学出版社.

[13] 钱能.C++程序设计[M].北京:清华大学出版社,2002

[14] 黄惟通.VC++面向对象程序设计[M].北京:清华大学出版社,2003.

[15] 刘小石,郑淮,马林伟等.精通Visual C++6.0[M] .北京:清华大学出版社,2000:37-41.

[16] 周立功等.PDIUSBD12USB固件编程与驱动开发[M] .北京:北京航空航天大学出版社,2003.

[17] 莫林利,赵秀绍.用VC++实现与USB驱动程序的通信[J] .电脑编程技巧与维护.2003(1) .

致 谢

71

值此论文完成之际,谨向我的导师刁鸣老师表示衷心的感谢!从选题,设计以及后来的调试都得到了刁鸣老师的帮助。尽管刁老师很忙,但是在我编写上位机软件期间,每天多次在实验室进行指导,询问进度情况,督促我的工作,尽心尽力,甚至周末,也不曾休息,通过电话等方式询问进展情况。我能顺利完成,与刁老师的帮助密不可分。在我与搭档一起对USB实验板功能进行调试的时候,刁老师更给了我们不少建议与意见,让我们少走了不少的弯路。

同时,对804教研室表示感谢,感谢他们在资源有限的情况下,给我提供了良好的软硬件环境,使得我能够全力投入到工作中。在我软件调试、连机通信期间,得到郭天祥的帮助,在此表示忠心的感谢!

在此期间,还有许多同学给了我很大的帮助,在我很迷惑的时候是跟他们一起研究学习,最后完成了软件的编写。没有他们我的软件设计过程不会那么顺利,在此,我对所有关心过我、帮助过我的人表示最衷心的谢意!

附 录

72

USB实验板正确连接时的显示界面

73

目 录

第1章 绪论 ...................................................................................................................................... 1

1.1 USB简介 ............................................................................................................................. 1 1.2 USB驱动程序的意义 ......................................................................................................... 2 1.3 VC++软件的介绍 ................................................................................................................ 2 1.4 系统方案设计 ...................................................................................................................... 3 1.5 预期结果 .............................................................................................................................. 3 第2章 USB协议 .............................................................................................................................. 5

2.1 USB系统的使用分类及系统的描述 ................................................................................. 5 2.2 USB物理接口的电器特性 ................................................................................................. 7

2.2.1 USB物理接口 .......................................................................................................... 7 2.2.2 电源 ........................................................................................................................... 8 2.2.3 总线协议 ................................................................................................................... 9 2.3 USB设备 ........................................................................................................................... 14

2.3.1 设备特性 ................................................................................................................. 14 2.3.2 设备描述 ................................................................................................................. 15 2.3.3 设备状态 ................................................................................................................. 16 2.4 Bus Enumeration总线标号 ............................................................................................... 18 2.5 通用USB设备操作 .......................................................................................................... 20 2.6 USB主机 ........................................................................................................................... 23 2.7 USB分组标识 ................................................................................................................... 27 2.8 USB的数据流包格式 ....................................................................................................... 28

2.8.1 令牌包 ..................................................................................................................... 28 2.8.2 数据包 ..................................................................................................................... 28 2.8.3 握手包 ..................................................................................................................... 29 2.8.4 特殊包 ..................................................................................................................... 29

2.9 本章小结 ............................................................................................................................ 30 第3章 USB设备驱动程序的开发 ................................................................................................ 31

3.1 USB驱动程序简介 ........................................................................................................... 31 3.2 USB驱动程序的开发过程 ............................................................................................... 32 3.3 本章小结 ............................................................................................................................ 44 第4章 上位机界面 ......................................................................................................................... 45

4.1 上位机显示界面 ................................................................................................................ 45 4.2 LED流水灯 ....................................................................................................................... 45 4.3 矩阵键盘显示 .................................................................................................................... 50 4.4 蜂鸣器 ................................................................................................................................ 54 4.5 数码管显示 ........................................................................................................................ 57 4.6 液晶显示 ............................................................................................................................ 62 4.7 温度显示区 ........................................................................................................................ 65 4.8 本章小结 ............................................................................................................................ 68 结 论 ............................................................................................................................................. 68 参考文献 ............................................................................................................................................. 69 致 谢 ............................................................................................................................................. 71 附 录 ............................................................................................................................................. 72

因篇幅问题不能全部显示,请点此查看更多更全内容