绪论
当今主流PC上留给用户的可扩展接口有串口,PCI总线,ISA总线,USB总线。串口已是很成熟的接口,广泛用于一般工、民用产品上。但随着PC机的高速发展,对于接口速度的要求越来越强烈,90年代很多公司可将自己的产品定位于ISA 接口,这对比串口在速度上明显有很大提高,可显示连续波形,完成大数据采集。但多媒体的兴起使得ISA接口力不从心,于是主板上的“黑色插条”被“白色插条”替代。基于视频高速的要求,我公司自主开发PCI总线接口板,在接口上面打破僵局。但PCI的非热插板,和开机箱却给用户带来许多不便,基于此,我公司又力推USB(universal serial Bus)总线接口,USB 接口因为它可扩展、高速、方便的特点,成了当今接口界当之无愧的“大哥大”。学会怎样制作USB总线的各种设备,已成为当今技术发展的必然趋势。
第一章USB特点及安装
一、特点
1.自动配置
当用户连接USB外设到一个正在运行的系统时,Windows能自动检测外设,载入合适的软件驱动。外设第一次连接到系统时,Windows可能提示用户插入驱动软件磁盘,但是除了这个以外安装都是自动的。
2.为其它设备空出硬件资源
让尽可能多的外设使用USB,可使IRQ线空闲出来给那些必须使用IRQ 的外设使用。PC必须贡献一系列的端口地址和一根IRQ线给这个接口,但除此之外,单个外设不需要其他的资源了。比对之下,每个非USB外设都要求有端口地址。
3.易于连接
有了USB就不需要打开计算机的机箱去为每个外设增加扩展尖。一个普通的PC机有两个或四个USB端口。你可以通过连接USB集线器到一个已有的端口来增加端口的数量。每个集线器都有其他的端口来连接更多外设或集线器。
4.提供电源
USB接口自带了电源供给和地线,可以从计算机或集线器的电源引进+5V 的电源电位。一个外设如果需要中等电源供应(最多500mA),那它完全可以从总线得到它的电源而不需要自己提供电源。相比之下,大部分使用其它接口的外设将不得不选择要么在设备中自带电源供应,要么使用一个散装的,不方便的外置电源。
5.速度
一个全速USB接口可以以12mb/s的速度进行通信。实际数据传输速率比这个数值要低一些,因为总线除传输数据外,还必须携带状态,控制和错误检测信号,因为所有外设都共用总线。当只有一个设备通信时,最大理论数据速
1
率可达9.6mb/s 或1.2mb/s。
如果这还不够快,USB2.0版规范将允许以480m/s传输数据。这使得USB 对打印机和其它需要快速传递大容量数据的外设更具吸引力。
USB也支持1.5mb/s的低速。低速外设通常很便宜。而且,他们的电缆可以灵活,因电缆不需要屏蔽。
6.灵活
USB四种传输类型和两种速度使得它适用于很多类型的外设。其中有适合大块和小块数据交换传输类型;有和没有时间限制的传输类型。对不能忍受延迟的数据来说,USB可以保证传输的速率或传输所需要的最长时间,这种能力在Windows下更受欢迎,因为在Windows中实时访问外设经常很困难的。
不像其他接口,USB没有为信号分配特殊的功能或做出这个接口是如何被使用的假设,举例来说,PC并行端口的状态和控制线是用来定义与打印机通信用的,这个接口的5条输入线,每一条线分配一个功能,例如指明忙或没纸状态。当开发者开始利用这个端口连接扫描仪或其他需要发送大量数据到PC 的外设时,只有5个输入的局限性形成的障碍。
为了和普通设备类型例如打印机和调制解调器通信。USB支持按规定的设备要求和协议分类,这使得开发者节省了为每个外设的再投资。
二、安装USB设备
如果你地电脑以前没有安装过此产品,第一次插上电缆后,屏幕会弹出一个对话框:“欢迎使用找到新硬件向导。”
2
点“下一步”会弹出“安装硬件设备驱动程序”对话框。
3
此对话框有两个选项:
〈1〉索适于我的设备的驱动程序。
〈2〉示已知设备驱动程序的列表,从中选择特定驱动程序。
你在这里选择〈1〉后点“下一步”,弹出“找到驱动程序文件”对话框,
4
这里有了个选择项:
〈1〉软盘驱动器
〈2〉CD-ROM驱动器
〈3〉指定一个位置
我们一般选择〈3〉指定一个位置,点“下一步”会弹出一个新的对话框,
下面有“厂商文件复制来源”字样,字下面一个显示条,显示驱动来源
5
路径。我们单击旁边的“浏览”后弹出一般选择文件对话框。这里假设你的文件在光盘上,路径如下:
G\USB\驱动\胜西_USB,找到位置后,双击“胜西_USB“(.inf文件),在弹出的对话框上单击“确定”,即可弹出“已完成设备驱动的安装”对话框,
单击“完成”即可大功告成。
如果你不太确定是否安装正确,可按如下方法检查:
①鼠标到“我的电脑”上,单击右键,选择属性条,在弹出的对话框上选“硬件”项,单击“设备管理器”,单击设备中的“通用串行总线控制器”,你会看到有“胜西_USB”字样,表明设备已正确安装,否则单击顶上工具选项的扫描硬件改动项,从头开始安装直至正确。
USB设备安装好以后就可以进行实验了。
6
第二章USB接口芯片PDIUSD12简介PDIUSBD12 带并行总线的USB接口器件
1:特点
* 符合通用串行总线USB 1 .版规范。
* 高性能USB 接口器件集成了SIE FIFO 存储器收发器以及电压调整器。
* 符合大多数器件的分类规格。
* 可与任何外部微控制器/处理实现高速并行接口2M 字节/S。
* 完全自治的直接内存存取DMA操作。
* 集成320 字节多结构FIFO存储器。
* 主端点的双缓冲配置增加了数据吞吐量并轻松实现实时数据传输。
* 在批量模式和同步模式下均可实现1 M 字节/的数据传输速率。
* 具有良好EMI特性的总线供电能力。
* 在挂起时可控制LazyClock输出。
* 可通过软件控制与USB的连接。
* 采用GoodLink技术的连接指示器,在通讯时使LED闪烁。
* 可编程的时钟频率输出。
* 符合ACPI OnNOW 和USB 电源管理的要求。
* 内部上电复位和低电压复位电路。
* 有SO28和TSSOP28封装。
* 工业级操作温度40--+85。
* 高于8kV 的在片静电防护电路减少了额外元件的费用。
* 具有高错误恢复率(>99%)的全扫描设计确保了高品质。
* 双电源操作3.3 ±0.3V 或扩展的5V 电源,围为3.6~5.5V。
7
* 多中断模式实现批量和同步传输。
2:说明
PDIUSBD12 是一款性价比很高的USB 器件,它通常用作微控制器系统中实现与微控制器进行通信的高速通用并行接口,它还支持本地的DMA 传输。
这种实现USB 接口的标准组件使得设计者可以在各种不同类型微控制器中选择出最合适的微控制器,这种灵活性减小了开发的时间风险以及费用,通过使用已有的结构和减少固件上的投资从而用最快捷的方法实现最经济的USB 外设的解决方案。
PDIUSBD12 完全符合USB1.1 版的规范,它还符合大多数器件的分类规格成像类海量存储器件、通信器件打印设备以及人机接口设备,同样地PDIUSBD12 理想地适用于许多外设例如打印机扫、描仪外部的存储设备Zip 驱动器和数码相机等等,它使得当前使用SCSI 的系统可以立即降低成本。
PDIUSBD12 所具有的低挂起功耗,连同LazyClock 输出可以满足使用ACPI OnNOW 和USB 电源管理的要求,低的操作功耗可以应用于使用总线供电的外设。此外它还集成了许多特性包括SoftConnet TM,
GoodLink TM 可编程时钟输出低频晶振和终止寄存器集合,所有这些特性都为系统显著节约了成本同时使USB 功能在外设上的应用变得容易。
3:连接好指示
GoodLink TM 技术可提供良好的USB 连接指示,在枚举中LED 指示根据通信的状况间歇闪烁,当PDIUSBD12 成功地枚举和配置后LED 指示将一直点亮,随后与PDIUSBD12 之间成功的传输带应答将关闭LED, 处于挂起状态时LED将会关闭。
该特性为USB 器件集线器和USB 通信状态提供了用户友好的指示,作为一个诊断工具它对隔离故障的设备是很有用的,该特性降低了现场支持和热线的成本。存储器管理单元MMU和集成RAM在以12M/s 的速率传输并与微控制器并口相连时MMU 和集成RAM 作为USB 之间速度差异的缓冲区,这就允许微控制器以
8
它自己的速率对USB信息包进行读写。
在该例中ALE 接为低电平表示一个独立的地址和数据总线配置,PDIUSBD12 的A0 脚与80C51的任意一个I/O 口相连该端口控制PDIUSBD12 的命令和数据状态,80C51 的多位地址和数据总线可直接与PDIUSBD12 的数据总线相连,80C51的频率输入可由PDIUSBD12的CLKOUT提供。
4:端点说明
PDIUSBD12 的端点适用于不同类型的设备, 例如图像打印机海量存储器和通信设备端点可通过Set Mode 命令配置为4 种不同的模式分别为:
模式0 Non-ISO 模式非同步传输
模式1 ISO-OUT 模式同步输出传输
模式2 ISO-IN 模式同步输入传输
模式3 ISO-IO 模式同步输入输出传输
模式0(非同步模式)
模式1 (步输出模式)
9
模式2(同步输入模式)
模式3(同步输入/输出模式)
主端点
主端点<端点2> 在有些方面是比较特别的,它是进行吞吐大数据的主要端点。同样地,它执行主机的特性以减轻传输大数据的任务。
1.双缓冲。允许USB 与本地CPU 之间的并行读写操作,这样就增加了数据的吞吐量。缓冲区切换是自动处理的,这导致了透明的缓冲区操作。
2.支持DMA (直接存储器访问)操作。可以和对其它端点的正常I/O 操作交叉进行。
3.3. DMA 操作中的自动指针处理。在跨过缓冲区边界时不需要本地CPU 的干预。
4. 可配置为同步传输或非同步(批量和中断)传输。
5:管脚配置
10
管脚描述
注: O2 : 2mA 驱动输出 OD4: 4mA 驱动开漏输出 OD8: 8mA 驱动开漏输出 IO2: 4mA 输出
6:命令寄存器
12
其他说明,请参见PDIUSBD12.pdf文件。
13
第三章固件(单片机程序)
就是单片机程序,它起到外设和USB芯片的数据交换,可用汇编也可用C语言编写,这是因为USB列举程序很长,于是我们选择用C语言。
我在介绍C51固件前先假设你对51单片机是熟悉的,至少可以用汇骗实现外设读写,对C语言是了解的,知道编一些小程序来完成一般的小任务,还有你知道仿真器是怎么用的。好了,如果你听了后心里有数了,那我们就可以去看一看这个固件了。
首先,你有一台仿真器,支持C编译器(C compiler),支持总线模式。而且装上了仿真软件,设置好编译器。当然是C编译器,在说固件前我觉得有必要说一下C编译器的安装,众所周知,C编译器有2K限制,如果你简单的将Compiler拷贝过来是不行的,你得先装上它。
第一步:虚拟一个A驱动器,也就是在Keil51 下面的几个文件中,选择CRACK文件夹作路径(在命令行下)运行“subst a:.”。这个命令有三要素,subst,a:,. ,别少了这个点,千万记住。
第二步:运行Keil51文件夹下面的setup目录下的setup.exe开始安装。
第三步:弹出一个对话框要求序列号。这个C的序列号是
“K1PRP-MWVI9-111QE”,还有FIRST NAME 和last name都是P1PTE4,会可,个人各可随便。好了这样就可以了。当然你得确认你的人仿真软件上的编译器就是你装的这个编译器。
我们先介绍一下固件结构,固件结构简化如下:
main()
{
先初始化;
清各个中断标志:
while(1)
{
if(标志1)
子程序1;
14
if(标志2)
子程序2;
if(标志3)
子程序3;
......
}
}
15
其流程图如下:
b.图
16
对应原程序:
main(){
unsigned char i;
//D12_WriteEndpoint(3, 1,&i);
init_port();
init_serial();
init_timer0();
EA = 0;
MCU_LED0=0;
MCU_LED1=0;
MCU_LED0=1;
MCU_LED1=1;
IE0=0;
IT0=0;
EX0=1;
MCU_D12CS = 0x1;
bNoRAM = TRUE;
MCU_D12CS = 0x0;
i=D12_ReadInterruptRegister();
i=0;
i=D12_ReadLastTransactionStatus(0);
i=D12_ReadLastTransactionStatus(1);
i=D12_ReadLastTransactionStatus(2);
i=D12_ReadLastTransactionStatus(3);
i=D12_ReadLastTransactionStatus(4);
i=D12_ReadLastTransactionStatus(5);
17
ENABLE;
reconnect_USB();
ENABLE;
while( TRUE ){
if (bEPPflags.bits.timer){
DISABLE;
bEPPflags.bits.timer = 0;
ENABLE;
if(bEPPflags.bits.configuration)
check_key_LED();
}
if (bEPPflags.bits.bus_reset) {
DISABLE;
bEPPflags.bits.bus_reset = 0;
ENABLE;
D12SUSPD=0;
} // if bus reset
if (bEPPflags.bits.suspend) {
DISABLE;
bEPPflags.bits.suspend= 0;
ENABLE;
if(D12SUSPD == 1) {
D12SUSPD = 0;
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
18
P3 = 0xFF;
D12_SetDMA(0xC3);
D12SUSPD = 1;
PCON |= 0x02;
while (1);
}
} // if suspend change
if (bEPPflags.bits.setup_packet){
DISABLE;
bEPPflags.bits.setup_packet = 0;
ENABLE;
control_handler();
//D12SUSPD = 1;
D12SUSPD=0;
} // if setup_packet
if(bEPPflags.bits.setup_dma != 0) {
DISABLE;
bEPPflags.bits.setup_dma --;
ENABLE;
setup_dma();
} // if setup_dma
} // Main Loop
那么标志在那里被改变呢?我们先看一下下面的中断简化程序:interrupt()
{
读中断寄存器;
19