资源目录
压缩包内文档预览:(预览前20页/共66页)
编号:53205683
类型:共享资源
大小:447.17KB
格式:RAR
上传时间:2020-02-28
上传人:qq77****057
认证信息
个人认证
李**(实名认证)
江苏
IP属地:江苏
5.99
积分
- 关 键 词:
-
MP3
单片机
系统
中的
应用
- 资源描述:
-
MP3在单片机系统中的应用,MP3,单片机,系统,中的,应用
- 内容简介:
-
65MP3在单片机中的应用MP3在单片机系统中的应用摘要:本文以MPEG Audio Layer作为语音信息的压缩格式,并借助电梯语音播报系统的设计,实现MP3在单片机中的应用。全文分为四个部分对电梯语音播报系统的软件、硬件两个方面作详细的论述。第一部分将概述整个系统的构成及功能,并介绍各组成部分的方案选择;第二部分将对硬件的设计进行介绍,包括主要芯片的简介和单元电路的分析;第三部分将介绍软件设计需要涉及到的理论知识,为下一步软件分析作铺垫;第四部分将对软件的设计进行分析,主要包括主控程序、U盘程序和语音播报程序等。关键字: 单片机;文件系统;MP3;USBApplication of MP3 in the single-chip systemAbstract: In this text, the MPEG Audio Layer was used as compression format of speech information, and the text asked for the design of elevator speech reported system to carry out the application of MP3 in the single-chip. The full text was divided into four parts to detailed treatise two aspects of elevator speech reported system: software and hardware. The first part will say the whole composing of system and functions, and introduce project of each part that constituted the system; The second part will introduce the design of the hardware, including introduction of the main chips and the analysis of the electric circuit unit; The third part will introduce the theory knowledge that the software design need to involve, to make the cushion for the next movesoftware analyzing; The fourth part will analyse the design of the software, mainly including master program, the U disk program and speech reported program etc.Key Words: Single-Chip; File System ; MP3;USB目录绪论11 电梯语音播报系统的构成21.1 电梯语音播报系统构成及功能21.2 第三层音频编码标准MP321.3 系统的数据传输21.4 系统的人机接口32电路原理设计与实现42.1 电路系统概述42.2 芯片摘要52.2.1 AT89C51SND1C单片机52.2.2 NAND FLASH K9F560852.2.3 CS4330 音频DAC芯片72.3 电路原理图72.3.1 FLASH K9F5608电路72.3.2 语音播报电路82.3.3 USB接口电路92.3.4 RS232串行接口电路92.3.5 电源电路103程序设计基础113.1 U盘程序设计基础113.1.1 概述113.1.2 描述符123.1.3 设备列举153.1.4 Bulk-Only传输协议173.1.5 SCSI-2 命令集183.1.6 USB设备标准请求193.2 U盘文件系统处理程序设计基础203.2.1 FAT文件系统介绍203.3 MP3程序设计基础233.3.1 帧头格式分析233.3.2 可变位率的MP3253.3.3 ID3标准254固件程序的设计与实现264.1 软件概述264.2 主控程序设计264.3 USB程序设计274.4 语音播报程序设计314.5 Uart通信程序设计334.6 控制界面设计345 结论35致谢36参考文献37附录绪论电梯的出现给人们带来了极大的方便,身处高楼大厦的人们不必再为上下楼梯而烦恼。随着中国经济的腾飞,越来越多的高楼大厦拔地而起,电梯势必会得到更为广泛的应用。出于对人性化的考虑,现在大多数高楼的电梯都已具有语音播报功能。目前,实现语音播报的方案大致有两种:一种是直接由电梯管理员进行播报;另一种是将需要播报的语音信息录制到专用语音芯片,然后再利用语音芯片进行播报。前一种方案可以做到想播报什么就播报什么,实时性好,但需要耗费人力成本。后一种方案虽在成本上大大的减少,但是它有一个很大的缺陷。如果由于损坏或者其他原因而更换语音芯片,那就必须重新录制语音信息,这对使用者造成了极大的不便。那么如何才能实现既能节省成本,又能保证使用方便呢?于是第三种方案应运而生,即先将语音信息做成音频文件存放于电脑中,再通过USB接口将音频文件复制到由单片机、海量FLASH存储器等器件构成的电梯语音播报系统。这一方案所需要的成本极少,而且除了语音播报功能外,它甚至可以做为U盘使用。就算更换芯片,也只需利用USB接口重新将音频文件复制一遍即可,操作极为方便。目前,音频文件的压缩格式有很多种。其中,MP3格式是目前最为流行的一种音频压缩格式,具有压缩程度高、音质好等特点,它的全称是MPEG Audio Layer。MP3是采用ISO/MPEG Layer编码器对音频数据进行压缩,使用此技术不但可以获得较大的音乐数据压缩比,还可得到较高的音乐回放质量。例如在目前最好的CD音质中,声音最高频率是20KHz,采样频率定位44.1KHz,16位量化。要获得CD音质的立体声,每秒钟的资料量将超过1.4Mbit。而采用MP3压缩,数据量可以缩小到1/12,音质却没有损失。如果再进一步压缩数据量到1/24或更多,依然可以维持相当好的音质。通过以上论述可知,MP3的优势是显而易见的。它作为高质量音乐压缩标准,已给数字音频工业带来了强劲的冲击,并越来越多地进入人们的生活。基于此,本文将以电梯语音播报系统为依托,实现MP3在单片机中的应用。1 电梯语音播报系统的构成1.1 电梯语音播报系统构成及功能电梯语音播报系统的结构框图如图1.1所示,由六部分构成。控制器采用内嵌MP3解码器的单片机,主要的功用是处理USB通信和播放MP3文件;海量存储器采用大容量的FLASH存储芯片,用于存储MP3文件;人机部分采用PC机通过RS-232串口对单片机进行输入输出操作,用于实时显示单片机工作状态及相关信息,并向单片机发出控制指令; USB接口用于系统在U盘状态下与PC机交换MP3文件;MPEG1 Layer3播报单元由音频数模转图1.1 电梯语音播报系统结构框图换器、功率放大器和音响组成,用于将单片机输出的数字信号转换为声音信号并播放;信号传输部分是用于实际应用中接收来自上位机或者电梯的信号。该系统有两个功能:语音播报功能和U盘功能。语音播报主要有楼层到达、上下行、开关门和安抚等信息,安抚是在电梯发生故障时使用。1.2 第三层音频编码标准MP3本次设计中采用MP3格式的音频文件。因为MP3格式是目前最为流行的一种音频压缩格式,具有压缩程度高、音质好等特点,它所遵循的压缩标准是MPEG标准。 MPEG标准是由ISO(International Organization for Standardization)和IEC(International Electrotechnical Commission)联合技术委员会ISO/IEC JTCI制定的。MPEG音频标准提供3个独立的压缩层次,使用户可以在复杂性和压缩质量之间权衡选择。其中,层3(layer)最为复杂,但音频质量最佳,使用的比特率为64kbps,尤其适用于ISDN上的音频传输。MP3是ISO/MPEG Layer(第三层音频编码标准)的缩写。它是一种超级声音文件的压缩方法,其数字元压缩速率为每信道128kbits/s,MP3的压缩比高达12:1。1.3 系统的数据传输电梯语音系统与PC机进行音频文件的传输的方法有两种:一是利用USB 接口;二是利用RS-232接口,两种方法各有千秋。利用USB接口作为PC机与本系统之间的接口,可以使系统很方便的与PC机传输音频文件,并且不需要考虑文件在系统的海量FLASH存储器中如何存放,但是这对后续查找音频文件会带来一定麻烦。利用RS-232接口作为PC机与本系统之间的接口,对系统和PC机之间传输文件会带来很大的麻烦。因为不但需要考虑如何让PC机中音频文件传输至单片机,而且还需要考虑文件在海量FLASH存储器中如何存放。但也正是由于音频文件是按照设计者的意愿在存储器中存放的,因此在后续查找文件会比前一种方法来得方便。综上所述,虽然第一种方法在后续查找文件时较为麻烦,但却省去了自己定义文件系统的麻烦。并且与RS-232接口相比,USB接口具有容易使用、传输速度快、低功耗和可靠性高等优势。因此,在本次设计中采用USB接口作为本系统与PC机之间传输文件的接口。1.4 系统的人机接口人机部分拟有两套方案:一是使用键盘和LCD显示器;二是使用PC机及RS-232串口。两者相较而言,后者更简单、更方便。原因有二,首先,可以通过工具软件在PC机上制作出非常好的控制及显示界面,更具人性化;其次,单片机与PC机双向数据传输的程序短而简单,实现起来方便。采用第二种方案可以显示任何信息以及执行各种操作,而且不需要添加任何硬件成本,这对于第一种方案来说是望尘莫及的。因此,在本次设计中选择RS-232作为系统的人机接口。2电路原理设计与实现2.1 电路系统概述语音播报和U盘功能的实现主要依赖于MP3硬件解码器、音频接口和DAC、USB通信电路、海量FLASH存储器以及单片机。在本次设计中,选用AT89C51SND1C单片机来构成MP3和U盘,这一方案具有很好的可行性。因为这款单片机内嵌了MP3硬件解码器和数字音频输出接口、USB接口,从而使得方案变的简单易行。AT89C51SND1C是基于8位C51内核的单片机,这使得程序设计也很简单。这款单片机内部提供2K大小的SRAM等资源,为实现语音播报和U盘功能提供了保障。从图2.1中可以看出,整个系统由单片机AT89C51SND1C、32M FLASH存储器K9F5608、 RS-232芯片MAX3232、音频DA芯片CS4330和功放芯片TDA2822、电源5V稳压芯片LM2576S和3.3V稳压芯片AS1117构成。由于U盘程序或者语音播放程序无法实现单步或者设置断点等一般方法进行调试,因而在本次设计中采用RS-232串口进行调试。图2.1 电梯语音系统硬件结构图FLASH芯片是构成U盘的重要组成部分,单片机通过USB接口来实现与PC机的数据通信,并按USB海量存储的相关协议响应PC机的命令,将数据写入FLASH或从中读取数据。同时FLASH芯片内部逻辑结构将按磁盘文件系统来组织。FLASH芯片通过数据总线和若干I/O端口和单片机连接。在语音播报功能中,单片机从FLASH芯片中读取MP3文件,再送到MP3硬件解码器的缓冲区,解码器的输出经过音频接口输出到外部DA芯片,转换为模拟音频信号后经过功率放大器即可推动音响。系统的电源电路支持从USB的5V电压中取电,也支持外部输入电源。前者用AS1117芯片稳压为3.3V供给大部分电路;后者则使外部电源经稳压芯片LM2576S稳压为5V后,再用AS1117芯片稳压为3.3V为电路供电。2.2 芯片摘要2.2.1 AT89C51SND1C单片机本次设计中,单片机采用的是ATMLE公司生产的AT89C51SND1C,它是一款嵌有MP3硬件解码器的芯片,具有C51内核。通过嵌入的4K字节闪存引导区可以实现在线编程。AT89C51SND1C在原有的89C51的基础上增加了MP3解码模块、IIC/PCM音频输出模块、串并行接口模块(USB、RS-232、General I/O)等模块。适用于MP3播放器、带MP3手机等嵌入式系统。本次设计中,主要用到AT89C51SND1C芯片的4个功能块。它们构成的内部框图如图2.2所示。图2.2 AT89C51SND1C内部架构框图(1)MP3音频解码器:AT89C51SNDlC可实时解码MP3数据为PCM音频数据,同时也支持MP3其他频率。解码器也支持其它特性如声音控制、低音放大、辅助数据提取等(2)音频输出接口:允许音频解码位流以不同的格式输出,并可兼容PCM和IIC格式。(3)通用串行总线(USB)接口:支持USB存储类的MP3音频解码文件下载。(4)串行接口:支持单片机通过RS-232串口进行通信。2.2.2 NAND FLASH K9F5608K9F5608是韩国三星公司生产的具有32M容量的NAND FLASH芯片。这种FLASH芯片被大量的应用在各种需要存储的设备上,比如U盘,MP3播放器等。因为AT89C51SND1C单片机没有NAND FLASH的控制器,所以只能用I/O端口来完成对FLASH芯片的读写时序。这款芯片只有8位数据/地址复用接口和CLE、ALE、WE、RE 等控制信号,硬件接口比较简单,但读写时序相对复杂,需要依次送入命令,地址和数据。内部存储矩阵是按块页逻辑结构组织的。图2.3 K9F5608块页逻辑结构K9F5608存储矩阵的块页逻辑结构如图2.3所示。K9F5608共有2K个Block(块),每个Block包括32个Page(页),每个页则包含528 Bytes,其中有512 Bytes基本空间和16Bytes扩展空间。这种逻辑结构很容易和磁盘文件系统联系起来,因为文件系统中的扇区也是512字节。K9F5608需要24位地址来定位需要被操作的块号和页号,也就是3个周期写入地址信息,见表2.1。表2.1 K9F5608的地址周期I/O0I/O1I/O2I/O3I/O4I/O5I/O6I/O71stcycleA0A1A2A3A4A5A6A72ndcycleA8A9A10A11A12A13A14A153rdcycleA16A17A18A19A20A21A22A23FLASH最小读写操作单位是页,而擦除是以块为单位进行的。在进行某种操作前必须先打入相应命令,K9F5608的命令有的是一字节命令,如:Read1、read2等;有的是两字节命令,如:Copy-Back Program、Block Erase等。本次设计中使用的命令见表2.2。表2.2 K9F5608的命令集Function1st cycle2nd cycleRead100/01h-ResetFFh-Page Program80h10hCopy-Back Program00h8Ah2.2.3 CS4330 音频DAC芯片图2.4 CS4330 的内部框图音频DAC芯片在电梯语音系统中承担音频信号的数字/模拟转换功能,其性能直接影响最终的音乐效果和音质。本系统采用CS4330芯片,这款芯片没有配置引脚,因此无需软件配置。CS4330的内部框图如图2.4所示。SDATA是位流数据输入、SCLK是位流时钟信号、LRCK是声道选择时钟,其频率即采样率、MCLK则是DAC电路所需的主时钟。2.3 电路原理图2.3.1 FLASH K9F5608电路图2.5 NAND Flash芯片电路图如图2.5所示,K9F5608的I/O7:0引脚是复用的,它可以作为地址、数据输入/输出和命令输入的端口,在具体操作时受命令锁存使能引脚CLE和地址锁存使能引脚ALE控制。WE、RE是读和写的使能信号,它将决定芯片当前的操作是读还是写。CE是片选信号,决定当前芯片是否处于工作状态。R/B则是Ready/Busy(准备/忙)信号,是单向输出信号。当为Ready时,表示芯片目前处于空闲状态,可以接受单片机对K9F5608的操作;当为Busy时,表示芯片正在进行编程、擦除或读的操作。单片机将根据这个信号来判断是否可以对K9F5608进行下一步操作。R/B信号线在默认时应为逻辑高电平,但由于芯片内部没有将R/B信号线置为高电平,因此在设计时用以上拉电阻将R/B信号线接至+3V电源。2.3.2 语音播报电路语音播报电路由两部分组成:第一部分为音频数模转换电路,第二部分为功率放大电路。音频数模转换电路如图2.6所示。图2.6 CS4330芯片电路图音频数模转换芯片选用的是立体声DA转换器CS4330。该芯片为双路输出:左声道输出和右声道输出。从图中可以得知,两个声道的外围电路一致。因此,现以左声道输出线路为例进行分析。简化后的外围电路如图2.7所示。图2.7 简化电路图其中,电解电容C22为耦合电容,起到“隔直通交”的作用;电容C27为滤波电容;电阻R24与电位器HR1组成分压电路,通过调节电位器HR1可以改变功率放大器的输入电压,起到调节音量的作用,也可将其称之为“音量硬调节”。CS4330有四根信号线:主时钟信号线MCLK、声道选择信号线LRCK、移位时钟信号线SCLK和位数据信号线SDATA。这四根线分别接到单片机的SCLK、DSEL、DCLK和DOUT上。SCLK的输出信号将作为CS4330的系统时钟;DSEL的输出信号用于选择左右声道;DCLK信号用于数据的移位传输;DOUT用于音频数字信号的输出。功率放大电路如图2.8所示。功率放大器选用的是双路低功率放大器TDA2822M。该芯片集成了两个放大器。现以一个放大器及其外围电路进行分析。图2.8 TDA2822M芯片电路图简化电路如图2.9所示。其中,电解电容C25、C29为耦合电容,起到“隔直通交”的作用。电容C18、C19为滤波电容。图2.9 简化电路图2.3.3 USB接口电路图2.9 USB接口电路图USB接口D+和D-这两个引脚就是单片机内部USB部件的差分信号输入输出引脚,通过图2.9所示的电路接到USB Device插口上。USB_INS定义的是I/O端口P3.2,用来检测USB电缆上的5V电压,判断是否插入USB电缆,以决定系统是执行U盘功能还是执行语音播报功能。2.3.4 RS232串行接口电路RS232串行接口电路中电平转换芯片采用MAX3232芯片。如图2.10所示,MAX323芯片的TXD、RXD引脚用于接至单片机的TXD、RXD因脚上,MAX3232芯片的RS232TXD、RS232RXD引脚用于接到一个DB9 标准串口插座上,可以连接PC机进行串口调试。图2.10 RS232串行接口电路2.3.5 电源电路在本次设计中,采用芯片LM2576S和AS1117产生两种稳压电源,分别为:+5V和+3V。+5V用于向功率放大器TDA2822M提供工作电压,+3V用于向单片机、海量FLASH存储器和音频数模转换器提供工作电压。电源电路如图2.11所示。图2.11 电源电路图3程序设计基础3.1 U盘程序设计基础关于USB 海量存储(USB Mass Storage)的知识相当复杂这里仅将涉及到的USB通信原理、设备描述符、Bulk-Only协议、SCSI命令集等知识作简要的说明。3.1.1 概述Microsoft Windows提供了对Mass Storage协议的支持,因此USB移动设备只需要遵循Mass Storage协议来组织数据和处理命令,即可实现与PC机交换数据。而FLASH的存储单元组织形式采用FAT16文件系统。这样就可以直接在Windows的浏览器中通过可移动磁盘来交换数据了,Windows负责对FAT16文件系统的管理,USB设备不需要干预FAT16文件系统操作的具体细节。每个设备可以有一个或多个配置(Configuration),配置用于定义设备的功能。如果某个设备有几种不同的功能,则每个功能都需要一个配置。配置是接口(interface)的集合。接口指定设备中的哪些硬件与USB交换数据。每一个与USB交换数据的硬件就叫做一个端点(Endpoint)。因此,接口是端点的集合。USB的设备类别定义(USB Device ClassDefinitions)定义特定类或子类中的设备需要提供的缺省配置、接口和端点。端点是USB中一个独特的概念,它是一个可以与USB Host交换数据的硬件单元。USB Host与USB设备之间都是通过端点来传输数据的,端点是桥梁和纽带,不同的端点其传输数据的能力不同,适于不同的应用场合。来自主机的通信流将止于设备上的端点,而从设备上向主机提供的数据也起于端点。管道是设备上的一个端点和主机上的软件的联合体。它表示经过一个存储缓冲区和一个设备上的端点,可以在主机上的软件之间传送数据的能力。与0号端点对应的0号管道总是可用的,主机通过这个管道来向设备查询信息,进行初始化,并配置其他端点。其他端点一经配置,与之对应的管道便建立起来了。系统软件使用缺省管道(与端点0相对应)来管理USB设备。描述符(descriptor)描述设备、配置、接口或端点的一般信息。USB(Host)唯一通过描述符了解设备的有关信息,根据这些信息建立起通信。在这些描述符中,规定了设备所使用的协议、端点情况等。因此,正确地提供描述符,是USB设备正常工作的先决条件。每个USB 设备都必须有一个设备描述符。3.1.2 描述符USB的描述符定义了关于设备的各种信息,如图3.1所示: 图3.1 USB描述符的类型与关系描述符是一种预定义的数据结构,每一个描述符的第1个字节都是该描述符的字节数长度,第2个字节则为该描述符自身类型的标示。其中,设备描述符(device descriptor)、配置描述符(configuration descriptor)、接口描述符(interface descriptor)和端点描述符(endpoint descriptor)为每个USB设备所必有的,字符串描述符(string descriptor)、各设备类不同的类描述符(class descriptor)及报告描述符(report descriptor)则可以根据不同的设备进行添加或删减。以下对本次设计所用到的各描述符进行介绍。(1) 设备描述符设备描述符是设备接入主机之后主机向设备要求的第一个描述符。设备描述符中包含了设备的基本信息,包括数据传输时设备遵守USB规范的版本、数据封包大小,以及设备包括的若干特定字符串描述符和配置描述符。/* 设备描述符 */unsigned char Device_Descriptor18 =0x12,/length描述符长度0x01,/DEVICE descriptor类型,01=Device0x10, 0x01,/spec rev level(BCD) 1.0USB规范1.100x0,/device class设备类码0x0,/device subclass设备子类码0x0,/device protocol设备协议0x20,/max packet size最大封包大小0x05, 0x82,/Nationals vendor ID制造商ID0x00, 0x11,/Nationals product ID 产品ID0x00, 0x00,/Nationals revision ID 发行序列号0,/index of manuf.string 制造商的字符串描述符索引0,/index of prod.string 产品的字符串描述符索引0,/index of ser.string 设备序号的字符串描述符索引0x01/number of configs.配置描述符的个数;(2) 配置描述符配置描述符向主机报告设备的配置信息,包括设备供电方式、最大电源电流等属性,并指定了一个配置包含的接口数。对每个设备而言,可能会有一个或多个配置类型,其配置的数目视由上面的设备描述符的最后一个字段(即number of configs)所设定的,本次设计中该值为1。当主机向设备要求配置描述符时,主机会连续的读取这些描述符(包括每个配置的配置描述符、接口描述符、端点描述符和类描述符,直到读完所有的配置为止。)/* 配置描述符*/code uchar Configuration_Descriptor9 =9,/Length, 描述符长度2,/Descriptor Type, 描述符类型,2-配置描述符0x20,0x00, /Total Length, 描述符总长度 1,/Interface Number 本配置支持的接口数1,/Configuration Value 选择本配置的参数值0,/Configuration Index 本配置串描述的索引0x80,/Configuration Feature配置的属性,总线供电0xfa,/Maximum Power最大功耗,500mA;(3) 接口描述符接口描述符用来描述设备设备的接口,指明接口的类型和遵循的传输协议等属性。对一个设备的配置来说,可能有一种或多种接口类型,其接口的数目是由配置描述符的Interface Number字段指定的,本次设计中该值为1。/*接口描述符*/unsigned char Interface_Descriptor9= 9,/Descriptor Length, 描述符长度4,/Descriptor Type, 描述符类型,04-接口描述符0,/Interface Number, 接口数目0,/Alternative Setting,交互设定值2,/EndPoint Number, 端点数目8,/Interface Class, 接口类码,8-Mass Storage6,/Interface Subclass, 接口次类码,6-SCSI0x50,/bulk 0nly Transport,接口规范,Bulk-0nly0,/Interface Index, 本配置串描述的索引;(4) 端点描述符端点描述符用来描述端点的属性以及各个端点的位置,包含此端点的传输方向、传输类型以及传输率等信息。每一个接口可能对应一个或多个端点,其端点数目由接口描述符的Endpoint Number字段设定,本次设计中该值为2。/* Bulk-in端点描述符*/unsigned char Endpoint_Descriptor14=/= Bulk-In端点描述符= 0x07,/Length, 描述符长度0x05,/Descriptor Type, 描述符类型,05-EndPoint0x81,/Endpoint Address(IN), D7=1:输入,D3-0=Ep号(Ep1,In)0x02,/Attributes(BULK), 传输类型属性(块)0x40, 0x00,/Max Packet Size(64), 最大封包大小0x0,/Interval, 轮询间隔/= Bulk-out端点描述符= 0x07,/Length, 描述符长度0x05,/Descriptor Type, 描述符类型,05-EndPoint0x02,/Endpoint Address(OUT),D7=0:输出,D3-0=Ep号(Ep2,Out)0x02,/Attributes(BULK), 传输类型属性(块)0x40, 0x00,/Max Packet Size(64), 最大封包大小0x0/ Interval, 轮询间隔;3.1.3 设备列举当设备接入主机后,主机将控制USB总线,发出一系列标准设备要求,读取设备的各项固有信息,设定设备的地址,最终使设备正常工作。这一过程成为设备的列举,如图3.2所示。图3.2 设备列举流程(1) 输入设备描述符的要求设备上电后的默认地址为0。在USB总线重置之后,主机会对地址为0的设备送出要求设备描述符(Get_Descriptor)的标准请求,标准设备要求作为由主机发起的一次数据交易,共有3个阶段组成:设定阶段、数据阶段和握手阶段。设定阶段为送给默认地址0设备的默认端点0的Setup令牌包,数据阶段主机送出Setup包的内容,这是送出的一般是80 06 00 01 00 00 12 00(均为十六进制表示),表示主机要求设备向主机提供设备描述符,然后设备响应握手信号表示接受正确。设备对这个标准设备要求译码,得知主机要求它送出自己的设备描述符,于是设备在发送缓冲区中写入设备描述符的第一个包长,当设备受到主机要求输入数据的下一个IN封包后就将这部分设备描述符送给主机。(2) 设定设备地址的要求第一次数据交易的作用并不在于主机对设备具体功能的设置,而更多的在于检测设备与主机的正常通信。因为主机收到设备送来的设备描述符的第一个封包后,并不急于接受设备描述符的其它封包并处理设备配置等任务,而是把这个包放在一边,转而为设备设置新地址。主机向默认地址0送出设置地址(Set_Address)的标准设备要求,例如:00 05 02 00 00 00 00 00,wValue域中的值为新地址值(例中的02),以后主机对此设备的所有操作都通过这个地址进行。(3) 再次输入设备描述符的要求在成功为设备设定新地址之后,主机通过为设备设定的新地址重新发出要求设备描述符的标准设备要求(Set_Address)。这一次的要求与上次的不同之处是wLength域为上次的得到的设备描述符的实际长度,而不再是默认的ff。这一次的要求设备描述符,主机会一直把全部设备描述符读完,进行必要的处理。如果这一次主机能够收到正确的设备描述符,就表明设备已经可以用新的地址正常的与主机通信了。主机的所有这些操作都是在操作系统的控制下完成的,由此可见操作系统支持USB,也是USB设备正常使用的一个必要条件。(4) 输入配置描述符的要求下一步,主机根据设备描述符中指定的配置数目,要求输入设备的配置描述符,设备对每个获得配置描述符的标准设备要求(Get_Configuration)作出响应。主机在这个标准设备要求的过程中并不仅仅只获得配置描述符一项描述符,而是将每个配置描述符所附带的接口描述符和端点描述符一并获得,这一过程只通过获得配置这一个标准设备要求,设备对这个标准设备要求的响应要连续的送出这几个描述符,直到主机不再送IN令牌包要求设备继续为止,换言之,主机默认设备的存储空间中这几个描述符是连续存放的,在固件程序的设计中也确实应该如此安排程序存储空间。(5) 设定配置的要求当主机成功接受所有配置描述符后,主机会在前面接受到的设备要求中所定义的若干可用配置中,选择其中一个配置,送出设定配置的标准设备要求,例如:00 09 01 00 00 00 00 00。这时,设备处于被配置的状态,而且对被选择的配置所定义的端点也同样被触发。相对地,主机也可以通过选择配置0来使设备进入未配置的状态,其中除控制端点之外的所有端点也都回被终止。(6) 主机对设备的列举设备列举正确完成后,主机就会报告给用户找到新的USB设备,并为设备找到一个正确的驱动程序,在Windows操作系统中的设备管理器窗口就可以看到这个设备的具体信息,包括生产商、版本、所有驱动程序等。而在设备正常工作当中,主机仍旧可以随时中断设备的正常工作,使设备复位,再次向设备送出各项标准设备要求。而设备必须及时响应每一个标准请求,否则主机会等待超时从而认为设备不可识别,设备也就无法工作了。3.1.4 Bulk-Only传输协议设备插入到USB后,USB即对设备进行搜索,并要求设备提供相应的描述符。在USB Host得到上述描述符后,即完成了设备的配置,识别出为BulkOnly的Mass Storage设备,然后即进入BulkOnly传输方式。在此方式下,USB与设备间的所有数据均通过Bulk-In和Bulk-Out来进行传输,不再通过控制端点传输任何数据。在这种传输方式下,有三种类型的数据在USB和设备之间传送,CBW、CSW 和普通数据。CBW(Command Block Wrapper,即命令块包)是从USB Host发送到设备的命令,命令格式遵从接口描述符中的bInterfaceSubClass所指定的命令块,这里为SCSI-2传输命令集。USB设备需要将SCSI-2命令从CBW中提取出来,执行相应的命令,完成以后向Host发出反映当前命令执行状态的CSW(Command Status Wrapper,即命令状态包),Host根据CSW来决定是否继续发送下一个CBW或是数据。Host要求USB设备执行的命令可能为发送数据,则此时需要将特定数据传送出去,完毕后发出CSW,以使Host进行下一步的操作。(1) CBW命令块包CBW命令块包的格式见表3.1。表3.1 CBW命令块包格式7bit6 bit5 bit4 bit3 bit2 bit1 bit0 bit0-3BytedCBWSignature4-7BytedCBWTag8-11BytedCBWDataTransferLength12BytebmCBWFlags13ByteReserved(0)bCBWLUN14ByteReserved(0)bCBWLength15-30ByteCBWCB其中dCBWSignature的值为43425355h(LSB),表示当前发送的是一个CBW;dCBWTag的内容需要原样作为dCSWTag再发送给Host;dCBWDataTransferLength为本次CBW需要传输的数据,bmCBWFlags反映数据传输的方向,0表示来自Host,1表示发至Host;bCBWLUN一般为零,但当设备有多个逻辑单元时,用此位指定本次命令是发给谁的;bCBWCBLength为本次命令字的长度;CBWCB即为真正的传输命令集的命令。得到一个CBW后,解析出CBWCB中所代表的命令,然后按照SCSI-2命令集中的定义来执行相应的操作,或是需要接收下一个BulkOut发来的数据,或是需要向Host传送数据,完成以后需要向USB Host发送CSW,反映命令执行的状态。USB也是通过此来了解设备的工作情况的。(2) CSW命令状态包CSW命令块包的格式见表3.2。表3.2 CBW命令块包格式765432100-3dCSWSignature4-7dCSWTag8-11dCSWDataResidue12dCSWStatus其中,dCSWSignature的内容为53425355h,dCSWTag 即为dCBWTag的内容,dCSWDataResidue还需要传送的数据,此数据根据dCBWDataTransferLength本次已经传送的数据得到。Host端根据此值决定下一次CBW的内容,如果没有完成则继续;如果命令正确执行,bCSWStatus返回0即可。按这个规则组装好CSW后,通过Bulk-In端点将其发出即可。3.1.5 SCSI-2 命令集Bulk-Only的CBW中的CBWCB中的内容即为如下格式的命令块描述符(Command BlockDescriptor)。SCSI-2有三种字长的命令,6位、10位和12位。(1)SCSI-2命令描述块command descriptor block(见表3.3)表3.3 SCSI-2命令描述块格式byte/bit765432100Operation Code1Logical unit numberReserved2Logical block address(if required)3456Transfer length(if required)Parameter list length(if required)Allocation length(if required)78910Reservedbyte/bit7654321011ControlOperation Code是操作代码,表示特定的命令。高3位为Group Code,共有8种组合,低5五位为Command Code,可以有32种命令。这样最多可以存在256个命令。表3.4给出了本次设计中用到的几个命令。表3.4 SCSI常见命令SCSI CommandOption CodeINQUIRY12hMODE SENSE(6)1AhREAD(10)28hREAD CAPACITY25hWRITE(10)2AhHost会依次发出INQUIRY、Read Capacity、Mode Sense请求,如果上述请求的返回结果都正确,则Host会发出READ命令,读取文件系统0簇0扇区的MBR数据,随即进入文件系统识别阶段。3.1.6 USB设备标准请求设备请求是一个标准请求集,但在本次设计中,只用到其中的几个请求,现将这几个请求的数据格式及其说明罗列如下:(1)Get_DescriptorUSB设备一插入到USB总线后,主机为了了解设备的情况,即使用此设备请求,来获取设备信息。Get_Descriptor请求的结构见表3.5。表3.5 Get_Descriptor请求的结构bmRequestType(1)bRequest(1)wValue(2)Windex(2)wLength(2)Data0x800x0600 0100 0008 00其中bmRequestType 0x80,bRequest06,代表请求类型为Get_Descriptor,而描述符类型由wValue00 01来表达,表示DEVICE,即获取设备描述符,长度由wLength08给出。设备接收到此请求后,应该向主机返回本设备的设备描述符,长度为8个字节。(2)Set_Configuration得到描述符以后,主机将为设备选择一个配置,成功进行配置以后,描述符中所定义的各个端点便可以正常使用了。该请求的结构见表3.6表3.6 Set_Configuration请求的结构bmRequestType(1)bRequest(1)wValue(2)Windex(2)wLength(2)Data0x000x0901 0000 0000 00其中bmRequestType 0,bRequest0x09,代表请求类型为SET_CONFIGURATION。(3)Set_Address设置地址,主机在通过缺省管道读取设备描述符后,便对设备设置一个非0 地址,此后的通信在此地址进行。该请求的结构见表3.7表3.6 Set_Address请求的结构bmRequestType(1)bRequest(1)wValue(2)Windex(2)wLength(2)Data0x000x0500 0200 0000 00其中bmRequestType 0,bRequest0x05,代表请求类型为SET_ADDRESS。3.2 U盘文件系统处理程序设计基础3.2.1 FAT文件系统介绍 一个FAT文件系统卷(卷可以理解为是一张软盘、一个硬盘或一个FLASH电子盘)由5部分组成:主引导记录区(MBR)、系统引导记录区(DBR)、文件分配区(FAT)、根目录区(DIR)和数据区(DATA)。(1)主引导记录区(MBR)按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。不过,在总共512字节的主引导扇区中,MBR只占用了其中的446字节(偏移0偏移1BDH),另外的64字节(偏移1BEH偏移1FDH)交给了DPT(Disk Parition Table 硬盘分区表),最后两字节“55,AA”(偏移1FE偏移1FFH)是分区的结束标志。这个整体构成了硬盘的主引导扇区。主引导记录中包含了硬盘的一系列参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确,并且在系统硬件完成自检以后引导具有启动标志的分区上的操作系统,并将控制权交给启动程序。MBR是由分区程序所产生的,它不依赖任何操作系统,而且硬盘引导程序也是可以改变的,从而实现多系统共存。(2)系统引导记录区(DBR)DBR(Dos Boot Record)是操作系统引导记录区的意思。它通常位于硬盘的0磁道1柱面1扇区,使操作系统可以直接访问的第1个扇区,它包括1个引导程序和1个被称为BPB(Bios Pararmeter Block)的本分区的参数记录表。引导扇区的主要任务是当MBR将系统控制权交给它时,判断本分区根目录前两个文件是不是操作系统的引导文件(以DOS为例,既是Io.sys和Msdos.sys)。如果确定存在,就把其读入内存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数和分配单元的大小等重要参数。DBR的结构定义如下:typedef struct uchar JmpBoot3; /典型值:0xEB,0x3E,0x90。char OEMName8; /典型值:“MSWIN4.1”。uint BytesPerSec; /每扇区字节数。uchar SecPerClus; /每簇扇区数。uint ReservedSec; /保留扇区数,从DBR 到FAT 的扇区数。uchar NumFATs; /FAT 的个数。uint RootEntry; /根目录项数。uint TotalSec; /分区总扇区数(=32M 时用)。uchar DrvNum; /软盘使用0x00,硬盘使用0x80。uchar Reserved1; /保留。uchar BootSig; /扩展引导标记:0x29。uchar VolID4; /盘序列号。char VolLab11; /“Msdos ”。char FileSysType8; /“FAT16 ”。uchar ExecutableCode448; /引导代码。uint EndingFlag; /结束标识:0xAA55。DBR_tag;(3)文件分配区(FAT)在DBR之后的是FAT(File Allocation Table文件分配表)区。FAT负责给文件分配空间,故称之为文件分配表。FAT区结构见表3.7。表3.7 FAT区结构表项代码示例含义0FFF8h磁盘标示字,必须为FFF8h,注意高位在后。1FFFFh第一簇已被占用。20003h0000h 可用簇。30004h0002h-FFFEh 已占用,代码代表存放文件的簇链中的下一个簇的簇号。40005hFFF0h-FFF6h 保留簇。5FFFFhFFF7h 坏簇。60000hFFF8h-FFFFh 文件的最后一簇。操作系统分配磁盘空间按簇来分配的。因此,文件占用磁盘空间时,基本单位不是字节而是簇,即使某个文件只有一个字节,操作系统也会给他分配一个最小单元即一个簇。为了可以将磁盘空间有序地分配给相应的文件,而读取文件的时候又可以从相应的地址读出文件,我们把整个磁盘空间分成32K 字节长的簇来管理,每个簇在FAT 表中占据着一个16 位的位置,称为一个表项。对于大文件,需要分配多个簇。同一个文件的数据并不一定完整地存放在磁盘的一个连续的区域内,而往往会分成若干段,像一条链子一样存放。这种存储方式称为文件的链式存储。为了实现文件的链式存储,磁盘上必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继内容的下一个簇的簇号,对一个文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT 表来保存的,FAT 表的对应表项中记录着它所代表的簇的有关信息:诸如是否空,是否是坏簇,是否已经是某个文件的尾簇等。(4) 根目录区(DIR)DIR(Directory)是根目录区,紧接着第2个FAT表(即备份的FAT表)之后,记录着根目录下每个文件(目录)的起始单元,文件的属性等。定位文件位置时,操作系统根据DIR中的起始单元,结合FAT标就可以知道文件在硬盘中的具体位置和大小了。目录项的结构见表3.8。表3.8 目录项的结构偏移长度/字节说明格式备注00H8文件名ASCII字符,当首字母如下时为特殊代码:00H-为用名称;05H-当文件的第一个字符为E5H时,必须换成05H,因为E5H在首字母时另有含义;E5H-文件已使用,但已删除;2EH-本项为目录。不足8个字节时,必须以空格填满。08H3文件类型(扩展名)ASCII字符不足3个字节时必须填满。0BH1文件属性76543210未定义未定义存档目录卷标系统隐藏只读0CH10保留16H2上次更新时间须经编码:(unsigned 16 bit-bit integer)time=Hr*2048+Min*32+Sec+2续表3.8 目录项的结构偏移长度/字节说明格式备注18H2上次更新日期须经编码:(unsigned 16 bit-bit integer)time=(Yr-1980)*512+Mon*32+Day1AH2起始簇号此文件开始的簇号,如果文件有多簇,根据FAT中与此对应项的信息可得下一簇簇号。1CH4文件大小文件长度(5) 数据区(DATA)数据区是真正意义上的数据存储的地方,位于DIR之后,占据硬盘上的大部分数据空间。3.3 MP3程序设计基础经过压缩后的MP3文件数据由多个帧组成,帧是MP3文件最小组成单位。每个帧又由帧头、附加信息和声音数据组成。每个帧播报时间是0.026秒,其长度虽位率的不同而不等,有些MP3文件末尾有些额外字节存放非声音数据的说明信息。MP3文件结构如图3.3所示。图3.3 MP3文件结构3.3.1 帧头格式分析帧头长4字节,对于固定位率的MP3文件,所有帧的帧头格式一样,其数据结构如下:struct FrameHeader unsigned int syn:11; /同步信息 unsigned int versio:2; /版本 unsigned int layer:2; /层 unsigned int protection:1; /CRC校验 unsigned int bitrate:4; /位率 unsigned int frequency:2; /频率 unsigned int padding:1; /帧长调节 unsigned int private:1; /保留字 unsigned int mode:2; /声道模式 unsigned int mode extension:2; /扩充模式 unsigned int copyright:1; /版权 unsigned int original:1; /原版标志 unsigned int enphasis:2; /强调模式HEADER;帧头4字节详细说明见表3.9。表3.9 帧头4字节的格式名称长度(位)说明同步信息11第1、2字节所有均为1,第1字节恒为FF。版本200-MPEG 2.5,01-未定义,10-MPEG 2,11-MPEG 1。层200-未定义,01-Layer 3,10-Layer 2,11-Layer 1。CRC校验10-校验,1-不校验。位率4第3字节取样率,单位是kbps,例如:采用MPEG-1 Layer3,64kbps时,值为0101。频率2采样频率,对于MPEG-1:00-44.1kHz,01-48kHz,10-32kHz,11-未定义。帧长调节1用来调整文件头长度,0-无需调整,1-调整。保留字1没有使用。声道模式2第4字节表示声道,00-立体声,01-Joint Stereo,10-双声道,11-单声道。扩充模式2当声道模式为01时才使用。版权1文件合法性,0-不合法,1-合法。原版标志1是否原版,0-非原版,1-原版。强调方式2用于声音经降噪压缩后再补偿的分类,一般不用。MP3的帧长取决于位率和频率,计算公式为:帧长=144bitrate/frequency+padding例如:位率为64kbps;,频率为44.1kHz,padding为1时,帧长为210字节。帧头后面是可变长度的附加信息,对于标准的MP3 文件来说,其长度是32字节,紧接其后的是压缩的声音数据,当解码器读到此时处就进行解码了。3.3.2 可变位率的MP3对于固定位率(CBR,Constant Bitrate)的MP3文件,并不是所有的帧都是等长的,有的帧可能多一个或几个字节。还有一种可变位率(VBR,Variable Bitrate)的MP3文件,是为了使MP3文件长度最小同时又保证声音质量,与CBR文件相比,除了第一帧不同外,其余的都一样。VBR的第一帧不包含声音数据,其长度是156个字节,用来存放标准的声音帧头(4字节)、VBR文件标识、帧数、文件字节数等信息。由于本次使用的MP3文件均为CBR类型,因此不对VBR文件的具体结构进行说明。3.3.3 ID3标准MP3帧头中除了存储一些像private、copyright.、orginial的简单音乐说明信息以外,没有考虑存放歌名、作者、专辑名、年份等复杂信息,而这些信息在MP3应用中非常必要。1996年,FricKemp在“studio3”项目中提出了在MP3文件尾增加一块用于存放歌曲的说明信息,形成了ID3标准,至今已制定出ID3 V1.0,V1.1,V2.0,V2.3和V2.4标准。版本越高,记录的相关信息就越丰富详尽。ID3 V1.0标准并不周全,它具有存放的信息少、无法存放歌词,无法录入专辑封面、图片等缺点。V2.0是一个相当完备的标准,但给编写软件带来困难,虽然赞成此格式的人很多,在软件中真正实现的却极少。绝大多数MP3仍使用ID3 V1.0标准。此标准是将MP3文件尾的最后128个字节用来存放ID3信息,这128个字节使用说明见表3.10表3.10 ID3 V1.0文件尾说明字节长度(Byte)说明133存放“Tag”字符,表示ID3V1.0标准,紧接其后的是歌曲信息43330歌名346330作者649330专辑名94974年份9812730附注1281MP3音乐类别,共147种4固件程序的设计与实现4.1 软件概述根据系统功能的构成,软件可分为主控程序、MP3播报程序、U盘程序等主要结构,而提供支持的则有文件系统和FLASH读写程序。还有用于交互的串口通讯等程序。软件的构成如图4.1所示。图4.1 电梯语音播报软件的构成4.2 主控程序设计主程序在结构上属于分支结构,其结构框图如图4.2所示。图4.2 主控程序结构框图主程序完成的任务主要有设备上电后的初始化工作、检测当前设备的工作状态和并引导相应程序的运行。在本次设计中,设备的工作状态有两种:U盘工作状态和语音播报状态。前者用于与外界交换MP3文件,后者用于播放MP3文件。因此有必要在上电伊始对设备的工作状态进行检测,以正确运行相应功能的程序。根据硬件的设计,只需检测P3.2上的电平信号就可知设备的工作状态。在主程序中,USB_INS即为P3.2。若其值为1,则设备工作于U盘状态;否则设备工作于语音播报状态。检测并判别后,主程序将循环运行某一工作状态相应的程序,直至掉电。上电后的初始化主要为时钟初始化、PC机与单片机的串口通迅初始化。其它初始化工作需在设备进入相应的工作状态后才被响应。4.3 USB程序设计对于U盘固件程序设计而言,难点在于充分了解USB海量存储的工作过程和每个阶段所用到的协议和详细定义。U盘的工作过程描述如下:插入U盘后,USB主机发出USB标准请求,也就是配置阶段,这时USB设备需要返回正确的设备描述符等,主机可以得知设备的相关信息并对其进行配置。U盘被主机识别为Bulk-Only的Mass Storage设备,然后即进入Bulk-Only传输方式,USB设备需要解析CBW中的SCSI命令并执行对应功能。首先需要正确响应Inquiry、Read Capacity、Mode Sense等请求,使主机获得关于U盘更具体的信息,之后便是U盘读写操作。程序需要将USB传下来的数据写入FLASH芯片,但在此并不用关心FAT文件系统,U盘程序只需要将数据写入Windows指定的地址,包括FAT本身。U盘程序的流程图如图4.3所示。图4.3 U盘程序的流程图从主控程序可以看出,对于一个USB Mass Storage设备而言,必须支持三个端点的数据处理。0号端点:控制端点,用于控制传输,主机通过与端点0 相对应的管道来读取设备描述符,完成对设备地址的设置,并完成配置。此端点为双向数据传输端点;两个非0端点:批量传输端点。这种端点为单向数据传输端点,分别为Bulk-In端点和Bulk-Out端点。最开始USB标准请求是通过端点0发给USB设备的。首先是对AT89C51SND1C单片机的USB硬件进行设置,包括时钟设置和使能USB部件。程序中用函数AtmelUSBInit()完成对USB的初始化。然后用函数EpEnable()使能两个批量传输端点,对FIFO缓冲区进行复位操作,允许相应端点的中断。USB设备插入到PC机的USB接口以后,主机检测到设备插入,就会通过控制管道向缺省地址发送USB标准请求,进入设备配置阶段。在配置过程中,每当设备收到主机发送的请求后,便会触发端点中断寄存器中端点0所对应的位。此时,应该读取端点0的数据缓冲区,读取指定长度的数据。然后对照USB标准设备请求的数据格式,对请求类型进行识别,然后转向相应的标准请求处理函数。函数Ep0()就是用来响应USB配置过程的,分别响应主机发出的Set_Address、Set_Confi-guration、Get_Descriptor等标准请求。Get_Descriptor要求USB设备向主机传送相应的描述符,程序里面定义了设备描述符Device_Descriptor18 、Configuration_Desc-riptor_All32等数据结构,后者包括接口描述符、端点描述符等。Set_Address将为设备分配一个有效地址,此请求不要求向主机回传数据,但必须返回状态。返回状态的方法是向端点写入长度为0的字节信息。然后对单片机的USBADDR和USBCON两个控制位进行设置。Set_Configuration的作用是为设备选择一个配置,一个功能设备可以有多个配置,配置将按其提供描述符时的顺序编号,而此请求是为设备选定一个配置。Ep0()函数调用Set_Address()、Get_Descriptor()、Set_Configuration()三个函数完成上述配置过程的具体工作,包括更改AT89C51SND1C的相关寄存器。Ep0()函数的代码如下:void Ep0()uchar xdata DT32=0,;/数组DT初始化uchar i; i = ReadEp(0,DT);/读端点0数据到DT,i=字节数,有时=8,有时=0 if (DT0 & 0x60)=0) & i)switch (DT1)/DT1=5,6,9 case set_address: Set_Address(DT2); break;case get_descriptor: Get_Descriptor(DT3,DT6); break;case set_configuration: Set_Configuration(DT2); break;default: break;elseif(DT0=0xa1) WriteEp(0,0,0);接下来就是要处理Bulk-Only传输中的SCSI-2命令解析了。Mass Storage协议通过Bulk传输方式来传送命令与数据。在这种传输方式下,有三种类型的数据在USB和设备之间传送:CBW、CSW和普通数据。CBW和CSW其实都有一定的格式,普通数据根据其前面的命令块来决定其归属和意义。程序中用main_rxdone()函数来处理Bulk-Out端点,用main_t-xdone()函数来处理Bulk-In端点。main_txdone()函数内容非常简单:void main_txdone() UEPSTAX &= (TXCMP);/清除TXCMP TransmitCSW(); /发送CSW命令包这是因为Bulk-In端点的事务都在main_rxdone()函数中处理掉了,也就是说当mai-n_rxdone()中解析到某命令需要从Bulk-In端点向主机发送数据时,尤其无法一次传送完毕时,并不退出main_rxdone()函数,而是循环陆续发送数据。这样在主控程序循环里就基本上没有机会执行main_txdone()函数了。在main_rxdone()函数里主要解析CBW中的CBWCB命令块,根据不同的SCSI-2命令调用对应的函数进行响应。void main_rxdone()data uchar i;xdata uchar Buf64;/原为data i = ReadEp(2,Buf); /i总是=31 LED =0;bulk_CSW4 = Buf4; bulk_CSW5 = Buf5; bulk_CSW6 = Buf6; bulk_CSW7 = Buf7; /CBW_Tag-CSW_Tag for(i=0;i12;i+) bulk_CBW.CBWCBi = Bufi+15;/CBW_CB就是SCSI-2命令switch(bulk_CBW.CBWCB0)/操作码case Inquiry:WriteEpBulk(1,36,B_InquiryData);break;/有TransmitCSWcase Mode_Sense:SCSI_Mode_Sense();break;case Read10:SCSI_Read10();break;/有TransmitCSWcase Read_Capacity:WriteEpBulk(1, 8, B_Read_Capacity);break;/读容量case Read_Format_Capacities:SCSI_Read_Format_Capacities(); break;case Test_Unit_Ready:TransmitCSW();break;/有TransmitCSWcase Verify:TransmitCSW();break;/有TransmitCSWcase Write10:SCSI_Write10();break;/有TransmitCSWcase Medium_Removal:TransmitCSW();break;/有TransmitCSWLED =1;主机会向设备发出下列几个SCSI-2命令:Inquiry、Read Capacity、Mode Sense这几个命令用于告知主机这个设备的存储器的具体情况,主机基于此创建一个可移动存储设备。程序中依据SCSI-2命令集定义了这几个命令的返回数据结构B_InquiryData、B_Read_Capacity、B_Mode_Sense_ALL等,其中填充了和FLASH逻辑结构即可移动磁盘容量、逻辑块数量、大小等相关参数。32M FLASH一共2048个Block,每Block包含32个Page,每Page包含512Bytes。本次设计中留下10个Block作为FLASH的读写缓冲区,可用的最大Block编号为2037。B_Read_Capacity数据结构中规定的逻辑块大小为512 字节,则最后逻辑块编号设定为2037320xfea0。然后,比较重要的就是U盘读写操作,也就是利用SCSI_Read10()、SCSI_Write10()两个函数响应Read10、Write10两个SCSI-2命令,对FLASH芯片进行读写操作。通过分析Read10()子程序(见附录三)可知,USB每次可以传输多个逻辑块,每个逻辑块512个字节需要分8次传输完毕。程序中在每次从FLASH芯片读取64个字节到UE-PDATX寄存器的过程中,调用了汇编语言编写的ReadFlash()函数,目的是大大缩短字节传送的时间,从而提高宏观U盘读取速度,这点在写U盘的程序中也有所应用。写U盘函数SCSI_Write10()中使用了WriteFlash()汇编语言函数来提高速度。从WriteFlash()子程序看,写U盘的处理过程远比读U盘的过程要复杂,因为FLASH 芯片必须先擦除再编程,而且每次至少擦除1个Block,也就是说为了写入一个Page需要擦除32个Page,那么如何处理这复杂多变的情况呢?在本次设计中,使用FLASH芯片最后的两个Block作为缓冲区,解决即将被擦掉的数据的备份问题,因为AT89C51SND1C的SRAM资源有限,无法在其中实现缓冲区。在程序中定义的BuffBlock为2046,使用第2046和2047个Block作为缓冲区,使用两个连续奇偶Block作为缓冲区是和FLASH芯片的COPY-BACK操作有关的。4.4 语音播报程序设计语音播报程序流程图如图4.4所示:图4.4 语音播报程序流程图程序中首先用下列函数进行和MP3播报有关的时钟设置,MP3解码器初始化和音频部件初始化。void MP3_Init(void)PllInit(); /时钟初始化MP3RegInit(); /MP3解码器相关寄存器初始化AudioInit(); /音频部件接口寄存器初始化然后利用函数Init_FAT_Info()初始化FAT文件系统,获取必要的参数信息,这里比较重要的有SecPerClus,BytesPerSec,SectorofFatSize,RootEntry,FirstDataSec等参数。GetMP3List()的功能是扫描目录区,获取扩展名为MP3的文件清单。在每首MP3歌曲开始播报的时候,会调用PlayInit()函数对MP3歌曲进行初始化,该函数的功能是解析MP3文件头,获取采用率等信息并正确设置MP3解码器的时钟参数。void PlayInit(uchar n)bWan=0;Dis_MP3(); /MPEN=0,禁止MP3解码MP3FsInit(MP3Cann & 0x0f);/设置MP3解码率Set_Sec(n); /设置歌曲初始扇区数据ReadFlasstoBuff(); /先读一扇区En_MP3(); /MPEN=1,允许MP3解码然后将要播报的MP3文件的帧头读取到MP3Can数组中,根据MP3帧头的格式,分离出MPEG版本和采样率标识,调用MP3FsInit()函数设置PLL时钟参数来满足MP3解码器和音频输出部件的采用率时钟要求。void MP3FsInit(uchar i)PLLNDIV = 0;PLLRDIV = 0;MP3CLK = 0;AUDCLK = 0;PLLNDIV= Tab_MP3i0;/NDIV=24,124PLLRDIV= Tab_MP3i1;/RDIVH=126,576,511PLLCON&= 0x3f; /清除d7,d6PLLCON|= Tab_MP3i2; /RDIVLMP3CLK = 3;AUDCLK = Tab_MP3i3; /AUDCLK=5,4,9,11,9,19AUDCON0 = Tab_MP3i4;MP3歌曲的采样率设置好以后,就调用PlayMP3()函数播放歌曲,该函数在播放完歌曲后才退出。主控程序这时会处于等待状态,直至收到上位机的控制信号。while(bWan) /若“播完”标志为1,则结束播报,否则继续播报 PlayMP3(); /MP3播报子程序在PlayMP3()这段程序中,将有大量的数据从FLASH芯片读取到SRAM的缓冲区中,然后再填充到MP3解码器的缓冲区中。这里存在一个重要的问题,就是程序运行过程中的效率问题,即不能出现MP3解码器数据填充的间断,否则将出现断音现象,这也是程序设计不当而导致声音杂乱(听起来失真,慢拍,实际是均匀连续的断音)的原因所在。为了保证不出现断音的问题,需要确保程序填充MP3解码缓冲区的速度大于MP3解码速度。具体到程序中,从SRAM的缓冲区复制一个字节到MP3解码器后,需要等待MP3解码器的握手信号,不能立即复制下一个字节。因此要先准备好一个扇区再判断MP3解码器握手信号,不要等查询到解码器需要数据了才去FLASH里读取。这里还有一个值得注意的地方,就是在程序中认为一个MP3歌曲文件在FLASH中是线性递增连续存放的,但这却与FAT文件系统的规定产生了矛盾。那么为什么这样编写程序还是正确的呢?其实,这是一种人为的干预。在硬盘中存储的文件确实是以簇为单位按链式存放的,但在这样一种情况下,文件可以是按线性递增连续存放的:即先将硬盘格式化,然后在将所有文件一起复制到硬盘中,那么这些文件在硬盘中就是按线性递增连续存放的。这样做的目的是为了简化后面的程序编写。在这个条件下,取MP3数据时,只需要在FAT表中找到相应的首簇(扇区)。在程序中,将该值赋予扇区指针SecP,以后只需要将SecP简单加1即可。4.5 Uart通信程序设计在程序调试的时候,需要从串口输出一些信息,帮助了解程序运行的状况。Uart通讯程序是通过RS-232串行接口与PC机通信,用于向PC机反馈信息,并且接收PC机发送过来的控制信号。该段程序有三部分组成:初始化程序、接收程序和发送程序。(1)初始化程序AT9C51SND1C单片机产生波特率的方法有两种,一种是利用定时器T1产生;另一种是利用内部波特率产生器(IBRG)。两种方法相比较,发现由内部波特率产生器产生的波特率的精度要比定时器产生的高。因此在本次设计中,采用内部波特率产生器作为波特率的来源。void Uart_Init(uchar br) CKCON |= 0x01;/CKCON.0=X2=1,Fcpu=Fper=Fosc=20Mhz BDRCON |= 0x1e;/BRR=1;启动波特率 PCON |= 0x80;/SMOD = 1; BRL = br; SCON = 0x52; ES = 1;(2)接收程序接收程序很简单,只需要判断接收中断标志位是否为1即可。若为1,则接收的内容就存放在SBUF中。void Receive() while(!RI); RI=0;(3)发送程序发送程序一共有三个,分别发送一串长度不限的字符串、一个限制长度的字符串和一个整型值。虽然三者在功能上有所不同,但其原理是一致的。以发送一串长度不限的字符串的程序为例进行分析。程序代码如下。void printStr1(uchar *str1)while(*str1!=#) SBUF=*str1;while(!TI);TI=0;str1+; 通过程序可知,要想发送一个字节的数据,只需将它放入发送缓冲区SBUF,单片机就会自动将它发送出去,然后根据发送中断标志位TI来判断发送是否结束。那么要想发送一串字符串,只要重复上述步骤直到发送完为止。在该段程序中,字符#是作为未知长度字符串的结束标志。当程序遇到它时,就认为后面没有要发送的字符了。4.6 控制界面设计本次设计采用Visual Basic软件制作电梯语音播报系统的PC机控制/显示界面。该界面可以模拟楼层到站播报、电梯上下行指示、电梯开关门指示等,还可对语音音量进行调节。另外,该界面还将实时的显示单片机运行过程中的参数及状态。整个VB程序主要有两部分组成:一是串口通信、一是按键处理。按键处理也就是将该按键所对应的命令字送入发送缓冲区,并将其发送。该命令字将用于告诉单片机将要播报哪首MP3,或者是否要调节音量。5 结论通过设计和调试,本次设计的电梯语音系统基本实现了MP3在单片机中的应用。由VB制作的界面可以控制单片机播放制定的MP3文件。可以播放的语音信息包括:1层16层的到达指示、开关门指示、上下行指示和安抚。同时,系统可以通过USB接口与电脑连接,并实现彼此间的数据交换。由于所学知识有限,本次设计只在粗浅的层面上对USB通信、MP3压缩格式、UART串口通信等方面进行研究,并设计出一套简单的电梯语音播报系统,实现一些基本的功能。在很多方面还有待改进。比如说在MP3文件存储方面:在本次设计中通过人为干预使MP3文件在FLASH中是以簇为单位顺序存放,这样虽使程序得以简化,但却不能随意的添加或删除文件。必须先将U盘格式化,再将所有的MP3文件一起复制到FLASH中,才能保证系统的正确运行。不过这样操作又显得麻烦,因此这一部分可以进行适当的改进。致谢在本次毕业设计过程中,赵玉昆老师与朱超锋师傅给予了诸多指导和帮助。其中不乏有对本次设计的顺利完成起到关键性作用的指导,在此,诚挚的感谢赵玉昆老师与朱超锋师傅,同时也诚挚的感谢电气创新实验室的蒋鸿飞老师、胡淑惠老师和袁老师为本次毕业设计的顺利完成提供的帮助。参考文献1 赵文博 单片机语言C51程序设计 人民邮电出版社 20052 刘文涛 MCS51单片机培训教程 电子工业出版社 20053 李朝青 PC机及单片机数据通信技术 北京航空航天大学出版社 20014 石东海 单片机数据通信技术从入门到精通 西安电子科技大学出版社 20025 夏路易、石宗义 电路原理图与电路板设计教程Protel 99SE 北京希望电子出版社 20026 周坚 单片机C语言轻松入门 北京航空航天大学出版社 20067 汪勇、熊前兴 “MP3文件格式解析” 武汉理工大学计算机学院 武汉4300638 萧世文、宋延清 USB2.0硬件设计 清华大学出版社 20069 许永和 8051单片机USB接口程序设计(上) 北京航空航天大学出版社 200410 李军 51系列单片机高级实例开发指南 北京航空航天大学出版社 200411 Single-chip AT89C51SND1C Datasheet12 NAND FLASH K9F5608 Datasheet附录一 电梯语音播报系统电路原理图附录二 电梯语音播报系统电路印板图附录三 电梯语音播报系统源程序清单主控程序main.c#include AT89C51SND1_REG.H#include UDISK_DEF.H#include /*定义标示符*/#define uchar unsigned char#define uint unsigned int#define K9F5608P0#define K9F_P4 P4#define COMMAND 0x05#define ADDRESS 0x09#define D_DATA 0x01#define RB 0x01#define NO_CE 0x03#define NUM21/最多歌数/*全局变量*/uchar SongInfNUM6,PageBuf512,ListNum; uint BootSector,BytesPerSec,SecPerClus,RsdSector,SecofFAT,RootEntry,FirstDataSec;uchar CMD,VOL=0x10;bit C_V_flag;uchar br=191;bit br_set;bit mp3;xdata uchar SongListNUM11;/歌名xdata uint ShSecNUM;/首扇区xdata uint MoSecNUM;/末扇区xdata uint FileSecYNUM;/末扇字节xdata uchar MP3CanNUM;/MP3帧头参数索引=0.5代表第几套参数data uint SecP,SecP0;/播放时扇区指针data uint SecM;/末扇区data uint SecY;/末扇字节data uint bufp,bufp0;/Buff中字节计数bit bWan; /放完/* MP3解码率表 */code uchar Tab_MP385=/NDIVRDIVHRDIVLAUCDAUDCON0Fs(Khz)24, 0x1f,0x80,/*=126*/ 5,0x77, /44.100124,0x8f,0xc0,/*=575*/ 4,0x77, /48.000124,0x7f,0xc0,/*=511*/ 9,0x76, /32.0000,0,0, 0,0 , /保留24, 0x1f,0x80,/*=126*/ 11,0x77, /22.050124,0x8f,0xc0,/*=575*/ 9,0x77, /24.000124,0x7f,0xc0,/*=511*/ 19,0x76, /16.0000,0,0,0,0 /保留;code uint Tab_Fs8=44100,48000,32000,0,22050,24000,16000,0;/采样率表code uint Tab_bps16=0,32,44,48,56,64,80,96,112,128,160,192,224,256,320,-1;/位率表/*函数原型*/void Uart_Init(uchar br);void Receive();void printMP3List();void printStr1(uchar *str1);void printStr2(uchar *str2);void printInt(uint Int);void Init_FAT_Info(void);void ReadPage(uint Page);uchar GetMP3List(void);void Get_List(void);void jsIndexTab(void);void PllInit(void);void MP3RegInit(void);void AudioInit();void MP3_Init(void);void Dis_MP3(void);void En_MP3(void);void MP3FsInit(uchar i);void Set_Sec(uchar Hao);void PlayInit(uchar n);void ReadFlasstoBuff(void);void PlayMP3(void);void Set_Volume(uchar v);void Rec_Switch();void Set_BR(uchar br);/*/* 主程序 */*/void main() Uart_Init(br); /串口初始化 MP3_Init(); /MP3初始化 Flash_Reset(); printStr1( ); if(USB_INS) /P3.4,USB Cable Insert Sensor AtmelUSBInit();EpEnable(); while(1) if (UEPINT & EP0) Ep0();/(UEPINT & EP0) 端点0中断 if (UEPINT & EP1) main_txdone(); if (UEPINT & EP2) main_rxdone(); else ListNum=GetMP3List(); /获取MP3列表及起始簇号和文件长度的数据 printMP3List(); jsIndexTab(); /计算第CMD号歌曲长度,首扇区,末扇区及其字节数 Get_List(); /在MP3文件中取MP3头,获得版本、采样率、位率 Set_Volume(VOL); while(1) printStr1(请选择要播放的歌曲); Receive(); /获得命令-要播放第CMD首歌曲 Rec_Switch(); if(br_set) printStr1(波特率重新设置); Set_BR(br); printStr1(新波特率已设置); if(C_V_flag) Set_Volume(VOL); printStr1(已设置音量); if(mp3) printStr1(已选择播放的歌曲:); printStr2(SongListCMD); PlayInit(CMD); printStr1(正在播放:); while(bWan) /printStr1(); PlayMP3(); printStr1(该歌曲已播完); /*/* 文件系统 */*/*获取MP3列表及起始簇号和文件长度的数据*/uchar GetMP3List(void)unsigned char i = 0, j = 0, l = 0;int k = 0;unsigned char MP33 = M, P, 3;Init_FAT_Info();k = BootSector + RsdSector + 2 * SecofFAT;ReadPage(k);while (PageBuf0 != 0)for (j=0; j16; j+)if (!PageBufj * 32) break;if (PageBufj * 32 = 0xE5) continue;if (!memcmp(MP3, &PageBufj * 32 + 8, 3) /file findfor (i=0; i11; i+) SongListli = PageBufj * 32 + i;for(i=0;i6;i+) SongInfli=PageBufj*32+i+26; /获得起始簇号和文件长度l+;k+;ReadPage(k);return l;/* 计算第j号歌曲长度,首扇区,末扇区及其字节数 */void jsIndexTab(void) uchar i,j; uint Cu,Sec; /小于32MB ulong Len; /文件长度for(j=0;j1; i-) Len = (Len 8) | SongInfji; /文件长度 ShSecj=Sec; /记录首扇区 MoSecj = Len / 512 + Sec; /末扇区 FileSecYj = Len % 512; /最后扇区字节数 /* 在MP3文件中取MP3头,获得版本、采样率、位率 */void Get_List(void)uchar n,t;uint i,sec;for(n=0;n21;n+) /第n首歌/if(SongListn0=0)continue;/无此歌sec=ShSecn; /找到第n首歌,取首扇区while(1) /连续读扇区,找MP3帧头ReadPage(sec); /读文件一个扇区for(i=0;i=0xe0)/数据帧的11个同步位t=(PageBufi+2 & 0x0C) 2);/采样率if(PageBufi+1 & 0x08) = 0)t=t+4;/版本2MP3Cann = t;/参数索引低4位=采样率MP3Cann |= (PageBufi+2 & 0xf0);/参数索引高4位=位速break;if(i512)break;/找到,下一个MP3sec+;/*初始化FAT信息*/void Init_FAT_Info(void)ReadPage(0);/读0块0页/找DOS引导扇区。有MBR就在分区表中找分区起始扇,再找到DOS引导扇。没有MBR、首字节是EB、XX、90,这就是DOS引导扇if (PageBuf0 = 0xeb & PageBuf2 = 0x90)/DOS Boot,软盘类型,本盘=eb,3c,90BootSector = 0;else/有MBR,硬盘类型BootSector = PageBuf454 + PageBuf455 * 256 + PageBuf456 * (256 * 256) + PageBuf457 * (256 * 256 * 256);ReadPage(BootSector);/读DOS引导扇BytesPerSec = PageBuf11 + PageBuf12 * 256;/每扇区字节数=200HSecPerClus = PageBuf13;/每簇扇区数=1RsdSector = PageBuf14 + PageBuf15 * 256;/保留扇区数=6SecofFAT = (PageBuf22 + PageBuf23 * 256);/FAT扇区数=00FD=253RootEntry = (PageBuf18 * 256 + PageBuf17);/根目录项数=200H FirstDataSec = BootSector + RsdSector + (SecofFAT * 2) + (RootEntry * 32 + (BytesPerSec-1) / BytesPerSec);/首数据扇区=0+6+ (253* 2) + (512* 32 + (512-1) /512)=544/*/* MP3播放 */*/* 初始化PLL */void PllInit(void)CKCON |= 0x01;PLLCON &= (0x13); /Enable PLLPLLCON |= 0x11;/* 初始化MP3寄存器 */void MP3RegInit(void)MP3CON &= (0x08);/不屏蔽数据请求,允许MPREQ中断标志MP3CON |= 0x80;/允许MP3解码/* 初始化音频寄存器 */void AudioInit()uchar i = 10;AUDCON0 = 0x77;/0111 0111 (PLL=384Fs)AUDCON1 &= (0xB0); /SRC=0,MSREQ=0,MUDRN=0AUDCON1 |= 0x01;while (i)i-;AUDCON1 |= 0x40;/* 初始化MP3播放器(PLL,MP3Reg,Audio) */void MP3_Init(void)PllInit();MP3RegInit();AudioInit();/* 禁止MP3解码 */void Dis_MP3(void)AUDCON1 &= (0x01);/AUDEN=0,禁止音频MP3CON &= (0x80);/MPEN=0,禁止MP3解码/* 允许MP3解码 */void En_MP3(void)AUDCON1 |= 0x01;/AUDEN=1,允许音频MP3CON |= 0x80;/MPEN=1,允许MP3解码/* 音量 */void Set_Volume(uchar v)MP3VOL = MP3VOR = v;/* 设置MP3解码率 */void MP3FsInit(uchar i)PLLNDIV = 0;PLLRDIV = 0;MP3CLK = 0;AUDCLK = 0;PLLNDIV= Tab_MP3i0;/NDIV=24,124PLLRDIV= Tab_MP3i1;/RDIVH=126,576,511PLLCON&= 0x3f; /清除d7,d6PLLCON|= Tab_MP3i2; /RDIVLMP3CLK = 3;AUDCLK = Tab_MP3i3;/AUDCLK=5,4,9,11,9,19AUDCON0 = Tab_MP3i4;/* 设置歌曲初始扇区数据 */void Set_Sec(uchar Hao)SecP=ShSecHao; /当前扇区=首扇区,不断增大SecM=MoSecHao;/末扇区,不变SecY=FileSecYHao;/末扇字节, 不变/* 播放初始化 */void PlayInit(uchar n)bWan=0;Dis_MP3();/MPEN=0,禁止MP3解码MP3FsInit(MP3Cann & 0x0f); /设置MP3解码率Set_Sec(n); /设置歌曲初始扇区数据ReadFlasstoBuff(); /先读一扇区En_MP3();/MPEN=1,允许MP3解码/* 读Flash一页到Page_Buf */void ReadFlasstoBuff(void) uint i;if(bWan) for(i=0;i SecM)/到末扇区for(i=SecY;i512;i+)PageBufi=0;/不足之处填全0bWan=1;bufp=0; /Buff中字节计数/* 有MP3帧请求就传送,直到帧请求消失 */void PlayMP3(void)while(MP3STA1 & 0x10)/有帧请求while(MP3STA1 & 0x08)/字节请求MP3DAT = PageBufbufp;/逐个送MP3解码if(+bufp = 512)/Buff用完ReadFlasstoBuff();/*/ /* 串口处理 */*/ /*串口初始化*/void Uart_Init(uchar br) CKCON |= 0x01;/CKCON.0=X2=1,Fcpu=Fper=Fosc=20MhzBDRCON |= 0x1e;/BRR=1;启动波特率,TRCK=1;RBCK=1;收发都用波特率,SPD=1;波特率不除6。PCON |= 0x80;/SMOD = 1;BRL = br;SCON = 0x52;ES = 1;/*输出歌曲列表*/void printMP3List() uint i,j; for(i=0;i21;i+) printStr1( ); for(j=2;j11;j+) SBUF=SongListij; while(!TI); TI=0; SBUF=r; while(!TI); TI=0; SBUF=n; while(!TI); TI=0;void printStr1(uchar *str1)while(*str1!=0) SBUF=*str1;while(!TI);TI=0;str1+; SBUF=r; while(!TI); TI=0; SBUF=n; while(!TI); TI=0;void printStr2(uchar *str2) uint j; for(j=0;j11;j+) SBUF=str2j;while(!TI);TI=0;SBUF=r;while(!TI);TI=0;SBUF=n;while(!TI);TI=0;void printInt(uint Int) uchar a6;int i=5,j;while(Int!=0) ai=Int%10;Int=Int/10;i-;for(j=i+1;j=24&SBUF100) switch(SBUF) case 126:br=126;br_set=1;printStr1(BaudRate=9600kbps);break; case 191:br=191;br_set=1;printStr1(BaudRate=19200kbps);break; case 223:br=223;br_set=1;printStr1(BaudRate=38400kbps);break; case 234:br=234;br_set=1;printStr1(BaudRate=57600kbps);break; case 245:br=245;br_set=1;printStr1(BaudRate=115200kbps);break; default:break; C_V_flag=0; mp3=0; if(SBUF=20) CMD=SBUF;mp3=1;C_V_flag=0;br_set=0; void Set_BR(uchar br) printStr1(%);BRL=br;br_set=0;void Receive() while(!RI); RI=0; printInt(SBUF);USB通信程序usb.c#include AT89C51SND1_REG.H#include UDISK_DEF.H#define LED P5_2extern void ReadFlash(); /Defined in FLASH_RW.Cextern void WriteFlash();/* 设备描述符 Get_Descriptor()使用*/code uchar Device_Descriptor18 =0x12,/0x12描述符长度0x01,/DEVICE descriptor类型,01=Device0x10, 0x01,/spec rev level (BCD) 1.0 USB规范1.100x0, /device class 类0x0, /device subclass 子类0x0, /device protocol 规范0x20,/max packet size Ep0的最大包尺寸0x05, 0x82,/Nationals vendor ID 0x00, 0x11,/Nationals product ID 0x00, 0x00,/Nationals revision ID 0,/index of manuf. string 0,/index of prod. string 0,/index of ser. # string 0x01/number of configs. 配置数;/* 配置描述符 Get_Descriptor()使用*/code uchar Configuration_Descriptor_All32 =/=Configuration Descriptor=配置描述符9,/Size of Descriptor in Bytes描述符长度2,/Configuration Descriptor (0x02)类型,02=Configuration0x20,0x00,/Total length in bytes of data returned LSB本配置的总长1,/Number of Interfaces本配置支持的接口数1,/Value to use as an argument to select this configuration选择本配置的参数值0,/Index of String Descriptor describing this configuration本配置串描述的索引0x80,/Configuration characteristic配置位,D7=10xfa,/Maximum Power Consumption in 2mA units 最大功耗=500ma/=Bulk-Only Data Interface Descriptor=接口描述符9,/ 描述符长度4,/ 类型,04=Interface0,/the index of the interface descriptor Number of Interface接口号0,/Value used to select alternative setting备选设置的值2,/EndPoint Number Used in this Descriptor Ep数,至少=28,/Class Code (Assigned by USB Org)类,8=Mass Storage Class6,/interface subclass1=RBC,2=SFF,3=QIC,4=UFI,5=SFF,6=SCSI子类0x50,/bulk 0nly Transport接口规范,bulk 0nly0,/Index of String Descriptor Describing this interface本配置串描述的索引/=Bulk-in Endpoint=Bulk-In端点描述符0x07,/length of this desc.描述符长度0x05,/ENDPOINT descriptor TYPE类型,05=EndPoint0x81,/address (IN) Endpoint 4 84地址,d7=1:输入,d3.0=Ep号(Ep1,In)0x02,/attributes (BULK)属性(块)0x40, 0x00,/max packet size (64)最大包尺寸0x0,/Does not apply to Bulk endpoints/=Bulk-out Endpoint=Bulk-Out端点描述符0x07,/length of this desc.描述符长度0x05,/ENDPOINT descriptor TYPE类型,05=EndPoint0x02,/address (OUT) Endpoint 5 05地址,d7=0:输出,d3.0=Ep号(Ep2,Out)0x02,/attributes (BULK)属性(块)0x40, 0x00,/max packet size (64)最大包尺寸0x0/Does not apply to Bulk endpoints;/* INQUIRY 命令返回的数据格式 main_rxdone()使用*/code uchar B_InquiryData36 =0x00, /Direct Access Device 设类型,00=软盘0x80, /RMB 可移动介质0x00, /ISO/ECMA/ANSI 版本,UFI应该=000x01, /Response Data Format UFI应该=010x1f, /Additional Length UFI应该=1F,附加长度,n-40x00,0x00,0x00, /ReservedE, a, s, e, m, e, n, t,/8字符,Vendor InformationU, S, B, -, M, P, 3, , V, 3, ., 0, , , , ,/16字符,Product Identification0, 1, 0, 2/Product Revision Level n.nn产品版本; /* SCSI-读_格式化容量命令(0x23)的返回数据 SCSI_Read_Format_Capacities()使用*/code uchar B_Read_Format_capacities =0x00, 0x00, 0x00, 0x10, /容量描述的长度,每个描述8字节0x00, 0x00, 0x07, 0xf5,0x01, 0x00, 0x02, 0x00, /当前容量(只有0.994M)0x00, 0x00, 0x07, 0xfd,0x00, 0x00, 0x02, 0x00 /可格式化容量(只有0.998M);/* SCSI-读_容量命令(0x25)的返回数据 main_rxdone()使用*/code uchar B_Read_Capacity8 =0x00, 0x00, 0xfe, 0xa0, /32MB的最末逻辑块地址0x00, 0x00, 0x02, 0x00/块字节数;/* SCSI-模式检测命令的返回数据 SCSI_Mode_Sense()使用*/code uchar B_Mode_Sense_ALL =0x0b, 0x00,/Mode Data Length0x00, 0x08, 0x00, 0x00,0x7d, 0, 0, 0, 0x02, 0x00;/* SCSI-模式检测命令的返回数据 SCSI_Mode_Sense()使用*/code uchar B_Mode_Sense_TPP18 =0xf0, 0x00,/Mode Data Length5, 0, 0, 0, 0, 0x0b, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0;/* (未执行到)SCSI-模式检测命令的返回数据 SCSI_Mode_Sense()使用*/code uchar B_Mode_Sense_ZERO =0x00, 0x06,/Mode Data Length0x00,/Medium Type Code0,/write enabled0, 0, 0, 0/reserved;/* main_rxdone()赋值,TransmitCSW()使用*/uchar xdata bulk_CSW13=/原来是data0x55,0x53,0x42,0x53,/bytes 4 dCSWSignatureUSBS0x00,0x00,0x00,0x00,/bytes 4 dCSWTag=CBW的Tag0x00,0x00,0x00,0x00,/bytes 4 dDataResidue剩余数据0x00/bCSWStatus 00=good state.;struct_CBW data bulk_CBW;/* USB初始化 main()调用*/void AtmelUSBInit() int data i;PLLNDIV= 0x04;PLLCON |= (0x3&Rdiv)2;USBCLK = 0;PLLCON &= (PLLRES);PLLCON |= PLLEN;USBCON &= (USBE);for(i=0;i3000;i+);USBCON |= USBE;/* Ep允许 main()调用*/void EpEnable(void)UEPNUM=0x00;UEPCONX=0x80;UEPNUM=0x01;UEPCONX=0x86;UEPNUM=0x02;UEPCONX=0x82;UEPRST=0x07;UEPRST= 0x00;UEPIEN=0x07;USBIEN|=EEOFINT;USBADDR=FEN;/* 读某Ep数据到XRAM,返回字节数 */uchar ReadEp(uchar EpNum,uchar *Data)uchar data i=0;UEPNUM = EpNum;/Ep号EndPointwhile(iUBYCTLX)/端点X字节计数器Datai+=UEPDATX;/端点X FIFO数据UEPSTAX &= (RXOUTB0|RXOUTB1|RXSETUP);/端点X状态 / RXOUTB0,RXOUTB1=当收到有效包时由硬件置1 / RXSETUP=当收到SETUP包时由硬件置1retur
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。