zoukankan      html  css  js  c++  java
  • 音乐播放器1-FATFS相关操作

        音乐播放器的两个关键点:1、用FATFS对音乐文件进行管理,包括打开,读取等。2、配置Codec芯片,通过DMA,把读取的音乐文件数据送到Codec。

    这个工程中,主要实现第一个大点的一些操作。

        直接上程序,需要注意的几个点。

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "lcd.h"
    #include "key.h"  
    #include "sram.h"   
    #include "malloc.h" 
    #include "sdio_sdcard.h"    
    #include "malloc.h" 
    #include "ff.h"  
    #include "string.h"
    #include "fattester.h"void upper(char *p);    //这个函数用来把小写字母转换成大写
    u8 tell_type(char *p);   //通过后缀名识别文件类型
    u8 wav_decode(FIL *p);    //WAV文件的解码
    
    u8 *readbuf;       
    UINT mybr;        
    
    int main(void)
    {        
        u8 key,res,music_number;
        char *myfn;                
        char *myfn_temp;              
        char *filename_temp;
        
       //FATFS相关的变量
    FATFS *fs[1]; FIL *myfile; DIR mydir; FILINFO myfileinfo; FRESULT myres; //初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); delay_init(168); uart_init(115200); LED_Init(); KEY_Init(); my_mem_init(SRAMIN); my_mem_init(SRAMCCM);   //SD卡初始化 while(SD_Init()) { delay_ms(500); LED0=!LED0; } //FATFS相关的很多函数,用到的结构体,需要申请内存,不然会出错,比如f_mount/f_open fs[0]=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); myfile=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); myfileinfo.lfsize = _MAX_LFN * 2 + 1; myfileinfo.lfname = mymalloc(SRAMIN,myfileinfo.lfsize); // 支持长文件名,方法为3,需要动态申请内存 _USE_LFN=3 readbuf=(u8*)mymalloc(SRAMIN,512); //读文件的缓冲区 myfn_temp= (char *)mymalloc(SRAMIN,myfileinfo.lfsize); res=f_mount(fs[0],"0:",1); //挂载 while(1) { key=KEY_Scan(0); if(key==1) //测试当前目录的文件读取,f_open-----f_read { f_open(myfile,"test1.txt",FA_READ); res=f_read(myfile,readbuf,20,&mybr); if(res) printf("Read Error:%d ",res); else while(*readbuf!='') { printf("%c",*readbuf); readbuf++; } } if(key==2) //文件类型识别 { music_number=0; f_opendir(&mydir,"0:/MUSIC"); // while(1) { myres=f_readdir(&mydir,&myfileinfo); //循环读取文件夹中所有的文件 if(myres != FR_OK || myfileinfo.fname[0] == 0) break; myfn = *myfileinfo.lfname ? myfileinfo.lfname : myfileinfo.fname; printf(" File name is %s ",myfn); filename_temp=myfn; res=tell_type(myfn); if(res==0) { printf("This is a music file. "); music_number++;//strcat(myfn_temp,myfn); strcpy((char*)myfn_temp,"0:/MUSIC/"); strcat((char*)myfn_temp,(const char*)myfn); //获取文件的绝对路径 printf(" File name is %s ",myfn_temp); f_open(myfile,myfn_temp,FA_READ); wav_decode(myfile); } } printf(" There is %d music file ",music_number); } if(key==3) // { f_opendir(&mydir,"0:/MUSIC"); f_open(myfile,"0:/MUSIC/µË×ÏÆå-Äã°ÑÎÒ¹à×í.wav",FA_READ); wav_decode(myfile); } } } //把字符串中的大写改成小写 void upper(char *p) { while(*p!='') { if((*p>=97)&&(*p<=120)) *p=*p-32; p++; } } //通过后缀名识别文件类型 u8 tell_type(char *p) { int i=0; char *attr; while(i<200) { if(*p=='') break; i++; p++; } if(i==200) return 1; i=0; while(i<5) { if(*p=='.') { p++; attr=p; break; } i++; p--; } if(i==5) return 2; if((strcmp(attr,"WAV")==0)||(strcmp(attr,"wav")==0)) { return 0; } else { return 4; } } //RIFF¿é typedef __packed struct { u32 ChunkID; // 0X46464952 u32 ChunkSize ; u32 Format; }ChunkRIFF ; //fmt¿é typedef __packed struct { u32 ChunkID; u32 ChunkSize ; u16 AudioFormat; u16 NumOfChannels; u32 SampleRate; u32 ByteRate; u16 BlockAlign; u16 BitsPerSample; // u16 ByteExtraData; }ChunkFMT; //fact¿é typedef __packed struct { u32 ChunkID; u32 ChunkSize ; u32 NumOfSamples; }ChunkFACT; u8 wav_decode(FIL *p) { u8 res; ChunkRIFF *riff; ChunkFMT *fmt; res=f_read(p,readbuf,512,&mybr); //ÔÚÍâÃæÖÐÒѾ­open if(res==FR_OK) { riff=(ChunkRIFF *)readbuf; printf("This is RIFF Chunk Read----------- "); printf("RIFF ChunkID is %x ",riff->ChunkID); printf("RIFF ChunkSize is %d MB ",riff->ChunkSize>>20); printf("RIFF Format is %x ",riff->Format); printf("This is FMT Chunk Read----------- "); fmt=(ChunkFMT *)(readbuf+12); printf("FMT ChunkID is %x ",fmt->ChunkID); printf("FMT ChunkSize is %d ",fmt->ChunkSize); printf("FMT Channle is %d ",fmt->NumOfChannels); } else { printf("Read Err:%d ",res); } return res; }
  • 相关阅读:
    完全背包详解
    0-1背包详解
    优先队列 + 模拟
    循环节 + 矩阵快速幂
    并查集 + 路径压缩(经典) UVALive 3027 Corporative Network
    dp
    动态规划分类(完整版)
    (二)Spring框架之JDBC的基本使用(p6spy插件的使用)
    (一)Spring框架基础
    (十六)客户端验证与struts2中的服务器端验证
  • 原文地址:https://www.cnblogs.com/nasduc/p/5272396.html
Copyright © 2011-2022 走看看