我现在用STC89C54RD+和CH375及STA013做读U盘MP3播放器,但是现在出现的问题是: 1、播放速度跟不上,一开始我以为是单片机的处理速度不够(24MH),但是我倍频后,拨放速度更慢. 2、好象这里下在的库没支持中文歌名的显示,要做到这点,应该怎么做,请大家给个提示.
代码如下:
#include #include #include "mainH.H"
#define MAX_BYTE_IO 192 /* 以字节为单位单次读写文件时的最大长度,默认值是29,值大则占用内存多,值小则超过该长度必须分多次读写 */
/* 以下定义的详细说明请看CH375HFC.H文件 */ #define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */ #define LIB_CFG_UPD_SIZE 1 /* 在添加数据后是否自动更新文件长度: 0为"不更新",1为"自动更新" */ /* 默认情况下,如果扇区数/字节数不为0那么CH375FileWrite/CH375ByteWrite只负责写入数据而不修改文件长度, 如果需要每次写完数据后会自动修改/更新文件长度,那么可以使全局变量CH375LibConfig的位4为1, 如果长时间不写入数据则应该更新文件长度,防止突然断电后前面写入的数据与文件长度不相符, 如果确定不会突然断电或者后面很快有数据不断写入则不必更新文件长度,可以提高速度并减少U盘损耗(U盘内部的内存寿命有限,不宜频繁改写) */
/* 只使用单片机内置的1KB外部RAM: 0000H-01FFH 为磁盘读写缓冲区, 以字节为单位读写文件不需要文件数据读写缓冲区FILE_DATA_BUF */ #define DISK_BASE_BUF_ADDR 0x0000 /* 外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE */ #define FILE_DATA_BUF_ADDR 0x0000 /* 外部RAM的文件数据缓冲区的起始地址,缓冲区长度不小于一次读写的数据长度,字节模式不用该缓冲区 */ /* 由于单片机内置的外部RAM只有1KB, 有些单片机还要去掉256字节内部RAM, 只剩下768字节的外部RAM, 其中前512字节由CH375子程序用于磁盘数据缓冲 */ //#define FILE_DATA_BUF_LEN 0x0200 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度,字节模式不用该缓冲区 */ /* 如果准备使用双缓冲区交替读写,那么不要定义FILE_DATA_BUF_LEN,而是在参数中指定缓冲区起址,用CH375FileReadX代替CH375FileRead,用CH375FileWriteX代替CH375FileWrite */
#define CH375_INT_WIRE INT3 /* P3.2, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
#include "CH375HFC.H" #include "sta013H.H"
/* 本例用I/O引脚模拟产生CH375的并口读写时序 */ /* 本例中的硬件连接方式如下(实际应用电路可以参照修改下述3个并口读写子程序) */ /* 单片机的引脚 CH375芯片的引脚 P3.2 INT# P1.0 A0 P1.1 CS# 如果模拟出的并口上只有CH375,那么CS#可以直接接低电平,强制片选 P1.2 WR# P1.3 RD# P0(8位端口) D7-D0 */ sbit CH375_A0 = P4^1; //sbit CH375_CS = P3^5; //CS->GND sbit CH375_WR = P3^6; // sbit CH375_RD = P3^7; //
void mDelay1_2uS( ) /* 至少延时1.2uS,根据单片机主频调整 */ { return; }
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */ { mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时1uS */ P0 = mCmd; /* 向CH375的并口输出数据 */ CH375_A0 = 1; // CH375_A0 = 1; CH375_WR = 0; /* 输出有效写控制信号, 写CH375芯片的命令端口 */ CH375_A0 = 1; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ CH375_WR = 1; /* 输出无效的控制信号, 完成操作CH375芯片 */ // CH375_CS = 1; CH375_A0 = 0; // P0 = 0xFF; /* 禁止数据输出 */ mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时2uS */ }
void xWriteCH375Data( UINT8 mData ) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */ { P0 = mData; /* 向CH375的并口输出数据 */ CH375_A0 = 0; // CH375_A0 = 0; CH375_WR = 0; /* 输出有效写控制信号, 写CH375芯片的数据端口 */ CH375_A0 = 0; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ CH375_WR = 1; /* 输出无效的控制信号, 完成操作CH375芯片 */ // CH375_CS = 1; // P0 = 0xFF; /* 禁止数据输出 */ mDelay1_2uS( ); /* 至少延时1.2uS */ }
UINT8 xReadCH375Data( void ) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */ { UINT8 mData; P0 = 0xFF; /* 输入 */ mDelay1_2uS( ); /* 至少延时1.2uS */ CH375_A0 = 0; // CH375_A0 = 0; CH375_RD = 0; /* 输出有效写控制信号, 读CH375芯片的数据端口 */ CH375_A0 = 0; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ mData = P0; /* 从CH375的并口输入数据 */ CH375_RD = 1; /* 输出无效的控制信号, 完成操作CH375芯片 */ // CH375_CS = 1; return( mData ); }
/* 延时100毫秒,不精确 */ void mDelay100mS( ) { UINT8 i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }
/* 将程序空间的字符串复制到外部RAM中,返回字符串长度 */ UINT8 mCopyCodeStringToXRAM( UINT8 xdata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); }
/* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ while ( 1 ) { mDelay100mS( ); mDelay100mS( ); } }
/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { T2CON=0X34; SCON=0X50; RCAP2H=0XFF; RCAP2L=0Xb0; //RCAP2L=fa 9600bps @24.576Mhz TMOD=0x91; TR2=TI=1; ET1=IT1=EX1=EA=1; }
U8 ReadData() { mCmdParam.ByteRead.mByteCount = 1; CH375ByteRead(); return(mCmdParam.ByteRead.mByteBuffer[0]); } /********************************* Playing mp3 file **********************************/ void PlayMp3() { U8 i; U8 *p=128; while(1){ i = mCopyCodeStringToXRAM( mCmdParam.Open.mPathName, "\\*" ); //*搜索文件名,*为通配符 mCmdParam.Open.mPathName[ i ] = FileNo; /* 根据字符串长度将结束符替换为搜索的序号,从0到254 */ i = CH375FileOpen( ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ if ( i == ERR_MISS_FILE ){ if(FileNo>1)FileNo-=1; else break; } else break; } if ( CH375FileOpen() == ERR_SUCCESS ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */ printf( " Playing file %s\n", mCmdParam.Open.mPathName ); /* 显示序号和搜索到的匹配文件名或者子目录名 */ } mCmdParam.ByteLocate.mByteOffset = 0; /* 移到文件的头部 */ CH375ByteLocate( ); mCmdParam.ByteRead.mByteCount = 64; CH375ByteRead(); // for (i=0; i<128; i++){ *p=mCmdParam.ByteRead.mByteBuffer[i]; p++; } // CH375FileClose( ); /* 关闭文件 */ sta013StartDecoder(); Playing=1; }
main( ) { UINT8 i,j,dat; //, month, hour;// UINT16 date, adc, len; mDelay100mS( ); /* 延时100毫秒 */ mInitSTDIO( ); /* 为了让计算机通过串口监控过程 */ i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i ); printf( "Waiting Insert Udisk\n" ); while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 查询CH375中断并更新中断状态,等待U盘插入 */ mDelay100mS( ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ mDelay100mS( ); /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ for ( i = 0; i < 5; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */ mDelay100mS( ); printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ }
/* 其它电路初始化 */ if (sta013Init()=='F') printf("Intilize Sta013 Fail\n"); else printf("Intilize Sta013 OK!!!\n"); FileNo=1; i=0; volum('+'); PlayMp3();
while