搜索
bottom↓
回复: 0

mega16+ch376枚举文件的数量问题

[复制链接]

出0入0汤圆

发表于 2013-4-12 06:42:32 | 显示全部楼层 |阅读模式
本帖最后由 Tobacco 于 2013-4-12 06:44 编辑

大家好,新人一枚拜上有个问题想请教一下大家

最近参考论坛上的mp3例子,自己也学着用mega16+ch376+vs1053做了一个简单的mp3。其中枚举文件的功能是由ch376官方例程修改而来的,函数如下,其中listAll调用了listfile:
  1. typedef struct _FILE_NAME {
  2.         UINT32        DirStartClust;                                /* 文件所在目录的起始簇号 */
  3. //        UINT32        Size;                                                /* 文件长度 */
  4.         UINT8        Name[8+1+3+1];                                /* 文件名,共8+3字节,分隔符,结束符,因为未包含上级目录名所以是相对路径 */
  5.         UINT8        Attr;                                                /* 文件属性 */
  6. } FILE_NAME;
  7. #define                MAX_FILE_COUNT                15
  8. FILE_NAME         FileNameBuffer[MAX_FILE_COUNT];        /* 文件名结构 */
  9. UINT16                FileCount;



  10. UINT8        ListFile( UINT8 index )
  11. /* 输入参数index是指目录在结构中的序号 */
  12. {
  13.    UINT8                buf[64];
  14.         UINT8                        s;
  15.         P_FAT_DIR_INFO        pDir;
  16.         UINT8                        *pNameBuf;  
  17.         UINT32                        CurrentDirStartClust;  /* 保存当前目录的起始簇号,用于加快文件枚举和打开速度 */
  18.         CH376WriteVar32( VAR_START_CLUSTER, FileNameBuffer[ index ].DirStartClust );  /* 将当前目录的上级目录的起始簇号设置为当前簇号,相当于打开上级目录 */
  19. //        printf( "List Directory: %s\n", FileNameBuffer[ index ].Name );  /* 显示当前要列举的目录名 */
  20.         s = CH376FileOpen( FileNameBuffer[ index ].Name );  /* 打开目录,仅为了获取目录的起始簇号以提高速度 */
  21.         if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );  /* 应该是打开了目录,但是返回结果是打开了文件 */
  22.         else if ( s != ERR_OPEN_DIR ) return( s ); /* ERR_OPEN_DIR指定路径的目录(文件夹)被打开 ,用在这里代表正确打开目录而非错误*/
  23.         if ( index ) CurrentDirStartClust = CH376ReadVar32( VAR_START_CLUSTER );  /* 不是根目录,获取目录的起始簇号 */
  24.         else CurrentDirStartClust = 0;  /* 是根目录 */
  25.         CH376FileClose( FALSE );  /* 对于根目录一定要关闭 */
  26.         CH376WriteVar32( VAR_START_CLUSTER, CurrentDirStartClust );  /* 当前目录的起始簇号,相当于打开当前目录 */
  27.         CH376SetFileName( "*" );  /* 设置将要操作的文件的文件名,通配符支持所有文件和子目录 */
  28.         xWriteCH376Cmd( CMD0H_FILE_OPEN );  /* 枚举文件和目录 */
  29.         xEndCH376Cmd( );
  30.         while ( 1 ) {
  31.                 s = Wait376Interrupt( );
  32.                 if ( s == USB_INT_DISK_READ ) {  /* 请求数据读出 */
  33. /* 在文件枚举过程中,不能执行其它可能产生中断的操作命令,例如,如果需要获取长文件名,那么可以将枚举出的文件名保存并在枚举结束后获取其长文件名 */
  34.                         CH376ReadBlock( buf );  /* 读取枚举到的文件的FAT_DIR_INFO结构,返回长度总是sizeof( FAT_DIR_INFO ) */
  35.                         xWriteCH376Cmd( CMD0H_FILE_ENUM_GO );  /* 继续枚举文件和目录,先发出下一个命令再分析上行读出的数据可以让CH376与单片机分别同时工作,提高速度 */
  36.                         xEndCH376Cmd( );
  37.                         pDir = (P_FAT_DIR_INFO)buf;  /* 当前文件目录信息 */
  38.                         if ( pDir -> DIR_Name[0] != '.' ) {  /* 不是本级或者上级目录名则继续,否则必须丢弃不处理 */
  39.                                 if ( pDir -> DIR_Name[0] == 0x05 ) pDir -> DIR_Name[0] = 0xE5;  /* 特殊字符替换 */
  40.                                 //if ( pDir -> DIR_Name[8] == 'H' && pDir -> DIR_Name[9] == ' '  /* 比较文件扩展名分析文件类型的范例 */
  41.                                 //        || pDir -> DIR_Name[8] == 'E' && pDir -> DIR_Name[9] == 'X' && pDir -> DIR_Name[10] == 'E' ) {
  42.                                 //        printf( "This is a .H or .EXE file\n" );
  43.                                 //}
  44.                                 if ( FileCount < MAX_FILE_COUNT ) {  /* 文件名结构缓冲区足够 */
  45.                                         pNameBuf =  FileNameBuffer[ FileCount ].Name;  /* 文件名结构中的文件名缓冲区 */
  46.                                         for ( s = 0; s < 11; s ++ ) {  /* 复制文件名,长度为11个字符 */
  47.                                                 if ( pDir -> DIR_Name[ s ] != 0x20 ) {  /* 有效字符 */
  48.                                                         if ( s == 8 ) {  /* 处理扩展名 */
  49.                                                                 *pNameBuf = '.';  /* 分隔符 */
  50.                                                                 pNameBuf ++;
  51.                                                         }
  52.                                                         *pNameBuf = pDir -> DIR_Name[ s ];  /* 复制文件名的一个字符 */
  53.                                                         pNameBuf ++;
  54.                                                 }
  55.                                         }
  56.                                         *pNameBuf = 0;  /* 当前文件名完整路径的结束符 */
  57.                                         FileNameBuffer[ FileCount ].DirStartClust = CurrentDirStartClust;  /* 记录当前目录的起始簇号,用于加快文件打开速度 */
  58.                                         FileNameBuffer[ FileCount ].Attr = pDir -> DIR_Attr;  /* 记录文件属性 */
  59.                                 //        if ( pDir -> DIR_Attr & ATTR_DIRECTORY ) printf( "Dir %4d#: %s\n", FileCount, FileNameBuffer[ FileCount ].Name );  /* 判断是目录名 */
  60.                                 //        else printf( "File%4d#: %s\n", FileCount, FileNameBuffer[ FileCount ].Name );  /* 判断是文件名 */
  61.                                         FileCount ++;  /* 子目录计数 */
  62.                                 }
  63.                                 else {  /* 文件名结构缓冲区太小,结构数量不足 */
  64.                                 //        printf( "FileName Structure Full\n" );
  65.                                         s = Wait376Interrupt( );
  66.                                         CH376EndDirInfo( );  /* 获取完FAT_DIR_INFO结构 */
  67.                                         break;  /* 强行终止枚举 */
  68.                                 }
  69.                         }
  70.                 }
  71.                 else {
  72.                         if ( s == ERR_MISS_FILE ) s = USB_INT_SUCCESS;  /* 没有找到更多的匹配文件 */
  73.                         break;
  74.                 }
  75.         }
  76. /*        if ( s == USB_INT_SUCCESS ) return( s );*/  /* 操作成功 */
  77.         return( s );
  78. }

  79. UINT8        ListAll( void )  /* 以广度优先的算法枚举整个U盘中的所有文件及目录 */
  80. {
  81.         UINT8        s;
  82.         UINT16        OldFileCount;
  83.         //UINT16        RealReadCount;
  84.         FileNameBuffer[ 0 ].Name[0] = '/';  /* 根目录,是完整路径名,除根目录是绝对路径之外都是相对路径 */
  85.         FileNameBuffer[ 0 ].Name[1] = 0;
  86.         FileNameBuffer[ 0 ].DirStartClust = 0;  /* 根目录的起始簇号 */
  87.         FileNameBuffer[ 0 ].Attr = ATTR_DIRECTORY;  /* 根目录也是目录,作为第一个记录保存 */
  88.         for ( OldFileCount = 0, FileCount = 1; OldFileCount < FileCount; OldFileCount ++ )
  89.         {  /* 尚有新枚举到的文件名结构未进行分析,FileCount处于变化之中 */
  90.                 if ( FileNameBuffer[ OldFileCount ].Attr & ATTR_DIRECTORY ) /* 是目录则继续进行深度搜索 */
  91.                 {
  92.                         s = ListFile( OldFileCount );  /* 枚举目录,记录保存到结构中,FileCount可能会改变 */
  93.                         if ( s != USB_INT_SUCCESS ) return( s );
  94.                 }
  95.         }
复制代码
我遇到一个难题,就是mega16的内存只有1k,而vs1053的送数程序已经占用了512byte缓冲,也就是说其实能用的内存只有一半。再看看上面的函数,是利用结构体FileNameBuffer[MAX_FILE_COUNT]来存储枚举出来的文件列表的,一个文件的信息就占用了18byte,20首歌就占用了360byte;所以我现在只敢枚举20首歌(感觉很挫~囧~明明用了ch376已经省下了FAT文件系统的负担了)……我看到论坛上有些大神也是用mega16+vs1003来做mp3的,不但做好了液晶显示歌曲列表,而且fat文件系统还是由mega16实现的,这太霸道了吧!内存怎么够用?真心请教各位,怎么才能罗列更多的歌曲?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-27 01:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表