[求助]急!U盘MP3 枚举MP3文件问题,麻烦看下~

想通过枚举找到MP3文件,然后顺序播放,但是未能如愿。程序如下:帮忙看下问题出在哪?谢谢了

while(1) { while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) /* 检查U盘是否连接,等待U盘插入,对于SD卡,可以由单片机直接查询SD卡座的插拔状态引脚 */ { delay_ms(100); } delay_ms(200); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */

USART1_SendByte(0xe3); /* 初始化磁盘并测试磁盘是否就绪 */ for ( k = 0; k < 100; k ++ ) /* 最长等待时间,100*50mS */ { delay_ms( 50 ); if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; /* 准备好 */ else if ( CH376DiskMount( ) == ERR_DISK_DISCON ) break; /* 检测到断开,重新检测并计时 */ if ( CH376GetDiskStatus( ) >= DEF_DISK_MOUNTED && k >= 5 ) break; /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */ } if ( CH376DiskMount( ) == ERR_DISK_DISCON ) { continue; }

/***********************/ pCodeStr = (char *)"\\*"; /* 列出根目录下的文件 */ for ( searchFileIndex = 0; searchFileIndex < 255; searchFileIndex++ ) { /* 最多搜索前255个文件 */ USART1_SendByte(0xe4); strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr ); /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */ i = strlen( (char const *)mCmdParam.Open.mPathName ); /* 计算文件名长度,以处理文件名结束符 */ mCmdParam.Open.mPathName[ i ] = searchFileIndex; /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */ ch375Result = CH376FileOpen( mCmdParam.Open.mPathName ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ if ( ch375Result == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ if ( ch375Result == ERR_FOUND_NAME ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */ nameLen = strlen( (char const *)mCmdParam.Open.mPathName ); if(nameLen < 4) continue; pExt = ((char *)mCmdParam.Open.mPathName) + nameLen - 4; if(strcmp(pExt, (char *)".MP3") == 0) { ch375Result = CH376FileOpen(mCmdParam.Open.mPathName ); /* 打开文件 */ if ( ch375Result != ERR_MISS_DIR && ch375Result != ERR_MISS_FILE ) { //mStopIfError( ch375Result ); //readSecCount = FILE_DATA_BUF_LEN / 512; if (ch375Result == USB_INT_SUCCESS) { u32FileLen = CH376GetFileSize(); /* 获取文件大小 */ while (u32DataCnt < u32FileLen) { SPI2_SetSpeed(SPI2_SPEED_8);//高速 pu8Temp = u8SectorBuf; CH376SecRead(pu8Temp, 1, 0); /*以扇区为单位从当前位置读取数据块,不支持SD卡*/ u32DataCnt += 512; SPI1_SetSpeed(SPI1_SPEED_16); //高速,对VS1003B,设置为4.5M

VS_XDCS = 0; m = 0; while (m < 512) //循环发送512个字节 { while (VS_DREQ == 0); //等待DREQ为高 for (j=0; j<32; j++) { SPI1_ReadWriteByte(*pu8Temp++); } m += 32; } VS_XDCS = 1; /*VS_XDCS = 1*/ } } } } } }

ch375Result = CH376FileOpen( mCmdParam.Open.mPathName ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ 此处ch375Result 返回的值 第一次为 62 第二次为 1D 第三次为 46 之后就一直重复这三个值。求解释?


请问怎样改才正确?


详细的说明一下现象,已经程序在哪里出现问题的。


if ( ch375Result == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ if ( ch375Result == ERR_FOUND_NAME ) {

if ( ch375Result == ERR_FOUND_NAME ) /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */

程序从这一句开始就进不去了,这是什么原因?谢谢


ch375Result = CH376FileOpen( mCmdParam.Open.mPathName ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ 现象: 我用串口查看此处ch375Resul的值 此处ch375Result 的值 第一次为 62 第二次为 1D 第三次为 46 之后就一直重复这三个值直到255次。


u8 CH376FileOpen( u8 *name ) /* 在根目录或者当前目录下打开文件或者目录(文件夹) */ { CH376SetFileName( name ); /* 设置将要操作的文件的文件名 */ if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 ); return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) ); }


与 mCmdParam.Open.mPathName有关的函数

/* ************************************************************************************** */ /* 主机文件模式下的数据输入和输出结构 */

#ifndef MAX_FILE_NAME_LEN #define MAX_PATH_LEN 30 /* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H */ #define MAX_BYTE_IO ( MAX_PATH_LEN - 1 ) /* 以字节为单位单次读写文件时的最大长度,超过该长度可以分多次读写 */

#define MAX_FILE_NAME_LEN (13+1) /* 文件名最大长度,最大长度是1个根目录符+8个主文件名+1个小数点+3个类型名+结束符=14 */

/* 外部命令参数 */ typedef union _CMD_PARAM { struct { UINT8 mBuffer[ MAX_PATH_LEN ]; } Other; struct { UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数 */ UINT32 mTotalSector; /* 返回: 当前逻辑盘的总扇区数 */ UINT32 mFreeSector; /* 返回: 当前逻辑盘的剩余扇区数 */ UINT8 mDiskFat; /* 返回: 当前逻辑盘的FAT类型 */ } Query; /* CMD_DiskQuery, 查询磁盘信息 */ struct { UINT8 mPathName[ MAX_PATH_LEN ]; /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ } Open; /* CMD_FileOpen, 打开文件 */ struct { UINT8 mPathName[ MAX_PATH_LEN ]; /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名(含通配符*)...,枚举序号], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILE*",00H */ } Enumer; /* CMD_FileEnumer, 枚举文件,返回文件名 */ struct { UINT8 mUpdateLen; /* 输入参数: 是否允许更新长度: 0禁止,1允许 */ } Close; /* CMD_FileClose, 关闭当前文件 */ struct { UINT8 mPathName[ MAX_PATH_LEN ]; /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ } Create; /* CMD_FileCreate, 新建文件并打开,如果文件已经存在则先删除后再新建 */ struct { UINT8 mPathName[ MAX_PATH_LEN ]; /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ } Erase; /* CMD_FileErase, 删除文件并关闭 */ struct { UINT32 mFileSize; /* 输入参数: 新的文件长度,为0FFFFFFFFH则不修改, 返回: 原长度 */ UINT16 mFileDate; /* 输入参数: 新的文件日期,为0FFFFH则不修改, 返回: 原日期 */ UINT16 mFileTime; /* 输入参数: 新的文件时间,为0FFFFH则不修改, 返回: 原时间 */ UINT8 mFileAttr; /* 输入参数: 新的文件属性,为0FFH则不修改, 返回: 原属性 */ } Modify; /* CMD_FileQuery, 查询当前文件的信息; CMD_FileModify, 查询或者修改当前文件的信息 */ struct { UINT32 mSectorOffset; /* 输入参数: 扇区偏移,0则移动到文件头,0FFFFFFFFH则移动到文件尾, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */ } Locate; /* CMD_FileLocate, 移动当前文件指针 */ struct { UINT8 mSectorCount; /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */ } Read; /* CMD_FileRead, 从当前文件读取数据 */ struct { UINT8 mSectorCount; /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */ } Write; /* CMD_FileWrite, 向当前文件写入数据 */ struct { UINT8 mSectorCount; /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */ UINT8 mReserved[7]; PUINT8 mDataBuffer; /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */ } ReadX; /* CMD_FileReadX, 从当前文件读取数据到指定缓冲区 */ struct { UINT8 mSectorCount; /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */ UINT8 mReserved[7]; PUINT8 mDataBuffer; /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */ } WriteX; /* CMD_FileWriteX, 向当前文件写入指定缓冲区的数据 */ struct { UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数 */ } DiskSize; /* CMD_DiskSize, 查询磁盘容量 */ struct { UINT32 mByteOffset; /* 输入参数: 以字节为单位的偏移量, 以字节为单位的文件指针, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */ } ByteLocate; /* CMD_ByteLocate, 以字节为单位移动当前文件指针 */ struct { UINT8 mByteCount; /* 输入参数: 准备读取的字节数,不得大于MAX_BYTE_IO, 返回: 实际读出的字节数 */ UINT8 mByteBuffer[ MAX_BYTE_IO ]; /* 返回: 读出的数据块 */ } ByteRead; /* CMD_ByteRead, 以字节为单位从当前文件读取数据块 */ struct { UINT8 mByteCount; /* 输入参数: 准备写入的字节数,不得大于MAX_BYTE_IO, 返回: 实际写入的字节数 */ UINT8 mByteBuffer[ MAX_BYTE_IO ]; /* 输入参数: 准备写入的数据块 */ } ByteWrite; /* CMD_ByteWrite, 以字节为单位向当前文件写入数据块 */ struct { UINT8 mSaveVariable; /* 输入参数: 为0则恢复变量,非0值则备份/保存变量 */ UINT8 mReserved[3]; PUINT8 mBuffer; /* 输入参数: 指向子程序库的变量的备份缓冲区,长度不小于80个字节 */ } SaveVariable; /* CMD_SaveVariable, 备份/保存/恢复子程序库的变量 */ union { struct { UINT32 mCBW_Sig; UINT32 mCBW_Tag; UINT8 mCBW_DataLen; /* 输入: 数据传输长度,有效值是0到255 */ UINT8 mCBW_DataLen1; UINT8 mCBW_DataLen2; UINT8 mCBW_DataLen3; UINT8 mCBW_Flag; /* 输入: 传输方向等标志 */ UINT8 mCBW_LUN; UINT8 mCBW_CB_Len; /* 输入: 命令块的长度,有效值是1到16 */ UINT8 mCBW_CB_Buf[6]; /* 输入: 命令块,该缓冲区最多为16个字节 */ } mCBW; /* BulkOnly协议的命令块, 输入CBW结构 */ struct { UINT32 mCSW_Sig; UINT32 mCSW_Tag; UINT32 mCSW_Residue; /* 返回: 剩余数据长度 */ UINT8 mCSW_Status; /* 返回: 命令执行结果状态 */ UINT8 mReserved; } mCSW; /* BulkOnly协议的命令状态块, 输出CSW结构 */ } BOC; /* CMD_BulkOnlyCmd, 执行基于BulkOnly协议的命令, 如果有数据传输那么数据在DISK_BASE_BUF中 */ } CMD_PARAM;

typedef CMD_PARAM CMD_PARAM_I; typedef CMD_PARAM *P_CMD_PARAM;


各位 帮忙看下,小弟第一次接触文件操作,求指导,谢谢~


如果你只枚举不打开应该是可以的吧? 还是枚举到文件,然后打开,然后再枚举出现的这种情况?


CH376S 的 CH376FileOpen(u8 * name)和CH375的CH375FileOpen()返回值不一样?? CH376S如果成功打开文件 应该会返回0X14,至于CH375的CH375FileOpen()不太清楚没研究过 从返回值来看 文件应该是没打开。此处ch376Result 返回的值重复出现以下情况: 第一次为 62 第二次为 1D 第三次为 46

ch376Result = CH376FileOpen( mCmdParam.Open.mPathName ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */

USART1_SendByte(ch376Result); if ( ch376Result == ERR_MISS_FILE )break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ if ( ch376Result == ERR_FOUND_NAME ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */

如果不打开文件也就是 ch376Result = CH376FileOpen( mCmdParam.Open.mPathName ); 这句不要,那下面的就没法判断了。搞不明白?

程序大概流程是 通过循环255次 ,找到前255个文件, 在循环中遇到 MP3文件则 播放。


只有登录才能回复,可以选择微信账号登录