摘要:情报指挥系统维修模拟训练器中采用USB作为计算机与仿真单体的接口,本文从工作原理、硬件设计、固件程序、主机程序和驱动程序五个方面论述了USB接口的开发过程,并给出了基于控制传输的USB系统设计方法。
关键词:USB;控制传输;固件;驱动
1、工作原理
情报指挥系统维修模拟训练器属于分布式仿真系统,系统结构如图1所示。其中,各仿真节点由单体计算机和仿真单体组成,仿真网络采用局域网,主控机用于集中配置各单体参数,触摸屏用于模拟操作界面。因为USB总线具有结构简单、即插即用、低功耗、广泛的软硬件支持等优点,传输速度也从USB1.1协议支持的12Mbps 发展到了USB2.0协议支持的480Mbps,另外其星型拓扑结构能支持多达127个外设同时工作,所以本系统采用USB总线来实现单体计算机和仿真单体之间的控制和通信。
图1 系统框图
1.1 USB的枚举与重枚举
USB芯片具有软特性,外设可以利用USB接口从主机8051程序代码到内部RAM运行,而不需要外部程序存储器,方便了固件调试和升级。为支持这种软特性,USB将端点0作为默认地址,外设初次连接主机时作为默认设备使用端点0进行自动枚举,当固件到内部RAM后,经过重枚举使外设具有用户在固件中设置的功能属性。
外设和主机连接时会自动加载驱动程序,加载什么驱动程序由USB设备描述符中的VID(2个字节)和PID(2个字节)决定,默认设备的VID和PID是0547和2131。当有多个外设同时工作时,需要不同的VID和PID加以区分,可利用EEPROM来存储外设的VID和PID信息,以便加载对应的驱动程序。
1.2 USB传输类型
USB定义了控制、中断、批量和同步四种数据传输类型。控制传输是复杂和重要的传输类型,也是USB枚举阶段主要的数据交换方式。USB设备初次连到主机后就是通过控制传输来读取地址信息和设备描述符的,这样主机才能识别设备并安装相应的驱动程序,其它三种传输方式也才能够得以使用。因此,控制传输是其它三种传输的前提和基础。
中断传输主要用于数据量小、速度要求不高的数据传输,如鼠标、键盘等;批量传输主要用于大容量数据的传输,比如硬盘接口、刻录机接口等;同步传输多用于音频流等需要恒定传输速率的数据传输,比如音箱、显示器的接口等。
在维修模拟训练器中,单体计算机和仿真单体之间传输的主要是控制信息,数据量不大,因此主要采用控制传输。
2、 USB硬件电路设计
USB硬件电路的是USB芯片,本电路采用的是Cypress公司提供的AN2131QC,封装形式为80引脚PQFP。其结构框图如图2所示,USB收发器与USB总线的 D+和D-相连,串行接口引擎对串行数据进行编码和译码,并执行错误更正、位填充等操作,发送数据字节到端口或从端口接收数据字节。内部微处理器是一个改进的8051内核,使用标准的8051指令系统,但执行速度更快,功能更强,与标准8051相比具有以下不同:
(1)一个总线周期包含4个时钟周期,空闲周期被消去,而标准8051则为12个时钟周期,因此速度提高了3倍;
(2)增加了第二个数据指针;
(3)增加了第二个UART;
(4)增加了第三个16位定时器;
(5)非多路复用的16位地址总线;
(6)增加了8个中断。
设计AN2131QC的外围电路时,要注意以下几个问题:
(1)AN2131QC有总线供电和外部供电两种供电方式,主机可以向外围USB设备提供500mA的电流,当USB设备耗电小于500mA时就可以使用总线供电。AN2131QC的工作电压是+3.3V,总线提供的电压是+5V,可以用电压转换芯片MAX882或AMS1117进行电压转换。电源引脚2、21、22、42、62都接+3.3V,并通过一个0.1uF电容接地,使电压更加稳定。引脚5、6、13、14、72通过 1K电阻接地。
(2)USBD+和USBD-通过24Ω电阻接到USB总线的D+和D-,可抑制噪声干扰。
(3)Xin(19)和Xout(20)之间接12MHz晶振,并通过两个30pF电容接地。
(4)Reset(25)引脚通过0.1uF电容接+3.3V,10K电阻接地。
(5)SDA(64)、SCL(65)、Wakeup(66)、WR(40)、RD(41)通过10K上拉电阻接+3.3V。
3、 固件程序
USB固件程序用Keil C编写,使用Keil uVision编译器进行编译调试。一个USB固件主要包括以下文件:
Fw.c:固件框架源文件,main()函数就位于该文件中;
Periph.c:用户函数定义,用户初始化函数TD_Init()和用户函数TD_Poll()的定义就位于该文件中;
Dscr.a51:USB描述符表,对加载驱动程序有重要意义的VID和PID信息就位于该文件的设备描述符中;
Ezusb.lib:EZ-USB固件函数库;
USBJmpTb.OBJ:中断向量和跳转表。
Ezusb.h、Ezregs.h:编写程序时必须包括的头文件,前者包含USB函数库的常量定义、宏定义、全局变量声明和函数原型等,后者包含位标志定义和寄存器变量声明。
固件程序的运行流程如图3所示,USB上电复位后进入main()函数先初始化内部状态变量,然后调用用户初始化函数TD_Init()。从该函数返回后使能中断,然后每隔1s进行设备重枚举直到端点0接受到主机的SETUP数据包。检测到SETUP包后开始任务调度,任务调度的步骤如下:
(1)调用用户函数SetupCommand(),判断是否受到SETUP包;
(2)分析判断SETUP包,如果是标准设备请求命令则执行标准请求,如果是用户请求命令则调用TD_Poll()进行数据处理并反馈给主机结果;
(3)判断是否收到USB挂起信号,收到则调用TD_Suspend()。从该函数返回后再检测是否发生USB唤醒事件,未检测到则处理器进入挂起状态,否则调用TD_Resume(),程序继续运行。
需要用户自己编写的代码主要包括TD_Init()、TD_Poll()。在本系统中,TD_Init()主要完成端点的选择和配置,以及外围器件的初始化。TD_Poll()将根据接收的主机命令对数据进行处理,之后将处理结果或状态信息反馈给主机。
4、 主机程序
主机程序主要用于发送用户命令和参数,接收USB设备的运行状态和处理结果。本系统的主机程序用VC++6.0编写实现,因为采用的是控制传输,用到的主要函数是CreateFile()和DeviceIoControl()。前者用于获得设备句柄,其本质是先由设备驱动器生成一个句柄,然后将这个句柄分配给外设。获得设备句柄后,用DeviceIoControl()对设备进行读写。主要程序代码如下:
DeviceHANDLE=CreateFile("\\\\.\\ezusb-0",
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
If (DeviceHANDLE==INVALID_HANDLE_VALUE)
MessageBox("无法创建设备","Information Box",MB_OK|MB_ICONINFORMATION);
bResult=DeviceIoControl(DeviceHANDLE,
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
&myrequest,
sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL),
returndata,
n,
&nBytes,
NULL);
在本系统中,主机发送给外设多的是VENDOR_OR_CLASS_REQUEST_CONTROL类型的请求,其结构定义如下:
typedef struct _VENDOR_OR_CLASS_REQUEST_CONTROL
{
UCHAR direction; //传输方向,0为主机到设备,1为设备到主机
UCHAR requestType; //请求类型,0为用户,1为类
UCHAR recepient; //接收者类型,0为设备,1为接口,2为端点,3为其他
UCHAR requestTypeReservedBits;
UCHAR request;
USHORT value;
USHORT index;
};
其中后四个参数分别对应于设备请求命令的bRequestType、bRequest、wValue和wIndex(具体定义参考文献[1]),因为发送的是用户自己的设备请求命令而非标准设备请求命令,所以bRequestType的值可设为0;且bRequest的值不能与标准设备请求命令的bRequest值相冲突;双字节的value和index可用来传递主机给USB设备的参数。
5、 驱动程序
要实现USB设备的固件和重枚举需要编写两个驱动程序,通用驱动(GPD)和固件装载驱动。前者完成主机与外设的通信和控制,一般不用重新编写,可直接采用Cypress公司提供的ezusb.sys。后者负责在外设连到主机时将正确的驱动程序装载到AN2131QC的RAM中,完成对外设的重新设置。主机根据新的设置安装通用驱动,重新枚举外设为一个新的USB设备。固件装载驱动的开发过程如下:
(1)新建一个目录dev_io,将Cypress\usb\drivers\ezloader目录下的文件复制到该目录下。
(2)打开该目录下的sources文件,将TARGETNAME=ezloader改为TARGETNAME=dev_io。
(3)利用hex2c将dev_io.hex转换为dev_io.c: hex2c dev_io.hex dev_io.c
(4)将fireware.c中的fireware[]数组用dev_io.c中的fireware[]数组替换。
(5)进入C:\NTDDK\BIN目录,在命令行方式下键入SETENV C:\NTDDK回车,此时显示设置环境完成,然后返回dev_io运行BUILD –c,这时会在dev_io\lib\i386\free或checked目录下生成我们需要的固件装载设备驱动程序,将该驱动程序复制到c:\windows\system32\drivers目录下。
(6)为了使该驱动程序正确工作,必须为它写一个安装信息文件,即.inf文件。它将设备的VID和PID绑定到特定的设备驱动程序上。可仿照开发包提供的inf文件编写,具体步骤参见文献[5]。
6、结束语
本文从工作原理、硬件设计、固件程序、主机程序和驱动程序五个方面系统论述了情报指挥系统维修模拟训练器中USB接口开发的全过程,并给出了基于控制传输的USB系统设计方法,为今后的维修模拟训练系统开发提供了一种规范、快捷的接口设计方法。
本文的创新观点主要有两点:1、与传统的VXI、PXI等总线相比,在情报指挥系统维修模拟训练器中采用USB总线作为仿真单体和单体计算机之间的接口能简化硬件,即插即用,使仿真单体具有便携能力。2、USB接口支持多达127个外设的能力使系统具有很强的单体扩展能力,而且支持多个单体同时工作
[1]. AN2131QC datasheet https://www.dzsc.com/datasheet/AN2131QC_2520925.html.
[2]. MAX882 datasheet https://www.dzsc.com/datasheet/MAX882_1058134.html.
[3]. AMS1117 datasheet https://www.dzsc.com/datasheet/AMS1117_134467.html.
[4]. EZ-USB datasheet https://www.dzsc.com/datasheet/EZ-USB_305660.html.
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。