磁动力电子网-雕刻机DIY论坛,单片机论坛,CNCDIY,DIYCNC

 找回密码
 加入磁动力

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3812|回复: 13

zipamp2.0中英文对照源码大公开

[复制链接]
发表于 2005-10-2 22:24:00 | 显示全部楼层 |阅读模式
zipamp2.0中英文对照源码大公开
去年就打算做这事了,一直没有空,最近有空了一段时间,不过现在又开始忙了,先做好了一段,只剩下zfat和zata没有翻译完全。大家如果有空的话可以帮忙翻译一下,这都是更据我自己的理解翻译的,有些地方可能有错误,请大家指正包含。
回复

使用道具 举报

 楼主| 发表于 2005-10-2 22:46:00 | 显示全部楼层
以上的是已经翻译好了的源码,按照上面的提示可以将屏幕改成中文显示的,这里有个打包文件,是已经翻译好了的打包文件,里面有一个prj文件,是用cvavr打开的,直接进行编译就能成功了,我用我的富士通3g的硬盘试过,播放时十分之不流畅。问过Datazyb斑竹,他的回答是这样的:“我不知道你懂不懂FAT原理,如果懂的话,结合程序看看.你可以不去跟踪FAT链表,这样速度就很快.zipamp作者做的注释很详细,仔细体会下”暂时还没有翻译到zfat所以还没有弄懂。有时间时再进一步研究。
这个播放器很值得初学avr单片机的人员研究,注释做得十分之清楚。
CUqPNDiP.rar (43.11 KB, 下载次数: 853)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:48:00 | 显示全部楼层
希望能尊重我的劳动,在转贴的时候表明一下出处。最好给个链接。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:25:00 | 显示全部楼层
zipamp.c /********************************************* ZipAmp Author : Nasif Akand Copyright : (C) Nasif Akand 2003 Notice : Copyright 2003 Nasif Akand (nasif@yifan.net) http://go.to/zipamp http://zipamp.virtualave.net This file is part of ZipAmp MP3 software. ZipAmp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ZipAmp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 这一个文件是 ZipAmp MP3 软件的一部份。 ZipAmp 是免费的软件;你能重新分配它及[或] 修正 它在角马公众执照的术语之下当做出版被 免费的软件基础; 或执照的 2 版,或 (在你的选项)任何的较迟版本。 ZipAmp 在希望中被分配它将会是有用的, 但是没有任何的担保; 没有更甚至被暗示的担保 为一个特别的目的 MERCHANTABILITY 或健身。 那 为较多的细节角马公众执照。 你应该要接受角马公众执照的副本 连同这一个密码一起; 如果不,写到免费的软件 基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国 Chip type : AT90S8515 Clock frequency : 12.00000 MHz Memory model : Small Internal SRAM size : 512 bytes External SRAM size : 0 byte Data Stack size : 64 bytes 这个是用来设置Codevision的,按照这个设置然后添加下面所提示的包含就可以编译了。 芯片类型 : AT90S8515 时钟频率 : 12.00000 MHz 内存模式 : 小的 内在的 SRAM 大小 : 512 bytes 外部 SRAM 大小 : 0 byte 数据堆栈大小 : 64 bytes Tested ATA Drive Samsung SpinPoint SV3064D 30 GB Test Drive Access Time: Track to Track : 0.8 m/s Average : 9.0m/s Full Stroke : 17 m/s Test Drive Playback: Full speed MP3 playback at 320KBps. 测试时使用的是三星的 SV3064D 30 GB 硬盘 测试硬盘的平均时间: 轨迹到轨迹 : 0.8 m/s 平均 : 9.0m/s 完全的读取 : 17 m/s 测试硬盘重放: 使用的是编码率高达320KBps的mp3. *********************************************/ #define DataReq PINB.2 #include <90s8515.h> //8515 header file #include //Codevision spi #include "zfat.h" #include "zata.h" #include "ztype.h" #include "zcontrol.h" #include "zlcd.h" #include //Codevision delay #include "i2c.h" //下面是按照Datazyb所提示而添加进的。添加这些包含后就能顺利的编译了。 //编译好了的程序能读取我的富士通3g的硬盘,但是出来的声音不流畅,可能示由于硬盘太老的缘故吧。 #include "zata.c" #include "zfat.c" #include "ztype.c" #include "zcontrol.c" #include "zlcd.c" #include "i2c.c" // External Interrupt 0 service routine // 外部中断 0个服务常式 //这里说明一下,这里是按钮输入的反应设置,也就是说当按钮按下zipmap要干些什么就是在这里设置的。 //情形(case)按照1,2,4,8...这样排列是照按键接口ad0,ad1...来的, interrupt [EXT_INT0] void ext_int0_isr(void) { unsigned char in; #asm("cli"); in=PINC; //Read the input buttons /读输入按钮 in=~in; //Invert them to see which one is high (thats the one pressed) /判断它们是哪一个按下了。 while ((!PIND.2)); //wait until interrupt key released /等候按纽松开了才输出 switch (in) { //Case 1= STOP /情形 1= 停止 case 1: //play=0 is pause, play=1 is play, play=2 is stop //播放=0 代表暂停, 播放=1 代表播放, 播放=2 代表停止 play=2; //STOP /停止 STAPlay(); //Stop player /停止播放器 UnBusy(); //Remove HD Busy light /使硬盘指示灯长亮 currentCluster=firstCluster; //Remember file start cluster /记忆文件开始群 clusterBufferReadPos=clusterBufferWritePos; //Clear cluster buffer /清除群缓冲 filePos=0; //Set filestart pos at beginning sectorPos=0; mp3Pos=0; break; //Case 2= Play or Pause /情形 2= 播放或暂停 case 2: play=(~play) & 1; //Invert play. If play then pause, if pause then play //反转播放.如果是播放就暂停,如果暂停就播放 STAPlay(); //Load command /读取命令 break; //Case 4= case 4: if (currentFileNum<=1) currentFileNum=totalFiles-1; else currentFileNum=currentFileNum-2; dirReadOffset.fileNum=0; //To reread dir from start. break; case 8: currentFileNum+=advance; //FF if (currentFileNum>totalFiles) { currentFileNum=1; dirReadOffset.fileNum=0; } break; case 16: filePos=FileSize; //NEXT break; case 32: //声音模式设置 soundMode = (soundMode+1) & soundModeMask; SetBassTreble(); break; case 64: playMode = (playMode+1) & playModeMask; //播放模式设定 break; }; intFlag=1; //Set interrupt occured flag /设置中断发生情况 } /* // External Interrupt 1 service routine / 外部中断 1个服务常式 interrupt [EXT_INT1] void ext_int1_isr(void) { // Place your code here // 把你的代码放到这里,实际上在zipamp里这里可以不用理会,因为它的中断1口根本就没有接东西上去 //不过你如果想添加遥控的话,把代码放到这里是再合适不过的了。 printf("Entered Interrupt 2"); } */ // Declare your global variables here //全局变量在这里 void main(void) { // Declare your local variables here byte temp; dword extension; //这些设置要结合硬件电路图才能看得明白。 // Input/Output Ports initialization /设定输入输出口初始值。 // Port A /PA口 DDRA=0x00; //Start as Input port /开始为输入口 PORTA=0x00; //Set to High-Z state /设定为高阻状态 // Port B /PA口 DDRB=0xBB; PORTB=0x0B; //Enable Reset for STA013, Disable ATA IOR and IOW. /允许重启STA013, 禁止ATA IOR与IOW. // Port C /PA口 DDRC=0xFF; //Output port /输出口 PORTC=0x00; //Set 0 /设定 0 // Port D /PA口 DDRD=0xF2; PORTD=0x20; //Disable Latch and Buffer. Never pull PORTD.1 high, that will cause damage to STA013 //使门电路和缓冲器失去能力。千万别拉高“PORTD.1”(这里注释可能有误,应该为PORTD.0)那样做会损坏到STA013 //这些设置要结合90s8515的说明书才会明白 // Timer/Counter 0 initialization / 定时/计数器0初始值设定 // Clock source: System Clock / 时钟来源: 系统时钟 // Clock value: Timer 0 Stopped / 时钟值: 时钟0停止 // Mode: Output Compare / 模式: 输出比较 // OC0 output: Disconnected / OC0 输出: 分离 TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization / 定时/计数器1初始值设定 // Clock source: System Clock / 时钟来源: 系统时钟 // Clock value: 14318.180 kHz / 时钟值: 14318.180 kHz // Mode: Output Compare / 模式: 输出比较 // OC1A output: Discon. / OC1A 输出: 不精读. // OC1B output: Discon. / OC1B 输出: 不精读. // Noise Canceler: Off / 噪音取消: 关 // Input Capture on Falling Edge / 输入取下下降沿 TCCR1A=0x00; TCCR1B=0x01; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization /设定外部(s)初始值 // INT0: On /INT0: 开 // INT0 Mode: Low level /INT0 模式: 低电平有效 // INT1: On /INT1: 开 // INT1 Mode: Low level /INT1 模式: 低电平有效 GIMSK=0x40; MCUCR=0x00; GIFR=0x40; // Timer(s)/Counter(s) Interrupt(s) initialization /设定定时(s)/计数器(s)中断(s)初始值 TIMSK=0x00; // UART initialization /串口初始值设定 // Communication Parameters: 8 Data, 1 Stop, No Parity /沟通叁数: 8 数据,1个停止,没有同等 // UART Receiver: Off /串口接收器(rx):开 // UART Transmitter: On /串口发射器(tx):关 // UART Baud rate: 19200 at 14.3181 /串口通讯波特率: 19200到14.3181之间 UCR=0x08; UBRR=0x2E; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; // SPI initialization // SPI Type: Master // SPI Clock Rate: 2460.000 kHz // SPI Clock Phase: Cycle Half // SPI Clock Polarity: Low // SPI Data Order: MSB First // SPI 初始值设定 // SPI 类型: Master // SPI 时钟频率: 2460.000 kHz // SPI 时钟周期: 一半 // SPI 时钟极性: 低 // SPI 数据次序: MSB第一 SPCR=0x50; #asm("cli"); //好了,设置好8515各个端口的初始之后,我们要开始干正事了,先初始化lcd屏,然后延时3000ms,这是为了在 //屏上显示logo InitLCD(); delay_ms(3000); //DDRC=0x00; //PORTC=0x00; //接下来就初始话ata与fta ATA_Init(); InitFAT(); currentFileNum=0; temp=0; //Find two required files in root dir ZIPAMP.SYS and ZIPAMP.CFG and save their LBA address //查找两个必须的文件ZIPAMP.SYS和ZIPAMP.CFG并保存它们的LBA地址 while ((temp<2)&&(getDirEntry(0)==1))>=FileSize) SongSelect(); //Song is selected when playing finished or NEXT/PREV button pressed ///当歌曲在播放的时候被按下了NEXT或PREV按纽时 if (intFlag) { //Interrupt occured and LCD display wasn't fixed, fix it. intFlag=0; printInfo(); } while ((DataReq)&&(filePos
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:30:00 | 显示全部楼层
i2c.c /* Copyright 2003 Nasif Akand (nasif@yifan.net) http://go.to/zipamp http://zipamp.virtualave.net This file is part of ZipAmp MP3 software. ZipAmp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ZipAmp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this code; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 这一个文件是 ZipAmp MP3 软件的一部份。 ZipAmp 是免费的软件;你能重新分配它及[或] 修正 它在角马公众执照的术语之下当做出版被 免费的软件基础; 或执照的 2 版,或 (在你的选项)任何的较迟版本。 ZipAmp 在希望中被分配它将会是有用的, 但是没有任何的担保; 没有更甚至被暗示的担保 为一个特别的目的 MERCHANTABILITY 或健身。 那 为较多的细节角马公众执照。 你应该要接受角马公众执照的副本 连同这一个密码一起; 如果不,写到免费的软件 基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国 */ //This module performs I2C operations for ZipAmp /这是zipamp的i2c程序组件 //Nasif Akand //If using CodeVision then following includes aren't needed. /如果使用 CodeVision 不需要包括下列各项 //#include "zcontrol.h" //#include "zfat.h" //#include "zata.h" //#include "ztype.h" #include "i2c.h" //#include "" //CodeVision AVR internal delay routines /CodeVision AVR 内在的延迟常式 //I2C implementation for STA013 通过i2c控制sta013 //Port D bit 7 (pin 17) is SDA output while bit 0 (pin 10) is input, Pin 16 is SCL //SDA input is always at HighZ state. If this pin is pulled up or output high, STA013 will be damaged. //这里是定意的i2c sda数据的输入输出口,输出为17脚,输入为10脚,时钟信号scl为16脚。 #define SDA PORTD.7 #define SCL PORTD.6 #define SDAIn PIND.0 #define Out DDRD.7=1 #define In DDRD.7=0 #define qDelay delay_us(3) //According to Phillips I2C specs in all modes.. /这里是按照菲利普i2c总线模式写的 #define delay delay_us(3) //..max I2C delay can be 5 micro seconds. /最大 I2C 延迟可能是 5个微秒。 #define Read 0x87 //STA013 I2C Read address /STA013 I2C 读取地址 #define Write 0x86 //STA013 I2C Write Address /STA013 I2C 写入地址 //下面这段函数是复位sta013 void STA013Reset() { DDRB.3=1; //Set bit3 to Output mode /设置pb3为输出状态 PORTB.3=0; //Set to 0 for reset /这里可以参看原理图就明白。pb3是连在sta013的26脚/reset上的. delay_ms(500); //Wait PORTB.3=1; //Set to 1 delay_ms(500); //Wait } //下面这段数据类型声明是用来测试i2c是否有正确应答,如果有就输出0则表示成功 unsigned char wait_Ack (void) { //returns 1 if ACK was 0 (meaning transfer was successful). In I2C ACK=0 means success. unsigned char t=1; delay; // Take clock high SCL=1; delay; // Test of ACK delay; if (PIND.0) { /*test of SDA level, if high -> problem*/ t=0; } delay; if (PIND.0) { /*test of SDA level, if high -> problem*/ t=0; } // Take clock back low delay; SCL=0; delay; return t; } //数据声明,声明i2c的阅读地址 adr为地址的缩写 unsigned char i2cReadAddress(unsigned char adr) { //Returns data read from register given in adr./从寄存器中读取数据后返回 //In most cases we don't have to worry about it. If we don't get ACK, try 10 times before giving up. //在大部分的情况下,我们不需要为它担忧,在拿不到正确的应答之前要尝试十次。 unsigned char data, try=0, ack; do { i2cStart(); //I2c start /i2c开始 ack=i2cSend(Write); //Send i2c write address /发送i2c写入地址 ack &=i2cSend(adr); //Send register address /发送记录地址 i2cStart(); //i2c re-start delay; //wait ack &= i2cSend(Read); //Send i2c read address data=i2cReceive(0); //Receive data without sending ACK i2cStop(); //Stop try++; } while ((ack==0)&&(try<10)); //try 10 times if failed /尝试10次后返回 return data; } //数据声明,声明i2c的写入地址。这段和上面一段类似只不过由读变成了写 unsigned char i2cWriteAddress(unsigned char adr, unsigned char data) { // Writes data to register adr. //Returns 1 on successful write, tries 10 times before giving up. unsigned char ack,try=0; do { i2cStart(); //Start ack = i2cSend(Write); //Send i2c write address ack &= i2cSend(adr); //Send register address delay; //wait ack &= i2cSend(data); //Send data i2cStop(); //Stop try++; } while ((ack==0)&&(try<10)); //give up after 10 tries return ack; } //这段函数是初始化i2c void i2cInit() { DDRD.7=1; //Set to output mode for SDA DDRD.6=1; //Set to output mode for SCL } //下面这段函数是i2c开始的必要条件 void i2cStart() { //I2C start condition. DDRD.7=1; //SDA output mode SDA=1; delay; SCL=1; delay; SDA=0; delay; SCL=0; } //数据声明,发送i2c数据到sta013后返回,成功为1,失败为0,这里发送的字节不大,一次为8个2进制数据,也就是1bit unsigned char i2cSend(unsigned char value){ //Sends byte value, and returs ACK from STA013, 1=Success, 0=Fail unsigned char i; DDRD.7=1; for (i=0; i<8; i++) { DDRD.7=1; if (((value >> (7-i)) & 0x01)==0x01) SDA=1; //Send bit by bit else SDA=0; SCL=1; delay; SCL=0; DDRD.7=1; SDA=1; delay; } delay; i=wait_Ack(); return i; } //数据声明,和上面的声明类似,不过变成了接收。 unsigned char i2cReceive(unsigned char ack) { //Receives data byte. Sends back acknoledge if ack is true unsigned char value=0,i; DDRD.7=1; SDA=1; for (i=0; i<8; i++) { delay; SCL=1; delay; value = (value << 1) + PIND.0; //leftshift previous value and add one more bit that's read delay; SCL=0; } if (ack) { //send ack if requested DDRD.7=1; SDA=0; delay; SCL=1; delay; SCL=0; } return value; } //此函数是i2c停止的条件 void i2cStop(){ //I2C stop condition. delay; DDRD.7=1; //SDA output mode SDA=0; delay; SCL=1; delay; SDA=1; delay; }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:30:00 | 显示全部楼层
i2c.h
/*
    Copyright 2003 Nasif Akand (nasif@yifan.net)
    http://go.to/zipamp
    http://zipamp.virtualave.net
    This file is part of ZipAmp MP3 software.
    ZipAmp is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    ZipAmp is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this code; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       这一个文件是 ZipAmp MP3 软件的一部份。
      ZipAmp 是免费的软件;你能重新分配它及[或] 修正
      它在角马公众执照的术语之下当做出版被
      免费的软件基础; 或执照的 2 版,或
      (在你的选项)任何的较迟版本。
      ZipAmp 在希望中被分配它将会是有用的,
      但是没有任何的担保; 没有更甚至被暗示的担保
      为一个特别的目的 MERCHANTABILITY 或健身。  那
      为较多的细节角马公众执照。
      你应该要接受角马公众执照的副本
      连同这一个密码一起; 如果不,写到免费的软件
      基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国
*/
//This module performs I2C operations for ZipAmp /这是zipamp的i2c程序组件
//Nasif Akand
//I2C implementation for STA013 /用i2c来操控sta013
#ifndef __I2C_H__
#define __I2C_H__
unsigned char wait_Ack (void);
unsigned char i2cReadAddress(unsigned char adr);
unsigned char i2cWriteAddress(unsigned char adr, unsigned char data);
void i2cInit();
void i2cStart();
unsigned char i2cSend(unsigned char value);
unsigned char i2cReceive(unsigned char ack);
void i2cStop();
void STA013Reset();
#endif
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:31:00 | 显示全部楼层

zlcd.c
/*
Copyright 2003 Nasif Akand (nasif@yifan.net)
http://go.to/zipamp
http://zipamp.virtualave.net
This file is part of ZipAmp MP3 software.
ZipAmp is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ZipAmp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this code; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
这一个文件是 ZipAmp MP3 软件的一部份。
ZipAmp 是免费的软件;你能重新分配它及[或] 修正
它在角马公众执照的术语之下当做出版被
免费的软件基础; 或执照的 2 版,或
(在你的选项)任何的较迟版本。
ZipAmp 在希望中被分配它将会是有用的,
但是没有任何的担保; 没有更甚至被暗示的担保
为一个特别的目的 MERCHANTABILITY 或健身。 那
为较多的细节角马公众执照。
你应该要接受角马公众执照的副本
连同这一个密码一起; 如果不,写到免费的软件
基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国
*/
//This module performs LCD operations for ZipAmp /这是zipamp的lcd程序组件
//Nasif Akand
//If using CodeVision then following includes aren't needed.
//#include "zcontrol.h"
//#include "zfat.h"
//#include "zata.h"
//#include "ztype.h"
//#include "i2c.h"
//#include "" //CodeVision AVR internal delay routines
#include "zlcd.h"

#define clkDelay delay_us(2);
#define delayLong delay_us(40);
//下面两段函数是用来向液晶屏传输数据的。
/*此函数适用来设定lcd模式的,这里设定为并口4bits模式*/
void SetNibble(byte value) {
//Write data on 4 bits for LCD
OutMode;
PORTC.0= value & 0x01;
PORTC.1= (value >> 1) & 0x01;
PORTC.2= (value >> 2) & 0x01;
PORTC.3= (value >> 3) & 0x01;
}
//此函数的作用是向显示屏写数据,一般来说是写显示屏的控制命令
void WriteByte(byte value) {
//Writes byte, nibble at a time
SetNibble(value>>4);
EN=1;
clkDelay;
EN=0;
clkDelay;
SetNibble(value);
EN=1;
clkDelay;
EN=0;
clkDelay;
delay_us(40);
}
/*这里两段函数一段是读取lcd,cgram里的内容,另一段是检测lcd是否处于忙碌状态,
这里由于用不上,而且作者可能考虑到空间有限,所以省去了。
byte ReadByte() {
byte value;
InMode;
EN=0;
clkDelay;
EN=1;
value = GetNibble();
EN=0;
clkDelay;
EN=1;
value = (value<<4) + GetNibble();
}

void WaitTillLCDBusy() {
byte value;
do {
EN=1; //Start LCD command
RS=0; //Its a command
RW=1; //Its a command
value=ReadByte();
}
while ((value & 0x80)== 0x80); //Busy is bit 7 set
RW=0;
}*/

//此函数的作用是初始化lcd,初始化完毕后,输出logo
void InitLCD() {
//Initialize LCD, then print logo
byte i;
OutMode;
RS=0;
RW=0;
EN=0;
clkDelay;
EN=1;
SetNibble(2); //Set 4 bit mode
EN=0;
clkDelay;
delayLong;
WriteByte(0x28); //Function Set
LCDclrscr(); //clearscreen
WriteByte(0x0C); //display on, cursor off /显示开,关闭光标
WriteByte(0x40); //Set CGram addres; /设定cgrom地址
RS=1;
for(i=0;i<64;i++) WriteByte(cg); //load CGRAM characters
// for(i=0;i<8; i++) WriteByte(cgleftTop);
// for(i=0;i<8; i++) WriteByte(cgrightTop);
// for(i=0;i<8; i++) WriteByte(cgleftBottom);
// for(i=0;i<8; i++) WriteByte(cgrightBottom);
RS=0;

//Printing Logo /输出logo
LCDclrscr();
writechar(0);
for(i=0;i<10;i++) writechar('=');
writechar(1);
gotoxy(1,0); writechar('|');
gotoxy(1,11); writechar('|');
gotoxy(2,0);
writechar(2);
for(i=0;i<10;i++) writechar('=');
writechar(3);
gotoxy(1,3);
writestring("ZipAmp");
gotoxy(1,16);
writestring("v2.0"); //three space version info
gotoxy(2,12);
writestring("(c)Nasif");
gotoxy(3,1);
writestring("http://go.to/zipamp");
}
//这段函数的作用是载入声音图标到显示屏的cgram
void SetSoundCg() {
//Load sound bar graph CGRAM characters
byte i; RS=0; RW=0;
WriteByte(0x40); //Set CGram addres;
RS=1;
for(i=0;i<32;i++) WriteByte(soundCg); //load CGRAM characters 0..3
RS=0;
}
//此函数的作用是向lcd屏写入字符
void writechar(byte value) {
//Write 1 character
#asm("cli");
RS=1; RW=0; //EN=0;
WriteByte(value);
RS=0;
Hi_Z;
#asm("sei");
}

//此函数的作用是向lcd屏写入字符串,如果是汉字屏也可以用这段程序显示汉字。
void writestring(byte flash *strn) {
//Write a string from flash ROM
while (*strn!=0) writechar(*strn++);
}

//此函数的作用是,在lcd屏指定的位置上显示,可以是字符,也可以是数字,因为没有图画显示函数所以不能显示图画
void gotoxy(byte line, byte position) {
//Gotoxy function. X=line number, Y=character position
byte address;
OutMode;
RS=0;
RW=0;
address=0x80+lcdLineStart[line]+position;
WriteByte(address);
}

void LCDclrscr() {
//Clear LCD /清除lcd
OutMode;
RS=0; RW=0;
WriteByte(0x01);
delay_ms(2);
}
void writeNumber(word value) {
//Write a decimal number on LCD /在lcd上写一个10进位的数字
//因为在统计mp3的时候是按十六进制统计的,所以需要进行一次变换,于是就用到了此函数。
byte temp[8],i=0;
do {
temp[i++]=value%10;
value=value/10;
}
while (value>0);
for(;i>0;) writechar(temp[--i]+48); //start from back and print the number
}
//这个函数是用于显示播放图标的
void blink() {
//Setup curson blink, based on player state
#asm("cli");
OutMode;
RS=0;
RW=0;
WriteByte(0x0C + (play & 1)); //if Play = 1 blink on, if play=0 blink off
}
/*下面这三段函数还没有弄明白是什么意思,可能是用来画图的,猜测而已,还没有证实,zipmap里面也没有用到。
void clreol(byte line) {
// gotoxy(line,0);
spacer(line,0,20);
// gotoxy(line,0);
}
void spacer(byte x, byte y, byte value) {
byte i;
gotoxy(x,y);
for(i=0;i

*/

#endif

[此贴子已经被作者于2005-10-19 9:30:50编辑过]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:34:00 | 显示全部楼层
zlcd.h
/*
    Copyright 2003 Nasif Akand (nasif@yifan.net)
    http://go.to/zipamp
    http://zipamp.virtualave.net
    This file is part of ZipAmp MP3 software.
    ZipAmp is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    ZipAmp is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this code; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    这一个文件是 ZipAmp MP3 软件的一部份。
      ZipAmp 是免费的软件;你能重新分配它及[或] 修正
      它在角马公众执照的术语之下当做出版被
      免费的软件基础; 或执照的 2 版,或
      (在你的选项)任何的较迟版本。
      ZipAmp 在希望中被分配它将会是有用的,
      但是没有任何的担保; 没有更甚至被暗示的担保
      为一个特别的目的 MERCHANTABILITY 或健身。  那
      为较多的细节角马公众执照。
      你应该要接受角马公众执照的副本
      连同这一个密码一起; 如果不,写到免费的软件
      基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国
*/
//This module performs LCD operations for ZipAmp /这是zipamp的lcd程序组件
//Nasif Akand
#ifndef __LCD_H__
#define __LCD_H__

/* change these definitions to adapt setting
改变这些设定可以让它适应不同档的液晶显示模块
实际上这里起的作用并不大,还要在程序里面再更改显示地址才行。*/
#define LCD_LINES           2     /* visible lines /这里应该是行数如果是128×64的屏的话这里要设置为4*/
#define LCD_LINE_LENGTH  0x40     /* internal line length /这里是显示的字数如果是128×64的屏的话这里要设置为0x16*/
#define EN PORTB.4
#define RS PORTC.5
#define RW PORTC.4
#define OutMode DDRC=0xFF //To send data to LCD /送数据给 LCD
#define InMode DDRC=0xF0 //To read data from LCD /读来自 LCD 的数据
#define Hi_Z DDRC=0  //Leave port at hi-z stat
#define LCD PORTC  //LCD data port
//Port setup: 接口设定
//D4=PORTC0, D5=PORTC1, D6=PORTC2, D7=PORTC3
//R/W=PORTC4, RS=PORTC5, E=PORTB4

//void  WaitTillLCDBusy();
//byte  ReadByte();
void  writechar(byte value);
void  writestring(byte flash *strn);
void  gotoxy(byte x, byte y);
void InitLCD();
void    LCDclrscr();
void    writeNumber(word value);
void blink();
void  WriteByte(byte value);
//void  clreol(byte line);
//void    spacer(byte x, byte y, byte value);
void  SetSoundCg();
#endif
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-2 22:35:00 | 显示全部楼层
ztype.h

/*********************************************
ZipAmp
作者     : Nasif Akand                     
版权         : (C) Nasif Akand 2003
Notice  :
  Copyright 2003 Nasif Akand (nasif@yifan.net)
  http://go.to/zipamp
  http://zipamp.virtualave.net
      这一个文件是 ZipAmp MP3 软件的一部份。
      ZipAmp 是免费的软件;你能重新分配它及[或] 修正
      它在角马公众执照的术语之下当做出版被
      免费的软件基础; 或执照的 2 版,或
      (在你的选项)任何的较迟版本。
      ZipAmp 在希望中被分配它将会是有用的,
      但是没有任何的担保; 没有更甚至被暗示的担保
      为一个特别的目的 MERCHANTABILITY 或健身。  那
      为较多的细节角马公众执照。
      你应该要接受角马公众执照的副本
      连同这一个密码一起; 如果不,写到免费的软件
      基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国
*/
/*这里的作用是存放显示和sta013的数据的,用来放在AT90S8515的eeprom中的,
包含了八种声音模式的显示和设定数据,以及播放状态的显示数据*/
#ifndef __ZTYPE_H__
#define __ZTYPE_H__
typedef unsigned char   byte;
typedef unsigned int   word;
typedef unsigned long int  dword;

#define false   0;
#define true    1;
#define playModeMask  1; //# of avialable play modes 0, 1 /包含两种播放模式 0, 1
#define soundModeMask  7; //# of available sound modes 0, 1, 2, 3, 4, 5, 6, 7 /包含八种声音模式 0...

        
        dword  filePos=0; //holds offset of file read. /记录被读文件的播放位置           
            
//        byte  sectorPos=0; //# of sectors read for a file, reset to 0 when reaches cluster size
     
byte  play;  // When set, Player will stop playing. 暂停或开始
byte  intFlag=0; // Set 1, after Interrupt Routine executed.
byte  playMode=0; // Playback mode, cycles through cont, random, repeat, program ./5种播放模式
word  totalFiles=0; // Total number of files in drive./硬盘上的文件总数

byte  mp3Pos=0; // MP3 send pos. Reset to 0 when reaches 256 (reaches the sector Buffer size)/预读mp3文件到缓冲,文件大小为0-256


byte   clusterBufferReadPos; // Current read pos of circular cluster buffer 读pos
byte  clusterBufferWritePos;// Current write pos of circular cluster buffer 写pos
byte  headMoved;       // when set head was moved for current read. 这个设置是为了使磁头移动到当前读取的位置

//Bass and FF
// byte  bass=0;              // sets bass
// byte  treble=0;       // sets treble
byte  soundMode=0;
byte  key;  // input keys for control 输入键控制
//eeprom dword  HDSerialNumber=0;
//eeprom byte    attenuation=10;       // Sound attenuation factor
//eeprom byte    bassFreq[2]={100,0}; // data for lower, upper register of Bass Enhance
//eeprom byte    bassEnhance=0x0C;    // Set at
//eeprom byte    trebleFreq[2]={0x58,0x1B}; // data for lower, upper registre of Treble Enhance
//eeprom byte    trebleEnhance=0x06;
eeprom byte  dash[3]={' ','-',' '};   // String " - ". Used for printing - in ID3 tag Signer - Title
/*这里是用来设置id3标签歌名与演唱者之间那个“-”号的,如果是中文显示屏这个符号一定要用两个半角“--”代替,
否则会显示乱码。 */
             //0x77 0x78 0x79 0x7A 0x7B 0x7C     
//eeprom byte lcdSetup[4]={0x28,1,0x0C,0x40};
eeprom byte lcdLineStart[4]={0,0x40,0x14,0x54}; // Supports 4 line, current setting for 20*4
//这里是设置行的起始位置,128×64的中文显示屏的每行起始显示应该是{0x80,0x90,0x88,0x98}   
eeprom byte soundCg[32] = { //Different sound mode bar graph characters. /不同声音模式的曲线图.
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,      
    0b00000000,
    0b00001110,
    0b00011111,
    0b00011111,
   
    0b00000000,
    0b00000000,
    0b00000000,
    0b00001110,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
   
    0b00000000,
    0b00001110,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
   
    0b00001110,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111,
    0b00011111                                                                                                
                                             
};                                       

eeprom byte cg[64]= {       // Characters for CGRAM of LCD
    // Lefttop, righttop, leftbottom, rightbottom are for
    // boot up display. These 4 are overwritten with soundCg array
    // after bootup.
    //这里是播放模式和开机logo的图标设置
    0b00000000,
    0b00000000,
    0b00001111,
    0b00001000,       //lefttop /logo的左上角
    0b00001011,
    0b00001010,
    0b00001010,
    0b00001010,

   
    0b00000000,
    0b00000000,
    0b00011110,
    0b00000010,       //righttop /logo的右上角
    0b00011010,
    0b00001010,
    0b00001010,
    0b00001010,

    0b00001010,
    0b00001010,
    0b00001011,
    0b00001000,       //leftbottom /logo的左下脚
    0b00001111,
    0b00000000,
    0b00000000,
    0b00000000,

    0b00001010,
    0b00001010,
    0b00011010,       //rightbottom /logo的右下角
    0b00000010,
    0b00011110,
    0b00000000,
    0b00000000,
    0b00000000,
    0b00001000,
    0b00001100,
    0b00001110,       //Play character /播放图标
    0b00001111,
    0b00001110,
    0b00001100,
    0b00001000,
    0b00000000,

    0b00011011,
    0b00011011,
    0b00011011,       //Pause character /暂停图标
    0b00011011,
    0b00011011,
    0b00011011,
    0b00011011,
    0b00000000,

    0b00000000,
    0b00010001,
    0b00001110,       // Bass Boost. Not used in version 2.x /重低音,不使用在2.x上
    0b00001010,
    0b00001110,
    0b00010001,
    0b00000000,
    0b00000000,
   
    0b00001110,
    0b00010001,
    0b00010000,       // Repeat /重复
    0b00010100,
    0b00010010,
    0b00001111,
    0b00000010,
    0b00000100
    };
//这下面的两段弄不明白意思。望高手翻译后告之。   
// Following is file name invalid characters table. Invalid chars are defined by MS. File is
// disregarded if one of these characters are found in name. Used in get Dir Entry function
eeprom byte invalidFileChars[47] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06,
          0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
          0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
          0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
          0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
          0x1F, 0x22, 0x2A, 0x2B, 0x2C, 0x2E,
          0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
          0x3F, 0x5B, 0x5C, 0x5D, 0x7C };
         
// Long file name byte offset table. It is used to select 13 characters of file name
// in each Long File Entry of directory table. Each entry in LFN is word wide, but
// we look in low byte only for ASCII char. This table is used in get Dir Entry function                        
//      PART1        PART2             PART3
eeprom byte longNameOffset[13] = {1,3,5,7,9,  14,16,18,20,22,24,  28,30};
// Character table for displaying play mode on LCD
//显示播放模式图标到lcd
eeprom byte PlayModeDisplayStrTable[4,4]={'-','-',0x7E,0,  //prints -->
       0x7E,'R',0x7F,0, //prints >R<
       'R','E','P',0,
       'D','I','R',0};   
// ERROR Strings 错误显示
eeprom byte ErrStr[8,21] = {  {"Error Detecteded :-("},
    {"Sector Read Error!"},
    {"Sector Write Error!"},
    {"FAT16 Not Supported!"},
    {"Missing SYS or CFG!"},
    {"Missing STA013.BIN!"},
    {"STA013 Not Found!"},
    {"STA013 Load Failed!"}
                           };

// This 8x4 array stores CGRAM char value to be displayed for corresponding sound Mode value
// It is organized in order of BassTrebleTable
//这里8组数字是声音模式显示的位置值
eeprom byte  SoundModeDisplay[8,4] = {
       1,1,1,1, //Normal
       3,1,1,3, //HiBs, HiTrbl
       1,2,2,1, //Hi vocal
       1,0,0,1, //LowBs, LowTrbl, LowVocal
       3,2,1,0, //HiBs, LowTrbl
       0,1,2,3, //HiTrbl, LowBs
       0,1,3,1, //HiMidTrbl, lowMidBs
       1,3,1,0  //HiMidBs, LowMidTrbl
      };

// This 8x6 array stores STA013 addresses for bass treble configruation for different sound modes.
//这8组数据是8种声音模式相对应的sta013的设置。
eeprom byte  BassTrebleTable[8,6]= { // TRLow TRHigh BSLow BSHigh TEhnc BSEnhc         
               0x40, 0x1F, 70, 0, 0x00, 0x00,  // Normal
               0x58, 0x1B, 100, 0, 0x06, 0x0C, // HiBS, HiTrbl
               0xE8, 0x03, 0x58, 0x02, 0x06, 0x09, // HiVocal
               0x58, 0x1B, 100, 0, 0xF7, 0xF7, // LowBS, LowTrbl, LowVocal
               0x58, 0x1B,   70,     0,      0xF7,   0x0C, // HiBs, LowTrbl
               0x58, 0x1B,   70,     0,      0x06,   0xF7, // LowBs, HiTrbl
               0xE8, 0x03,   0x58,   0x02,   0x06,   0xF7, // LowMidBS, HiMidTrbl
               0xE8, 0x03,   0x58,   0x02,   0xF7,   0x06 // HiMidBS, LowMidTrbl
           };
           
eeprom byte  advance=1;       // advance used for quick jumps  快速跳跃前进
#endif
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-9 11:31:00 | 显示全部楼层

再发两段,zcontrol.h

/*
Copyright 2003 Nasif Akand (nasif@yifan.net)
http://go.to/zipamp
http://zipamp.virtualave.net

This file is part of ZipAmp MP3 software.

ZipAmp is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

ZipAmp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this code; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
这一个文件是 ZipAmp MP3 软件的一部份。

ZipAmp 是免费的软件;你能重新分配它及[或] 修正
它在角马公众执照的术语之下当做出版被
免费的软件基础; 或执照的 2 版,或
(在你的选项)任何的较迟版本。

ZipAmp 在希望中被分配它将会是有用的,
但是没有任何的担保; 没有更甚至被暗示的担保
为一个特别的目的 MERCHANTABILITY 或健身。 那
为较多的细节角马公众执照。

你应该要接受角马公众执照的副本
连同这一个密码一起; 如果不,写到免费的软件
基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国

*/

//This module performs different control operation for ZipAmp /这是zipamp的控制程序组件
//Nasif Akand


//#include "ztype.h"
#ifndef __ZCONTROL_H__
#define __ZCONTROL_H__

#define TPE1 0x54504531 //ID3V2 Tags /ID3V2标签
#define TIT2 0x54495432

void readFile(word wordToRead); //读取文件
void STA013Setup(); //重启或复位sta013
void STAPlay(); //播放或停止mp3使之在STA013上重放
byte writeClusterBuffer(); //填满循环的簇缓冲区,在clusterBuffer.cluster写上在当前文件chain中的下个簇的地址.
byte readClusterBuffer(); //如果簇缓冲器不是空的话,读取下一个簇,成功返回1,失败返回0,返回的簇地址依然是当前的簇地址
void read(); //一次读256字节,它仅仅用簇缓冲来回放MP3文件
word randomKey(); //这段函数是用来产生一个从0到总文件数之间的随机数的。
void SongSelect(); //这个函数的作用是查找MP3文件基于当前的播放状态
void SetBassTreble(); //这个函数是用来设置重低音的。
void Halt(byte errorCode); //如果发生错误,停止ZipAmp,输出错误信息后进入死循环
void printFileName(); //输出文件名在lcd屏上
void printInfo(); //输出其它信息在lcd屏上。

#endif

回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-9 11:32:00 | 显示全部楼层

zcontrol.c

/*
Copyright 2003 Nasif Akand (nasif@yifan.net)
http://go.to/zipamp
http://zipamp.virtualave.net

This file is part of ZipAmp MP3 software.

ZipAmp is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

ZipAmp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this code; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
这一个文件是 ZipAmp MP3 软件的一部份。

ZipAmp 是免费的软件;你能重新分配它及[或] 修正
它在角马公众执照的术语之下当做出版被
免费的软件基础; 或执照的 2 版,或
(在你的选项)任何的较迟版本。

ZipAmp 在希望中被分配它将会是有用的,
但是没有任何的担保; 没有更甚至被暗示的担保
为一个特别的目的 MERCHANTABILITY 或健身。 那
为较多的细节角马公众执照。

你应该要接受角马公众执照的副本
连同这一个密码一起; 如果不,写到免费的软件
基础,公司, 59个寺庙地方,随员 330 ,波士顿,文学硕士 02111-1307 美国

*/

//This module performs different control operation for ZipAmp /这是zipamp的控制程序组件
//Nasif Akand

//If using CodeVision then following includes aren't needed.
#include "zcontrol.h"
//#include "zfat.h"
//#include "zata.h"
//#include "ztype.h"
//#include "i2c.h"
//#include "<delay.h>" //CodeVision AVR internal delay routines


// mask for cyclic buffer of cluster Buffer, check zata.h for clustBuf size
#define clustBufMask ClusterBufSize-1


void readFile(word wordToRead){ //
// Reads the current file word by word, no cluster buffering, used for generic file reading
//一个一个字的读当前文件;没有簇缓冲,用于一般文件的读取;
if ((sectorPos==Sectors_Per_Cluster)) { // if whole cluster is already read then
currentCluster=findNextCluster(); // a new cluster must be read by looking into FAT
readPos=0; //当整个簇已经被读取,我们必须查FAT然后去读新的一簇
sectorPos=0;
}
ATA_Read_Sectors_LBA(clust2LBA(currentCluster)+sectorPos,wordToRead); // read # of words;
filePos += (wordToRead<<1); // filepos = filepos+ (wordtoread*2)
}


//这个程序跟上面的相似,但是一次读256字节,它仅仅用簇缓冲来回放MP3文件.
void read() {
// This function is similar to above but reads 256 bytes at a time
// It is only used with cluster buffering for MP3 playback.

// The code below has been repeated many times. A function was
// was not written because of speed considerations.
//下面的代码要被重复很多次,没有写函数是考虑到速度问题.
if (sectorPos==Sectors_Per_Cluster) { // Check if a cluster has been already read.
if (readClusterBuffer()!=1) { // If cluster buffer is empty.
currentCluster=findNextCluster(); // find next cluster
} //检查一个簇是否被读取,当簇缓冲空了后就找下个簇.
sectorPos=0; // reset parameters /复位配置;
readPos=0;
headMoved=0;
}
// if head wasn't moved when we reached at sector end then move head.
// That will happen when readPos and headMoved both are 0.
//当我们达到扇区的末尾而磁头没有移动,然后就移动磁头,这个将在readPos和headMove
//同时为0时发生.
if ((readPos|headMoved)==0) ATA_Move_Head(clust2LBA(currentCluster)+sectorPos);

ATA_Read(128); // Read 128 words /读128个字,256字节.
filePos += 256; // Increment file position. /增加filePos.
}


//填满循环的簇缓冲区,在clusterBuffer.cluster写上在当前文件chain中的下个簇的地址.
//如果缓冲成功,则返回1,否则如果缓冲区是满的话,就返回0
byte writeClusterBuffer() {
// Fills up the cyclic buffer of clusterBuffer
// Writes clusterBuffer.cluster with next cluster address of the current file chain
// Returns 1 if buffering was successful, otherwise 0 if buffer is already full.

dword tempClust;
if (((clusterBufferWritePos+1)& clustBufMask) != clusterBufferReadPos) { // if buffer is not full /缓冲区没有满
tempClust=currentCluster;
if (clusterBufferWritePos!=clusterBufferReadPos)
// If buffer is not empty then get the previous cluster from buffer to find Next cluster
//如果缓冲区没有空,然后就从缓冲区获取上个簇地址去找下个簇
currentCluster=clusterBuffer.cluster[(clusterBufferWritePos-1) & clustBufMask];

// findNextCluster function will looks at currentCluster
//找下个簇函数将要看看当前的簇
clusterBuffer.cluster[clusterBufferWritePos]=findNextCluster();

// increment buffer write pos and AND with mask
//增加缓冲的写位置,然后和 clustBufMask 相与.
clusterBufferWritePos = (clusterBufferWritePos+1) & clustBufMask;
currentCluster=tempClust;
return 1;
}
else return 0; // Buffer is full, can't buffer anymore
}

byte readClusterBuffer() {
// Reads next cluster from cluster buffer if it is not empty
// Returns 1 if success full, 0 if failed.
// Cluster address is returned in current Cluster.
//如果簇缓冲器不是空的话,读取下一个簇,成功返回1,失败返回0,返回的簇地址依然是当前的簇地址。
if (clusterBufferWritePos != clusterBufferReadPos) { // if not empty buffer /缓冲器如果不为空
currentCluster=clusterBuffer.cluster[clusterBufferReadPos];
clusterBufferReadPos = (clusterBufferReadPos+1) & clustBufMask;
return 1;
}
else return 0;
}

byte DecodeID3Frame(dword FrameStrVal,byte offset) {
// Decodes ID3v2 tag.
// This is very crude way to decode ID3 tags. It was done to fit the code in AVR 8515.
// This function only looks at first 256bytes of MP3 file for ID3v2 tags. If its not there
// then we are out of luck. Do not take this function as your guide to ID3 tag decoding.
// It was only written to decode TIT2 and TPE1 frames.
// FrameStrVal is value of ID3 frame name string in binary. e.g. TIT2 = 0x54495432
// offset is the storage offset in fileName string.
// Returns 0 if decoding failed, otherwise it returns the offset at fileName string.
//这一段程序的作用是解码ID3V2标签,可以借鉴一下,写一段读取ID3V1标签的程序。
byte i;
dword strn; // storage for binary ID3v2 frame name.
readPos=0; // need to read a sector, set readPos=0

// Read the first 256 bytes of MP3 file. This is where we will look for ID3v2 tag.
ATA_Read_Sectors_LBA(clust2LBA(currentCluster),128);

readPos=0;

while (readPos<220) {
// looks in first 256 bytes, we actually finish by 220 bytes so that we don't cross array
// boundary when we are doing following instructions in the loop.

if (sectorBuffer.data[readPos]=='T') // Check if its start of TIT2 or TPE1 frame
for(i=0; i<4; i++) strn=(strn<<8)+sectorBuffer.data[readPos+i]; // Load the bytes into strn for comparision

if (strn!=FrameStrVal) goto FAIL; // Check if its the frame that we are looking for
mp3Pos=sectorBuffer.data[readPos+7]; // mp3Pos is used to store Frame length
readPos += 11; // Increment readPos by frame record size (11 bytes) so we can start reading text data.
mp3Pos += offset; // Increment mp3Pos with offset so that we are ready to copy into fileName string.
while ((offset<41)&&(offset<mp3Pos)) { // If there is more space left in the string.
fileName[offset++]=sectorBuffer.data[readPos++];
}
offset--; // Decrement offset by 1
fileName[offset]=0; // Set last fileName char to NULL.
return offset; // finished reading frame, so retrn.

FAIL: // We reach here only if we didn't find the frame that we were looking for.
readPos++;
}
return 0; // We failed, so return 0. /失败,返回0
}


void SongSelect() {
// This function finds an MP3 file based on current play mode.
// Saves player status. Fixes the LCD display.
//这个函数的作用是查找MP3文件基于当前的播放状态
//保存播放状态,使之显示在lcd上。
byte offset,i=0;

if (playMode==1) { // If its Random mode. /如果播放方式为随机
dirReadOffset.fileNum=0;
currentFileNum=randomKey(); // get random file number /获取随机文件数
}


if (getDirEntry(1)!=0) { // get an MP3 file. /获取mp3文件

offset=DecodeID3Frame(TPE1,0); // Decode frame TPE1, and store in fileName offset 0
i=0;
// If we found TPE1 then put " - " character.
if (offset>0) while((offset<41)&&(i<3)) fileName[offset++]=dash[i++];
DecodeID3Frame(TIT2,offset); // Decode frame TIT2, and store in fileName offset position.

saveConfig(); // Save the ZipAmp status in hard drive. /保存ZipAmp状态到硬盘里
firstCluster=currentCluster; // Remember the starting cluster of the file. /记得文件的起始簇
clusterBufferReadPos=0; clusterBufferWritePos=0; // Clear cluster buffer /清除簇缓冲器
while (writeClusterBuffer()!=0); // Now Fill up the cluster buffer. /现在填冲簇缓冲器

UnBusy(); // Clear the busy led /清除忙碌指示灯
filePos=0; // Reset all parameters /复位所有参数。
readPos=0;
sectorPos=0;
mp3Pos=0;

printFileName(); // Print file name on LCD /输出文件名到lcd显示屏上
printInfo(); // Print other information /输出其它的信息在lcd上。
intFlag=0; // LCD fixed, so clear interrupt flag. /固定lcd,清除中断标志。
}

gotoxy(0,19); // Put the LCD cursor on position of play/stop character.
//播放/暂停标志在lcd上的放置位置
}

void STA013Setup() {
// Sets up STA013 after initial power up or reset.
//重启或复位sta013

byte success; byte i;
dword extension;

// Setup STA013 /设置sta013
STA013Reset(); // Give reset pulse to STA013 /复位STA013
i2cInit();
if (i2cReadAddress(1)!=0xAC) { // Check if STA013 is there /检查sta013是否存在
Halt(6); // STA013 decoder not found.
}

success=0;
currentFileNum=0;

do { // Find STA013.BIN /查找STA013.BIN

if (getDirEntry(0)==0) Halt(5); // root directory finished and STA013.BIN not found. Generate error.
extension=0; //在根目录里面查找STA013.BIN文件,如果没有就输出错误
for(i=0; i<3; i++) extension=(extension<<8)+fileExtension; // Load extension chars into dword variable

//下面的函数是用来查找STA013.BIN文件的,查找成功后返回1失败返回0
// If extension is BIN and fileName starts with either 's' or 'S',
// then we assume filename is STA013.BIN. Whole filename comparision will take
// lot of code, therefore this assumption is made. User therefore must
// not save any other file that is BIN and starts with S.
if ((extension==0x0042494E)&& //if it is 0BIN
((fileName[0] & 0x53)==0x53)) // 'S' & 's' == 'S'

success=1; // we found STA013.BIN
}
while ((success==0));

success=0;
readPos=0; // reset to read start of STA013.BIN /这里两句的大楷意思就是复位读取和扇区计数器读取STA013.BIN
sectorPos=0; // reset sector position to begin reading for start;

do { // Load STA013.BIN 、读取STA013.BIN
readFile(1); // Read 1 word, 1st byte is I2C address, 2nd byte is data. /读取一个字,第一字节是i2c地址,第2字节是数据
i2cInit();
success = i2cWriteAddress(sectorBuffer.data[0],sectorBuffer.data[1]);
}
while ((filePos<FileSize)&&(success==1));

// Load failed. Generate error. /载入失败,输出错误
if (success==0) Halt(7);

i2cInit();

i2cWriteAddress(0x7D,11); // Set tone attenuation level -16.5dB. /衰减-16.5dB,这个是必要的,否则会出现破音。
// This is required. Otherwise sound will crack when we do bass/treble boost.
i2cWriteAddress(0x72,1); // Run, (its not play) /运行,这个不是播放。

}

void SetBassTreble() {
//这个函数是用来设置重低音的。
// Sets the STA013 bass treble registers depending on soundMode.
// Loads the pre-defined bass/treble values from BassTrebleTable array (look at ztype.h)

byte i;
for(i=0;i<6;i++)
// Bass treble I2C address starts at 0x77
i2cWriteAddress(i+0x77,BassTrebleTable[soundMode,i]);

}


void STAPlay() {
// Play/Stop MP3 playback on STA013./播放或停止mp3使之在STA013上重放
i2cInit();
i2cWriteAddress(0x13,(play & 1));
}

word randomKey() {
// Generate random number between 0 to totalFiles-1
// Uses 16 bit timer/counter for random number.
// Random number is found by moding 16 bit counter TCNT1 with totalFiles.
//这段函数是用来产生一个从0到总文件数之间的随机数的。
word temp;
temp = TCNT1H;
temp = (temp<<8) + TCNT1L;
return (temp % totalFiles);
}

void printError(byte errorCode) {
// Print error based on errorCode on LCD from ErrStr array (look at ztype.h)
//基于errorCode的信息输出错误信息在lcd屏上,可以参看ztype.h
byte i=0;
while (ErrStr[errorCode,i]!=0) writechar(ErrStr[errorCode,i++]);
}

void Halt(byte errorCode) {
// Halt ZipAmp if error was encountered. /如果发生错误,停止ZipAmp,输出错误信息后进入死循环
LCDclrscr();
printError(0); // Print first line of error
printError(errorCode);// Print the error line
while(1); // Infinite loop.
}

void printFileName() {
// Print file name on LCD /输出文件名在lcd屏上。

byte i=0;
LCDclrscr();

gotoxy(1,0);
while((fileName!=0)&&(fileName!='.')) {
if (i==20) gotoxy(2,0);
writechar(fileName[i++]);
}
gotoxy(3,0);
for (i=1; i<dirString[0]; i++) writechar(dirString);

}

void printInfo() {
// Print other info on LCD. /输出其它信息在lcd屏上。
byte i;

// Display fileNumber /显示文件数目
gotoxy(0,0);
for(i=0;i<9;i++) writechar(' ');
gotoxy(0,0);
writeNumber(currentFileNum); //当前的文件数
writechar('/');
writeNumber(totalFiles); //总文件数

gotoxy(0,10); // Fix LCD display for sound mode /在lcd屏的固定位置上显示声音模式
for(i=0;i<4;i++)
writechar(SoundModeDisplay[soundMode,i]);

// Diplay play mode characters /显示播放模式的符号
writechar(' ');
for (i=0; i<3; i++) writechar(PlayModeDisplayStrTable[playMode,i]);
writechar(' ');

// Display stop/play/pause characters /显示播放、停止、暂停的符号
if (play==2) writechar(255); // player stopped /播放器停止。
else writechar(5-play);
blink();
gotoxy(0,19);
}

// End of zcontrol.h

回复 支持 反对

使用道具 举报

发表于 2011-5-12 11:06:00 | 显示全部楼层

THX

感谢分享

回复 支持 反对

使用道具 举报

发表于 2016-6-1 09:20:34 | 显示全部楼层
真是好东西,顶啊!
回复 支持 反对

使用道具 举报

发表于 2016-6-10 10:10:27 | 显示全部楼层
什么内容看一看嗤
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入磁动力

本版积分规则

QQ|小黑屋|手机版|Archiver|www.cdle.net 磁动力电子网 2001-2017 ( 粤ICP备10098153号

粤公网安备 44040402000001号

GMT+8, 2019-6-27 05:59

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.