基于S3C2410处理器的IDE硬盘接口设计_第1页
基于S3C2410处理器的IDE硬盘接口设计_第2页
基于S3C2410处理器的IDE硬盘接口设计_第3页
基于S3C2410处理器的IDE硬盘接口设计_第4页
基于S3C2410处理器的IDE硬盘接口设计_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、基于S3C2410处理器的IDE硬盘接口设计1设计任务在学习了接口技术这门课后,基于对课堂的知识的理解,加上自己查阅的一些资料。对S3C2410处理器做了一些了解,尤其是IDE硬盘接口,作为适用于嵌入式系统的大容量、高速率、高可靠性的数据存储系统,它的重要性不用明说。在这次论文中主要完成以下任务:1. 对S3C2410处理器的概述;2. 对IDE硬盘接口的概述;3. 完成原理图和硬件设计说明;4. 完成软件设计和驱动设计;5. 给出应用示例。其中应用示例由于现在还在学习中,所以借鉴他人的示例进行解读和学习,并尝试加入自己的创新。2 S3C2410处理器S3C2410处理器是Samsung公司基

2、于ARM公司的ARM920T处理器核,采用0.18um制造工艺的32位微控制器。该处理器拥有:独立的16KB指令Cache和16KB数据Cache,MMU,支持TFT的LCD控制器,NAND闪存控制器,3路UART,4路DMA,4路带PWM的Timer ,I/O口,RTC,8路10位ADC,Touch Screen接口,IIC-BUS 接口,IIS-BUS 接口,2个USB主机,1个USB设备,SD主机和MMC接口,2路SPI。S3C2410处理器最高可运行在203MHz。ARM 包括一系列微处理芯片技术。ARM920T是ARM 系列微处理器的一种,ARM920T 的32位微处理器结构带有一个

3、5阶管线,可以极低的功耗提供优异的性能。 16K指令高速缓存和16K数据高速缓存可为现有的程序和数据提供零等待时间,或者也可被锁定,以确保对关键指令和数据的无延迟存取。ARM920T的单/双精度整数及浮点运算能力。当对数字音频和视频格式进行编码、执行工业控制运算以及其它运算密集型计算和数据处理功能时,该协处理器可具有高速精确计算能力。同时配备了Thumb扩展、EmbeddedICE调试技术和Harvard总线。在生产工艺相同的情况下,性能可达ARM7TDMI芯片的两倍之多。ARM920T系列主要应用于机顶盒产品、掌上电脑、笔记本电脑和打印机。3 IDE接口3.1IDE接口基本概况IDE的英文全

4、称为“Integrated Drive Electronics”,即“电子集成驱动器”,它的本意是指把“硬盘控制器”与“盘体”集成在一起的硬盘驱动器。是现在普遍使用的外部接口,主要接硬盘和光驱。采用16位数据并行传送方式,体积小,数据传输快。一个IDE接口只能接两个外部设备。 把盘体与控制器集成在一起的做法减少了硬盘接口的电缆数目与长度,数据传输的可靠性得到了增强,硬盘制造起来变得更容易,因为硬盘生产厂商不需要再担心自己的硬盘是否与其它厂商生产的控制器兼容。对用户而言,硬盘安装起来也更为方便。IDE这一接口技术从诞生至今就一直在不断发展,性能也不断的提高,其拥有的价格低廉、兼容性强的特点,为其

5、造就了其它类型硬盘无法替代的地位。但其传输最大只能是133MB/s,远远低于串口的600MB/s的速度。IDE/ATA磁盘驱动器与早期的ATA驱动器相比,增加了任务文件寄存器,包括数据寄存器、状态寄存器以及反映地址的驱动器号、磁头号、道号和扇区号寄存器等。ATA接口规范定义了信号电缆和电源线的电器特征、互联信号的电器和逻辑特征,还定义了存储设备中可操作的寄存器以及命令和协议。3.2IDE接口的发展和作用早期的IDE接口有两种传输模式,一个是PIO(Programming I/O)模式,另一个是DMA(Direct Memory Access)。虽然DMA模式系统资源占用少,但需要额外的驱动程序

6、或设置,因此被接受的程度比较低。后来在对速度要求愈来愈高的情况下,DMA模式由于执行效率较好,操作系统开始直接支持,而且厂商更推出了愈来愈快的DMA模式传输速度标准。而从英特尔的430TX芯片组开始,就提供了对Ultra DMA 33的支持,提供了最大33MB/sec的的数据传输率,以后又很快发展到了ATA 66,ATA 100以及迈拓提出的ATA 133标准,分别提供66MB/sec,100MB/sec以及133MB/sec的最大数据传输率。值得注意的是,迈拓提出的ATA 133标准并没能获得业界的广泛支持,硬盘厂商中只有迈拓自己才采用ATA 133标准,而日立(IBM),希捷和西部数据则都

7、采用ATA 100标准,芯片组厂商中也只有VIA,SIS,ALi以及nViidia对次标准提供支持,芯片组厂商中英特尔则只支持ATA 100标准。3.3寄存器规范定义了两组寄存器:命令寄存器和控制寄存器。命令寄存器用来接收命令和传送数据,控制寄存器用来控制磁盘操作。常用的寄存器包括数据寄存器、命令寄存器、驱动器/磁头寄存器、柱面号寄存器、扇区号寄存器、扇区数寄存器和状态寄存器。3.4数据传输方式ATA接口规范定义了两种数据传输方式:可编程I/O(PIO)方式和DMA方式。PIO传送方式下,CPU对控制器的访问都是通过PIO进行的,包括从控制器读取状态信息和错误信息,以及向控制器发送命令和参数。

8、在一次PIO数据传输过程中,CPU先选址,然后使读/写信号有效,CPU或控制器放数据到数据总线,控制器或CPU读取数据,操作完成后,释放总线,这样一次数据传输完成。DMA方式,即直接内存访问,CPU把缓冲区的地址与需要读写的长度告诉外设,外设在准备好后向CPU发出一个DMA请求,要求CPU暂停使用内存,获得同意后就直接在内存和外设之间传输数据,完成后再把对内存的访问权归还给CPU。IDE实物图4硬件设计IDE设备(例如硬盘、光驱等)上都会使用一组跳线来确定安装后的主盘(Master,MA)、从盘(Slave,SL)状态。如果在一根IDE数据线上接两个IDE设备的话,还必须分别将这两个IDE设备

9、设置为一个为主盘,另一个为从盘状态。这样,安装后才能正常使用。如果一根IDE数据线上只接惟一的IDE设备,不管这个IDE设备原先是设置为主盘还是从盘状态,都不需要对这个惟一的IDE设备重新设置跳线。确定好硬盘的连接方案后,就要设置硬盘跳线了。一般可以在硬盘的IDE接口与电源接口之间找到由35列跳线。不管是什么硬盘,在跳线设置上,大致可分成主盘、从盘与电缆选择(Cable Select)三种。硬盘的出厂预设值都是设为主盘,所以如果将硬盘设为主盘,一般就不用设置跳线了。 如图1所示,S3C2410与硬盘之间接口电路分为3个部分:片选信号、数据信号和控制信号。硬盘上寄存器分为两组,分别由IDE_CS

10、0和IDE_CS1选中,DA0DA2则用于组内寄存器寻址;数据线DD0DD15因存在输入/输出方向问题,故用nOE(读信号)接buffer(74LVTH)的DIR引脚来控制缓冲器方向;控制信号部分因该CPU与硬盘之间DMA时序不一致,故采用一块EPM7032AETC44-7芯片用于调整其时序。PIO模式下,不需要DMARQ和nDMACK信号,DMA模式下,这两个信号才起作用。5驱动软件设计硬盘驱动程序实现分为初始化、打开设备、设备I/O操作和释放设备等几部分。下表说明接口引脚的定义5.1 硬盘初始化与X86不同,在ARM 体系结构中,对内存和外设的访问使用统一的指令,所以要对外设地址进行内存映

11、射。也就是说,通过一张表将I/O地址映射到内存空间中来,这部分工作是在系统初始化期间完成的。在IDE子系统初始化期间,Linux系统一旦发现一个IDE控制器,就设置它的ide_hwif_t结构来反映这个控制器和与之相连的磁盘;向Linux的VFS登记每一个控制器,并分别把它加到blk_dev和blkdevs向量表中;请求控制适当的IRQ中断(主IDE控制器是14,次IDE控制器是15)和I/O空间(主控制器0x1f0,次控制器0x170):为每一个找到的IDE控制器在gendisk列表中增加一个条目。IDE硬盘的初始化工作由idedisk_init完成:(1)在数组ide_hwifs中找出已登

12、记得各IDE控制器控制的所有IDE硬盘(一个控制器最多控制两个硬盘),每个IDE硬盘对应一个ide_drive_t结构。(2)对找到的每个IDE硬盘,调用函数ide_register_subdriver填写各IDE硬盘结构中的相关信息域,主要是填写其驱动程序结构ide_driver_t。硬盘驱动中的函数do_rw_disk通过向磁盘控制寄存器写参数启动磁盘操作,完成真正的数据读写。(3)对找到的每个IDE硬盘,调用函数idedisk_setup进一步设置其ide_drive_t结构,包括设置该结构的settings域、doorlocking域、cyl、head、sect域、id域等。5.2 打

13、开设备打开块设备的操作与打开普通文件的操作基本相同。(1)在当前进程的文件描述符表中为打开文件找一个空位,申请一块内存,用于建立新文件的打开文件对象,即结构file。(2)解析设备特殊文件名,获得其VFS inode和dentry结构,根据dentry结构填写file结构,尤其是将file结构的f_op域设为其VFS inode中的缺省文件操作。(3)执行该文件操作集中的open操作,即blkdev_open,它根据设备特殊文件的主次设备号从blkdevs向量表中取出已经注册的文件操作集(file_operations)fops,用该结构代替file结构中的f_op域。(4)执行中新文件操作集

14、中的open操作,即bl带头kdev_open,它根据VFS inode中的i_rdev域查找数组ide_hwifsp,从中找出该IDE硬盘所对应的ide_drive_t结构;如果ide_drive_t结构中注册有驱动程序,执行驱动程序集中的open操作。(5)将打开文件对象插入到当前进程的文件描述符表中,返回文件描述符,即打开文件对象在进程文件描述符表中的索引。5.3 设备I/O操作读写块设备时要用到块缓冲区(bufer),对bufer的管理采用BuferCache机制。它管理bufer的创建、撤销、回收、查找、更新等,同时还要与系统中的其它部分(如文件系统、内存管理等)交互。Linux将B

15、uffer Cache从块设备驱动程序中独立出来,作为对块设备读写的通用机制,所以对块设备的读、写、同步等操作采用的都是由操作系统提供的公共函数,一般为block_read()和block_write()。为了减少对块设备操作的次数,读写块设备时采用延迟操作,尽量将多个读写操作合并,所以操作请求不是马上递交给物理设备,而是提供了一种手段记录每次的请求(request),并为每类块设备提供一个请求队列用来排队、合并、重组对该块设备的请求。当需要从硬盘读时,block_read()函数首先查找Buffer Cache 如果在其中能找到需要的buffer,则立刻返回:否则,生成一个读请求,并将其加入

16、相应的请求队列排队。当需要向硬盘写时,block_write()为此次写操作生成一个buffer,而后生成一个写请求,并将其加入相应的请求队列排队。块设备驱动程序提供了一个请求处理函数,对硬盘而言是函数do_rw_disk。在适当的时候,硬盘的请求处理函数启动,do_rw_disk处理在请求队列上排队的请求,通过向硬盘发出读、写命令完成对设备的真正操作。其伪代码如下:DO_RW_DISK(COMMAND)Set_Registers();if(COMMAND=READ) Set read_intr as interrupt process function Send WIN_READ or WI

17、N_MULTREAD command to Command registerif(COMMAND=WRITE) Send WIN_WRITE or WIN_MULTWRITE command to Command register Get the status of Status register and set DRQ bit Set write intr as interrupt process function Senddatato buferin thedisk5.4 释放设备由设备驱动程序中的release操作完成,一般完成与打开设备相反的动作:释放打开设备特殊文件时在file结构上

18、所创建的私有结构;如果是最后一个设备的释放,则从硬件上关闭设备。6应用示例(给出相应的应用示例,1个或者几个例子都可)6.1示例介绍由于手边没有合适的机器做实物的实验,所以根据书上的介绍,给出应用示例。这个示例是利用IDE接口改装光驱。由于现在很多人的机器上都装有光驱,但原来旧的光驱读盘能力下降,加上网络资源的丰富,光驱变很少人使用了。但丢弃了又很可惜,所以可以利用光驱加上单片机的控制,改造成一个CD播放器。由于光驱本身没有播放功能,所以利用IDE接口连接单片机去控制光驱,改装后的CD播放器具有播放、前进、后退、停止等功能。6.2设计原理在本次示例中使用51单片机作为控制芯片,用它的P1、P2

19、口组成16为的数据输入输出口,连接IDE的数据线。P0口用于连接IDE的读写控制、复位和寄存器控制,由于P0口的驱动力比较低,所以用10k的中的排阻对其上拉。光驱需要的电流比较大,一般要一点几安培的电流,在制作时可以使用开关电源模块或使用旧电脑上的AT电源。还有一点IDE连接电缆的红色线为1号线,其他则书序排列到40号,同时要把光驱后面板上的跳线设置为主盘。下表中列出了需要用到的元件名和作用。6.3编程思路及部分函数介绍像其他电脑接口或单片机应用制作一样,难点在于单片机控制程序的编写,ATAPI协议时从ATA协议发展出来的,它的控制命令和返回的数据格式十分复杂,用于光驱时对于不同形式的光盘,控

20、制命令的使用方式也不太一样。ATAPI有许多寄存器,操作这些不同的寄存器便可以实现CD读取的相应功能,如读状态寄存器应先设置好CS和DA,选定要操作的是状态寄存器,把DIOW应缴电平拉低,这时就可以读ATAPI的数据线DD了,得到当前设备状态,再把DIOW拉高完成读取。在源码中ReadStatus(void)函数用作此功能。在发送控制命令,可以分为两类,分别为ATA Command和ATAPI Packet command,前者只要先选择要操作的是命令寄存器,在向数据口发一个命令直接就可以实现所要的功能。在源码中InitCDROM(void)函数就是用于此,如先选择命令寄存器再发送A1H到数据

21、口,就可以执行识别光驱的自检命令,命令完成后读数据口可以得到光驱的相关信息。后者的使用则相对复杂一些,发送信息包时,先向传输直接计数寄存器中写入药发送的字节数,再送A0H信息命令字到命令寄存器,通知设备要发送信息包,最后向数据寄存器发送信息包。光驱播放CD时有一系列的动作,先是上点复位,光盘托盘打开,托盘关闭,读取曲目播放。使用单片机对光驱进行CD播放控制时也应该有这样的顺序,在本文源码的主程序中先是调用速食化函数,对光驱进行复位和识别,初始化沉厚后就会调用读取TOC函数,读取曲目和相关值,然后在对按钮进行判断,做出相应的控制。下图是设计原理图:6.4 IDE(ATAPI)引脚定义从表一可以看

22、到ATAPI各引脚的定义,下面是几个在实例中要使用的引脚具体说明:1 DD(15:0)Device DataDD占用318引脚,是一个8位或16位的双向数据线,在用于读写CDROM的寄存器时只使用低8位,而在传送信息包或数据时使用全部16位。2 CS(1:0)Chip SelectCS0,CS1是用于选择指令寄存器芯片的,为低电平有效,它和DA组合就可以选择所要操作的寄存器。3 DA(2:0)Device AddressDA为三位的地址线,和CS组合选取要操作的寄存器。4 DIOR(Device I/O read)DIOR为控制寄存器或数据口读的引脚,低电平有效。5 DIOW(Device I

23、/O write)DIOW为控制寄存器或数据口写的引脚,低电平有效。6 RESET当此引脚为低电平时CDROM会被复位。7 INTRQ (Device interrupt)INTRQ为中断请求,当CDROM在读写数据等状态下会在此引脚输出信号以使控制器中断程序得以执行,本实例中没有使用到这个方法。8 IORDY (I/O channel ready)这个引脚可判断CDROM的数据口是否就绪,等待数据的输入或输出。同样实例中没有使用到些引脚。前6种引脚都在实例电路中一一连接在51单片机的IO引脚上,我们可以根据CDROM引脚所要求的电平去实现该引脚的功能,如RESET引脚为低电平有效,连接于单片

24、机的P0.7引脚上,用如下的51C语言就可以实现对CDROM实行复位操作:P0_7 = 0; /拉低P0_7,RESET为低,复位开始dmsec(100); /调用延时函数延时一段时间P0_7 = 1; /拉高RESET,复位完成6.5寄存器在IDE界面中寄存器的作用可以分二类,一种是用于传送指令和返回数据,一种是用于控制设备和返回控制状态。表3中指明了各ATAPI常用寄存器的地址和功能。地址是用CS和DA组成,CS为寄存器区段的选择,再加上三位地址的DA就可以组合出多个地址编码选择不同的寄存器。在单片机控制程序中可以把P3口IO引脚和DA、CS相连,在程序中控制P3口各引脚的电平状态去选择要

25、操作的寄存器,再通过控制DIOR/ DIOW引脚电平实现读写寄存器。部分的寄存器地址是相同的,如状态寄存器和命令寄存器使用同一个地址,读这个地址时为操作状态寄存器,写这个地址时为操作状态寄存器。6.6 ATA命令ATAPI是在ATA发展而来的,所以仍支持绝大部分的ATA命令。这些命令会直接送到Command寄存器后被ATAPI设备所执行。在这里只说明一下实例程序中所用到的一些相关命令。1ATAPI设备软复位命令(08H)当向命令寄存器写入08H时,驱动器会执行软件复位命令,执行效果和硬件复位差不多。2. 设备诊断(90H)执行这个命令时,驱动器会运行自身诊断程序,诊断结束后会返回一个值到错误寄

26、存器,读取错误寄存器值并和标准值比较,当返回值不等于01H或81H时则说明CDROM自身诊断未通过(Device0)。3.识别信息包功能IDENTIFY PACKET DEVICE(A1H)这个命令执行后可以返回当前所选择的驱动器的信息包参数和其它相关的参数,如信息包的长度、驱动器的型号、驱动器序列号等等。先向命令寄存器发1H,然后就可以在DATA寄存器中读取驱动器相关信息,每次可以读取两个字节。5 信息包功能PACKET(AOH)执行这个命令后驱动器将准备发送信息包命令,在执行这个命令之前应先向Cylinder Low/High寄存器写入将发送一个值为命令信息包的长度除于2的数值,以让驱动器

27、知道要接收多少次数据。6.6信息包命令ATAPI是在ATA发展过来的,最大的不同点就是有了针对CDROM等设备的信息包命令,实现两者的兼容。从上文可以得知发送PACKET命令后就可以发送信息包命令了,简单说来就是ATAPI设备在收到PACKET命令后就会进入信息包的接收状态,如信息包正常发送完成后,设备就会执行这个信息包命令。信息包的格式一般由12字节组成,有些设备是16字节,对于这个值的确定可以用识别信息包功能读取信息值。首字节是指令字,以后的字节就是参数。这些字节的发送是这样实现的,选定DATA寄存器,把两个字节加在DD的十六位数据线上,控制DIOW为低,完成写入,再拉高DIOW,后两个字

28、节加上数据线上如此循环直到所有字节发送完。文中的实例是针对CDROM中的CD播放功能的,那下面举几个CD播放要用到的信息包命令。1. READ SUBCHANNEL读次信道命令这个命令执行后驱动器会返回CD中的次信道信息和播放状态等。这些信息如:当前的MSF地址,当前的音频播放状态和当前的轨道数等。具体的实现可以参考实例程序中的void ReadSub(void)函数。2READ TOC Command 读轨道TOC命令TOC是指光盘中轨道的开始地址及其它相关信息,这些信息存在于Q sub-channel(Q子信道)中。当指定要播放一条曲目,就要先知道曲目所在轨道的开始地址和结束地址。这就需要

29、用这个命令去读取光盘中轨道信息,它还将返回CD光盘的曲目数等。MSF位是要求返地址格式为MSF地址格式,这个位一般要置1。MSF地址格式是指光盘中的数据实际被写入的位置,最小单位是F,75个F字段则为一个S字段,而60个字段则为一个M字段。F字段的有效值范围为074,S字段的有效值范围为059,M字段的有效值范围为099。MSF地址的数据格式由4个字节组成,第一字节为保留字节,第二字节为M字段,第三字节为S字段,第四字节为F字段。返回数据格式在第二字节和第九字节中,设它为的数值返回的数据形式也不同,在CD光盘播放中一般置零就可以了。曲目号是指定要返回TOC数据的曲目号,它的有效值为00H-63

30、H,也就是0-99号,当曲目号为AAH时则返回整张光盘的结束MSF地址。具体编程方法可以参看void ReadTOC(unsigned char Track)函数的写法。3. PLAY AUDIO MSF Command播放命令当用读TOC 命令得知曲目的MSF 开始和结束地址数据后,就可以用播放命令去插放该曲目的音乐了。要播放单个曲子可以先读它的开始MSF 地址做为开始地址,再读下一曲子的MSF 地址做为结束地址。而播放整个光盘则可以先读首曲目的MSF 地址做为开始地址,再用AAH 去读最后的结束地址做为结束地址。6.7源代码#include #defineA0P0_0#defineA1P0

31、_1#defineA2P0_2#defineCS0P0_3#defineCS1P0_4#defineWRP0_5#defineRDP0_6#define RSTP0_7#define CDCOM P0 /CDROM控制线#define INTRQP3_7 /INTRQ#define DBMP2 /CDROM数据线高8位#define DBL P1 /CDROM数据线低8位/用变量设置P0的值,以方便对应于各寄存器的地址值#defineREG_Data 0xE0#defineREG_Err 0xE1 /Features#define REG_Features 0xE1#define REG_Se

32、ctor 0xE2#define REG_CyLow 0xE4#define REG_CyHig 0xE5#define REG_DriveHead 0xE6#define REG_Status 0xE7 /Command#define REG_Command 0xE7#define PLAYKeyP3_2#define EJECTKeyP3_3#define STOPKeyP3_5#define NEXTKeyP3_4#define PREVIOUSKeyP3_6#define ERRLEDP3_7unsigned char code ReadSubP=0x42,0x02,0x40,0x01

33、,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00; /ReadSub命令信息包unsigned char code ReadTOCP=0x43,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00; /ReadTOC命令信息包unsigned char code PlayMSFP=0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00; /MSF播放命令信息包unsigned char data PacketTemp24; /信息包暂存RAM,

34、用写数据和读数据的暂存unsigned char REGBL=0, REGBM=0; /用于暂存读取寄存器的值unsigned char PacketSize; /用于保存CDROM定义的信息包长度,有12,16unsigned char bdata CDStatusREG; /可位寻址变量保存CDROM的状态寄存器值sbit ERR = CDStatusREG0; /错误sbit DRQ = CDStatusREG3; /数据请求sbit DRDY = CDStatusREG6; /设备就绪sbit BSY = CDStatusREG7; /忙unsigned char bdata CDEr

35、r=0; /保存各种错误标识sbit INITERR = CDErr0; /初始化错误sbit TESTERR = CDErr1;/CDROM自身诊断错误sbit UKERR = CDErr2; /未知错误sbit EJECTING = CDErr3; /弹出sbit CDOK = CDErr4; /CD就绪sbit PLAYING = CDErr5;sbit PAUSEING = CDErr6;sbit STOPING = CDErr7;unsigned char DEV; /选择驱动器时所用的参数unsigned char AudioStatus; /当前的播放状态unsigned cha

36、r StartTrackNum; /开始曲目unsigned char EndTrackNum; /结束曲目unsigned char CurrentTrackNum; /当前曲目unsigned char CurrentM, CurrentS, CurrentF; /当前MSF值unsigned char StartM, StartS, StartF; /开始的MSF值unsigned char EndM, EndS, EndF; /结束的MSF值 void dmsec(unsigned int msec);void RedREG(unsigned char REG);void WriREG

37、(unsigned char LSB, unsigned char MSB, unsigned char REG);void SendPacket(unsigned char SkipDRQ);void TestCD(void);void ReadSub(void);void ReadTOC(unsigned char Track);void ResData(unsigned char Count);void ReadStatus(void);void InitCDROM(void);void BSYWait(void);/void INTRQWait(void);void DRQWait(v

38、oid);void NDRQWait(void);void LoadPacket(unsigned char code *RT);void TestUnitReady(void);void PlayMSF(void);void Eject(unsigned char EJ);void Pause(unsigned char PR);void Next(unsigned char NP);void Stop(void);void main(void)InitCDROM();doif (!PLAYKey) /play or pause 要求CD就绪才响应if (CDOK)dmsec(20); if

39、 (!PLAYKey)if (PLAYING) /CD正在播放中的处理if (PAUSEING) /继续播放Pause(0);PAUSEING = 0;else /暂停播放Pause(1);PAUSEING = 1;else /CD就绪按play后播放ReadTOC(CurrentTrackNum); /读当前TOCReadTOC(0xAA);PlayMSF(); /播放PLAYING = 1; /标识dmsec(2000);if (!STOPKey) /当CD在播放中if (PLAYING)dmsec(20);if (!STOPKey)Pause(1); /暂停Stop(); PLAYING

40、 = 0;PAUSEING = 0;dmsec(2000);if (!NEXTKey)if (PLAYING)dmsec(20);if (!NEXTKey)Next(1);dmsec(2000);if (!PREVIOUSKey)if (PLAYING)dmsec(20);if (!PREVIOUSKey)Next(0);dmsec(2000);if (!EJECTKey)dmsec(20);if (!EJECTKey)if (EJECTING)Eject(3); /装载EJECTING = 0;dmsec(3000);InitCDROM();elseEject(2);EJECTING = 1

41、;CDOK = 0;PAUSEING = 0;PLAYING = 0;STOPING = 0;dmsec(2000);ReadStatus();/读状态ERRLED = ERR; /ERR指示while(1);/1ms延时11.0592MHz void dmsec(unsigned int msec) unsigned int TempCyc;while(msec-)for(TempCyc=0; TempCyc125; TempCyc+);/写寄存器void WriREG(unsigned char LSB, unsigned char MSB, unsigned char REG)CDCOM

42、 = REG; /设要写的REG/EA=0;/程序中有中断程序时应先关中断CS1 = 1;DBL = LSB;DBM = MSB; /写数据WR = 0;WR = 1; CS1 = 0; /WD,CS1置回DBL = 0xFF;DBM = 0xFF;dmsec(3); /延时/EA=1; 在这开中断/读寄存器void RedREG(unsigned char REG)CDCOM = REG; /设要读的寄存器/EA=0;/程序中有中断程序时应先关中断CS1 = 1; RD = 0; /开始读数据线REGBL = DBL; /从数据线上读状态寄存器值REGBM = DBM;RD = 1; CS1

43、 = 0; /RD,CS1置回dmsec(3); /延时/EA=1; 在这开中断/Count向CDROM发送信息包的大小void SendPacket(unsigned char SkipDRQ) unsigned char TempCyc;if (!SkipDRQ) NDRQWait();WriREG(PacketSize, 0xFF, REG_CyLow); /设CyLow,CyHig的值不应小于传输的数量否则PacketCommand时ERR出错WriREG(0x00, 0xFF, REG_CyHig); WriREG(DEV, 0xFF, REG_DriveHead); /选择Devi

44、ce 0WriREG(0xA0,0xFF,REG_Command); /发送A0H,Packet命令,准备发送PacketDRQWait(); for (TempCyc=0; TempCycPacketSize; TempCyc+)CDCOM = REG_Data; /设控制IO,CS0-1=0,A0-2=0,WR-RD=1,RST=1CS1 = 1; /这时CS1=1,CS0=0,A0-2=0,为选择数据寄存器Data RegisterDBL = PacketTempTempCyc*2;DBM = PacketTempTempCyc*2+1; /写信息包数据WR = 0;WR = 1; CS

45、1 = 0; /WR,CS1置回DBL = 0xFF;DBM = 0xFF;dmsec(3); /延时/EA=1; 在这开中断ReadStatus(); /返回当前状态/INTRQWait(); /等待CDROM中断/返回数据,Count为返回数据的多少void ResData(unsigned char Count)unsigned char TempCyc;for (TempCyc=0; TempCycCount; TempCyc+)CDCOM = REG_Data; /设控制IO,CS0-1=0,A0-2=0,WR-RD=1,RST=1CS1 = 1; /这时CS1=1,CS0=0,A0

46、-2=0,为选择数据寄存器Data RegisterRD = 0; /开始读数据线PacketTempTempCyc*2= DBL;PacketTempTempCyc*2+1 = DBM;RD = 1; CS1 = 0; /WR,CS1置回dmsec(3); /延时/EA=1; 在这开中断/读当前CDROM状态void ReadStatus(void)RedREG(REG_Status);/读状态寄存器CDStatusREG = REGBL; /放入可寻址位方便使用/读曲目TOCvoid ReadTOC(unsigned char Track)unsigned char TempCyc = 0

47、;LoadPacket(ReadTOCP); /暂存数据到RAMPacketTemp6 = Track; /要读取的轨道,值为0H63H,写AAH为返回开始区段值SendPacket(0); /向CDROM送信息包ResData(12);/返回数据4字节StartTrackNum = PacketTemp2; /读首曲目数字EndTrackNum = PacketTemp3; /读尾曲目数字if (Track = 0xAA)EndM = PacketTemp9; /读曲目的MSF值EndS = PacketTemp10;EndF = PacketTemp11;elseStartM = Pack

48、etTemp9; StartS = PacketTemp10;StartF = PacketTemp11;/播放MSFvoid PlayMSF(void)LoadPacket(PlayMSFP); /暂存数据到RAMPacketTemp3 = StartM; /写MSF值PacketTemp4 = StartS;PacketTemp5= StartF;PacketTemp6 = EndM;PacketTemp7 = EndS;PacketTemp8 = EndF;SendPacket(0); /向CDROM送信息包/弹出、装入void Eject(unsigned char EJ)LoadPa

49、cket(PlayMSFP); /暂存数据到RAMPacketTemp0 = 0x1B; /START/STOP UNIT Command字节PacketTemp4 = EJ; /EJ=0为停止,1为开始并读次信道,2为弹出托盘,3为装载光盘SendPacket(1); /向CDROM送信息包/暂停或继续void Pause(unsigned char PR)LoadPacket(PlayMSFP); /暂存数据到RAMPacketTemp0 = 0x4B; /PAUSE/RESUME CommandPacketTemp8 = PR; /PR为1时暂停SendPacket(0); /向CDRO

50、M送信息包/停止void Stop(void)LoadPacket(PlayMSFP); /暂存数据到RAMPacketTemp0 = 0x4E; /STOP/SCAN CommandSendPacket(0); /向CDROM送信息包/前进或后退void Next(unsigned char NP)ReadSub(); /读当前曲目if (NP) /计算NP = CurrentTrackNum + 1;elseNP = CurrentTrackNum - 1;if (NP EndTrackNum)NP = EndTrackNum;ReadTOC(NP); /读下一首或前一首的TOCPlayM

51、SF(); /播放/读次信道信息void ReadSub(void)LoadPacket(ReadSubP); /暂存数据到RAMSendPacket(0); /向CDROM送信息包ResData(12);/返回数据16字节AudioStatus = PacketTemp1;CurrentTrackNum = PacketTemp6;CurrentM = PacketTemp9;CurrentS = PacketTemp10;CurrentF = PacketTemp11;/检查CDROM是否就绪void TestUnitReady(void)unsigned char TempCyc;uns

52、igned char TempS;for (TempCyc = 0; TempCyc 12; TempCyc+)PacketTempTempCyc = 0x00; /Packet for Test Unit Ready CommanddoSendPacket(1); /因可能CDROM不在就绪状态所以跳过DRQ检测TempS = CDStatusREG & 0x89; /CDStatusREG & 0x89为判断ERR,DRQ,BSY中是否有1while(TempS); /PacketCommand失败时认为CDROM没就绪,再次发送Test Unit Ready command/初始化CDROMvoid InitCDROM(void)DBL = 0xFF;DBM = 0xFF;RST = 0; /拉低RST,延时使CDROM复位dmsec(100); /延时RST = 1; /复位完成拉高RS

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论