usb接口设计.docx
《usb接口设计.docx》由会员分享,可在线阅读,更多相关《usb接口设计.docx(18页珍藏版)》请在冰点文库上搜索。
usb接口设计
6.4USB接口实验
6.4.1实验目的
了解USB接口基本原理。
掌握通过USB接口与PC通讯的编程技术
6.4.2实验设备
硬件:
EmbestEduKit-III实验平台,EmbestARM标准/增强型仿真器套件,PC机。
软件:
EmbestIDEProARM集成开发环境,Windows98/2000/NT/XP。
6.4.3实验内容
编写USB通信程序程序,基于已有的USB驱动程序接口,完成与PC端的USB测试程序之间的
数据接收与发送。
6.4.4实验原理
1.USB基础
定义
通用串行总线协议USB(UniversalSerialBus)是由Intel、Compaq、Microsoft等公司联
合提出的一种新的串行总线标准,主要用于PC机与外围设备的互联。
1994年11月发布第一个草案,
1996年2月发布第一个规范版本1.0,2000年4月发布高速模式版本2.0,对应的设备传输速度也
从1.5Mb/s的低速和12Mb/s的全速提高到如今的480Mb/s的高速。
其主要特点是:
支持即插即用。
允许外设在主机和其它外设工作时进行连接配置使用及移除。
传输速度快。
USB支持三种设备传输速率:
低速设备1.5Mb/s、中速设备12Mb/s和高速设备
480Mb/s。
连接方便。
USB可以通过串行连接或者使用集线器Hub连接127个USB设备,从而以一个串
行通道取代PC上其他I/O端口如串行口、并行口等,使PC与外设之间的连接更容易。
独立供电。
USB接口提供了内置电源。
低成本。
USB使用一个4针插头作为标准插头,通过这个标准插头,采用菊花链形式可以把多达
127个的USB外设连接起来,所有的外设通过协议来共享USB的带宽。
组成
USB规范中将USB分为五个部分:
控制器、控制器驱动程序、USB芯片驱动程序、USB设备
以及针对不同USB设备的客户驱动程序。
控制器(HostController),主要负责执行由控制器驱动程序发出的命令,如位于PC主板的
USB控制芯片。
控制器驱动程序(HostControllerDriver),在控制器与USB设备之间建立通信信道,一般
由操作系统或控制器厂商提供。
USB芯片驱动程序(USBDriver),提供对USB芯片的支持,设备上的固件(Firmware)。
USB设备(USBDevice),包括与PC相连的USB外围设备。
设备驱动程序(ClientDriverSoftware),驱动USB设备的程序,一般由USB设备制造商提
供。
传输方式
针对设备对系统资源需求的不同,在USB规范中规定了四种不同的数据传输方式:
同步传输(Isochronous),该方式用来联接需要连续传输数据,且对数据的正确性要求不高而
对时间极为敏感的外部设备,如麦克风、嗽叭以及电话等。
同步传输方式以固定的传输速率,连续不
断地在主机与USB设备之间传输数据,在传送数据发生错误时,USB并不处理这些错误,而是继续
传送新的数据。
同步传输方式的发送方和接收方都必须保证传输速率的匹配,不然会造成数据的丢失。
中断传输(Interrupt),该方式用来传送数据量较小,但需要及时处理,以达到实时效果的设备,
此方式主要用在偶然需要少量数据通信,但服务时间受限制的键盘、鼠标以及操纵杆等设备上。
控制传输(Control),该方式用来处理主机到USB设备的数据传输,包括设备控制指令、设备
状态查询及确认命令,当USB设备收到这些数据和命令后,将依据先进先出的原则处理到达的数据。
主要用于主机把命令传给设备、及设备把状态返回给主机。
任何一个USB设备都必须支持一个与控制
类型相对应的端点0。
批量传输(Bulk),该方式不能保证传输的速率,但可保证数据的可靠性,当出现错误时,会要
求发送方重发。
通常打印机、扫描仪和数字相机以这种方式与主机联接。
关键定义
USB主机(Host)
USB主机控制总线上所有的USB设备和所有集线器的数据通信过程,一个USB系统中只有一个
USB主机,USB主机检测USB设备的连接和断开、管理主机和设备之间的标准控制管道、管理主机
和设备之间的数据流、收集设备的状态和统计总线的活动、控制和管理主机控制器与设备之间的电气
接口,每一毫秒产生一帧数据,同时对总线上的错误进行管理和恢复。
USB设备(Device)
通过总线与USB主机相连的称为USB设备。
USB设备接收USB总线上的所有数据包,根据数
据包的地址域来判断是否接收;接收后通过响应USB主机的数据包与USB主机进行数据传输。
端点(Endpoint)
端点是位于USB设备中与USB主机进行通信的基本单元。
每个设备允许有多个端点,主机只能
通过端点与设备进行通讯,各个端点由设备地址和端点号确定在USB系统中唯一的地址。
每个端点都
包含一些属性:
传输方式、总线访问频率、带宽、端点号、数据包的最大容量等。
除控制端点0外的
其他端点必须在设备配置后才能生效,控制端点0通常用于设备初始化参数。
USB芯片中,每个端点
实际上就是一个一定大小的数据缓冲区。
管道(Pipe)
管道是USB设备和USB主机之间数据通信的逻辑通道,一个USB管道对应一个设备端点,各端
点通过自己的管道与主机通信。
所有设备都支持对应端点0的控制管道,通过控制管道主机可以获取
USB设备的信息,包括:
设备类型、电源管理、配置、端点描述等。
2.USB设备开发
USB设备开发包括硬件电路设计和软件设计二部分内容,其中软件部分又包括USB芯片驱动程
序和应用程序二部分。
USB设备在硬件上通过USB芯片实现,USB芯片负责:
管理和实现USB物理层差分信号;
通过配置和管理寄存器初始化设备。
提供连接的端点;
电源管理;
通过寄存器管理端点;
USB芯片驱动程序基于以上硬件资源实现USB的功能。
USB芯片提供多个标准的端点,每个端点都支持单一的总线传输方式。
端点0支持控制传输,其
他端点支持同步传输、批量传输或中断传输中的任意一种。
管理和使用这些端点,实际上就是通过操
作相应的控制寄存器、状态寄存器、中断寄存器和数据寄存器来实现。
其中,控制寄存器用于设置端点的工作模式、启用端点的功能等;状态寄存器用于查询端点的当前状态;中断寄存器则用于设置端
点的中断触发和响应功能;数据寄存器则是设备与主机交换数据用的缓冲区。
电路设计原理
EmbestEduKit-IIIUSB接口模块采用美国国家半导体公司的USBN9603USB控制器,该控
制器是全速USB节点器件,完全兼容USB1.0,USB1.1通信规范。
USBN9603/4-28M芯片引脚图如下:
USBN9603与MCU的接口模式分为两种:
8位并行总线模式(ParallelInterface),使用并行总线方式时又可选择复用(Multiplexed)
或非复用(Non-Multiplexed)模式,其中地址/数据线的复用方式电路设计稍显复杂。
微总线模式(MICROWIREinterface)。
以上模式的选择由管脚MODE0,MODE1决定。
在使用复用的8位并行总线模式下,USBN9603支持与MCU之间的增强型DMA方式传输,使
用DMA方式传输使MCU和USBN9603之间交换数据的速度成倍提高,最终可以显著提高PC与USB
的通讯速度。
USBN9603在EmbestEduKit-III评估板与CPU连接图如下:
EduKit-III的电路设计中采用的是非复用的8位并行总线模式,该模式中没有使用DMA方式,
因此DACK接高电平。
CPU通过译码器生成的片选信号CS1对USB控制器进行选通,USBN9603
通过EXINT1对CPU发出中断请求。
设备驱动程序设计
USB读写
EmbestEduKit-III的USB控制器USBN9603用户寄存器有两个,分别为只写的内部地址寄
存器,与可读写的数据寄存器,内部地址寄存器的地址为0x02000002,数据寄存器地址为
0x02000000。
对USB控制器进行读操作(包括读USB内部寄存器及数据)时,第一步是设置USB6bits宽的内部地址寄存器,指明将要从USB某个内部地址读一个字节,第二步是从数据寄存器读出8bits宽的
数据。
对USB进行写操作类似读操作,第一步同样是设置USB的内部地址寄存器,指明将要写一个字
节数据到USB内部某个地址中去。
USB中断
EmbestEduKit-III的USB控制器中断请求引脚连接S3C44B0X外部中断引脚EXINT1,对
应的中断向量为1,初始化USB中断的步骤是:
使EINT1中断使能。
安装USB中断服程序入口到中断向量中去。
初始化IO端口G组控制器PCONG,PUPG指明EXINT1是作为中断输入引脚使用。
设置外部中断寄存器EXTINT,指明触发中断方式。
初始化USB
初始化USB需要使用USB读写函数对USB控制器内部的控制寄存器进行设置。
需要设置的USB
控制寄存器如下:
首先,通过设置主控制寄存器MCNTRL软件复位位(SRST),复位USB控制器。
设置主控制寄存器MCNTRL,电压调整位(VGE),及中断输出(INTOC)位,以禁止中断输出。
写时钟寄存器CCONF,设置USB控制器工作频率。
初始化功能地址寄存器FAR(FunctionAddressRegister),及EPC0寄存器(Endpoint0
ControlRegister),端点号0为双向端点,作控制使用。
设置中断掩码寄存器,有主掩码寄存器(MAMSK),无应答事件寄存器(NAKMSK),发送事件寄
存器(TXMSK),接收事件寄存器(RXMSK),Alternate事件寄存器(ALTMSK)。
最后允许USB控制器中信号输出,使控制器附加到USB总线上。
USB中断服务例程
中断服务程序处理USB控制器产生的中断,它将数据从USB内部FIFO读出,并建立正确的事
件标志,以通知主循环程序处理。
基本步骤如下:
从主事件寄存器(MAEV)读出产生中断的事件。
根据主事件寄存器某位状态判别事件,接着读取相应的事件寄存器:
接收事件寄存器(RXEV),
或发送事件寄存器(TXEV),或无应答事件寄存器(NAKEV),或Alternate事件寄存器(ALTEV)。
进一步判别事件寄存器的某位状态,根据具体事件,分别做相应的操作。
通道0(端点0)用于控制传输,在驱动程序中调用rxevent0(),txevent0()处理端点0的事件。
通道1中由Txevent1()处理端点1(单向发送)的事件,rxevent1()处理端点2(单向接
收)的事件。
通道2中由Txevent2()处理端点3(单向发送)的事件,rxevent2()处理端点4(单向接
收)的事件。
通道3中由Txevent3()处理端点5的事件,rxevent3()处理端点6的事件。
6.4.5实验操作步骤
1)拷贝光盘CD1\Software\EduKit44b0文件夹到EmbestIDE\Examples\Samsung\目录
下;
2)实验环境准备。
使用USB连接线连接EduKit-III的USB接口和PC主机的USB接口;通过Embest仿真
器连接PC主机并行口和目标板JTAG接口。
3)编译、链接、运行USB例程。
使用EmbestIDE打开USB_Test\USB_Test.pjf工作区,直接编译链接输出可执行文件
USB_Test.elf,下载到EduKit-III上运行。
4)安装USB设备驱动程序。
运行USB例程后,Windows弹出发现新硬件的提示对话框,按照安装向导安装驱动程序
EmbestEduKit-IIIUSBDriver,驱动程序安装文件位于USB_Test\Driver目录。
5)运行USB数据传送演示软件。
运行位于USB_Test目录下demo.exe,出现如下窗口:
6)发送和接收数据。
在传送数据窗口里输入要发送的数据,点发送按钮,在接收数据窗口里,显示目标板USB控
制器返回的数据。
7)在PC机上观察超级终端程序主窗口,可以看到如下界面:
bootsuccess...
USBN9603TestExample
Receivedata...
ReceiveOK.
6.4.6实验参考程序
/*********************************************************************************************
*name:
write_usb
*func:
writes9603controls/conditions/dataregister
*para:
addr---registeraddress//寄存器地址
*dat---data
*********************************************************************************************/
voidwrite_usb(unsignedcharaddr,unsignedchardat)
{
(*(volatileunsignedchar*)0x02000002)=addr;
(*(volatileunsignedchar*)0x02000000)=dat;
}
/*********************************************************************************************
*name:
read_usb
*func:
reads9603controls/conditions/dataregister//控制、状态、数据寄存器
*para:
addr---registeraddress//寄存器地址
*ret:
data
*********************************************************************************************/
unsignedcharread_usb(unsignedcharaddr)
{
(*(volatileunsignedchar*)0x02000002)=addr;
return(*(volatileunsignedchar*)0x02000000);
}
/*********************************************************************************************
*name:
Isr_Init//中断性量表地址映射
*func:
Theseveranceinitialization,installstheUSBseveranceservicefunction//中断的初
//始化,安装usb中断服务函数
*********************************************************************************************/
voidIsr_Init(void)
{
rINTMOD&=~BIT_EINT1;//eint1中断
rINTMSK&=~BIT_GLOBAL;//GLOBALvalid
pISR_EINT1=(int)__Eint1Isr;
rPCONG=rPCONG|(3<<2);
rPUPG=rPUPG&0xFD;
rEXTINT=0x00;
rINTMSK=rINTMSK|BIT_EINT1;
}
/*********************************************************************************************
*name:
Init_9603
*func:
theinitializationUSBN9603,initialization9603interiorregisters,attach9063toarriveonUSBHUB//初始化初始化USB-CAN转换,9603内部寄存器,在USB集线器到附加9063
**********************************************************************************************/
voidInit_9603(void)//9603初始化
{
status_GETDESC=0;
usb_cfg=0;
//giveasoftreset,thensetintstopushpull,activehiorlo
write_usb(MCNTRL,SRST);
while(read_usb(MCNTRL)&SRST);
write_usb(MCNTRL,VGE+INT_H_P);
//initializetheclockgenerator初始化时钟发生器
write_usb(CCONF,CODIS+0x0c);
//setdefaultaddress,enableEP0only设置默认的地址,使EP0只有
write_usb(FAR,AD_EN+0);//FAR=FUNCTIONADDRESSREGISTERfar=函数地址寄存器
write_usb(EPC0,0x00);
//setupinterruptmasks设置中断
write_usb(NAKMSK,NAK_O0);//NAKevnts
write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3);//TXevents
write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3);//RXevents
write_usb(ALTMSK,SD3+RESET_A);//ALTevnts
write_usb(MAMSK,INTR_E+RX_EV+NAK+TX_EV+ALT);
//enablethereceiverandgooperational使接受并工作
FLUSHTX0;//flushTX0anddisable
write_usb(RXC0,RX_EN);//enablethereceiver接收
write_usb(NFSR,OPR_ST);//gooperational工作
write_usb(MCNTRL,VGE+INT_L_P+NAT);//setNODEATTACH
delay(100);
}
/*********************************************************************************************
*name:
Eint0Isr
*func:
TheUSBinterruptserviceisr,processestheUSBseverance,disposestheequipment,transmitsthedataUSB中断服务程序,过程的USB遣散,配置设备,发送数据
*********************************************************************************************/
voidEint0Isr(void)
{
rINTMSK=rINTMSK|BIT_EINT0;
rI_ISPC=BIT_EINT0;
evnt=read_usb(MAEV);//checktheevents检查事件
if(evnt&RX_EV)
{
evnt=read_usb(RXEV);//checktheRXevents检查接收的事件
if(evnt&RXFIFO0)
rxevent_0();//endpoint0
elseif(evnt&RXFIFO1)
rxevent_1();//endpoint2
elseif(evnt&RXFIFO2)
rxevent_2();//endpoint4
elseif(evnt&RXFIFO3)
rxevent_3();//endpoint6
}
elseif(evnt&TX_EV)
{
evnt=read_usb(TXEV);//checktheTXevents检查发送的事件
if(evnt&TXFIFO0)
txevent_0();//endpoint0
elseif(evnt&TXFIFO1)
txevent_1();//endpoint1
elseif(evnt&TXFIFO2)
txevent_2();//endpoint3
elseif(evnt&TXFIFO3)
txevent_3();//endpoint5
}
elseif(evnt&ALT)usb_alt();//alternateevent?
//NAKscancomesofastandfurious(especiallywithOHCIhosts)
//thattheyMUSThavealowerprioritythantheotherevents.If
//theydidnot,theothereventscouldgetstarvedout.
elseif(evnt&NAK)
{
evnt=read_usb(NAKEV);//checktheNAKevents检查该事件
if(evnt&NAK_O0)nak0();
elseif(evnt&NAK_O1)onak1();
elseif(evnt&NAK_O2)onak2();
elseif(evnt&NAK_I3)inak3();
}
rINTMSK=rINTMSK&(~BIT_EINT0);
}
/******************************************************