为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

单片机MP3原理图+程序

2017-09-19 24页 doc 98KB 36阅读

用户头像

is_682974

暂无简介

举报
单片机MP3原理图+程序//mian.c/////////////////////// #include "config.h" xdata FILE TmpFile ; void main() {     UINT32 lba = 0;     UINT16 i;     UartInit();                            //初始化串口     UartSendStr("**************************************\r\n");     UartSendStr("**************...
单片机MP3原理图+程序
//mian.c/////////////////////// #include "config.h" xdata FILE TmpFile ; void main() {     UINT32 lba = 0;     UINT16 i;     UartInit();                            //初始化串口     UartSendStr("**************************************\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("*********51MP3播放器演示程序**********\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("**************************************\r\n");     UartSendStr("初始化SPI接口\r\n");     InitSPI();        //初始化SPI接口     UartSendStr("初始化VS1003\r\n");     RstVs1003();     UartSendStr("正弦测试\r\n");     //Sintest();     DelayMs(300);     UartSendStr("退出正弦测试\r\n");     SoftRstVs1003();     UartSendStr("初始化CH375\r\n");     InitCH375();         //初始化液晶     LCD_Init();     //显示logo     LCD_SET_CURSOR(1,1);     Print("  mp3 player  ",16);     LCD_SET_CURSOR(2,1);     Print("    stuelab    ",16);     SPI_HIGH_SPEED();      //高速SPI接口     UartSendStr("初始化文件系统\r\n");     InitFat (SectorBuf);     UartSendStr("统计文件信息\r\n");     i = StatFileNum(2, "MP3", SectorBuf);     sprintf(SectorBuf,"根目录下MP3文件个数为%d .\r\n",i);     UartSendStr(SectorBuf);     i = StatFileNum(2, "WMA", SectorBuf);     sprintf(SectorBuf,"根目录下WMA文件个数为%d .\r\n",i);     UartSendStr(SectorBuf);     i = StatFileNum(2, "  ", SectorBuf);     sprintf(SectorBuf,"根目录下文件夹个数为%d .\r\n",i);     UartSendStr(SectorBuf);     UartSendStr("查找根目录下第一个MP3文件\r\n");     SearchFile(2, 1, "MP3", SectorBuf, &TmpFile);     UartSendStr("\r\n开始播放\r\n");     //UartSendStr(TmpFile.short_name);     lba = ClusToLba(TmpFile.start_clus);     while (1)     {         RdSDblock(lba++,SectorBuf);         PlaySector();     } } //spi.c//////// #include "config.h"                                          sbit SCK = P1^7; sbit SO    = P1^5; sbit SI    = P1^6; void InitSPI (void) {     SCK = 1;     SO = 1;     SI = 1;     SPCR = 0xdc+3;          //主机模式,允许中断,时钟常高,4分频     ES  = 0;                    //串口中断允许。SPI和UART共用同一个中断。     EA  = 0;                      //中断总控位 } void SPIsendByte (unsigned char dat) {     SDAT = dat;     while (!(SPSR & 0x80));        //等待发送完毕     SPSR = 0;                      //清除中断标志 } unsigned char SPIrecvByte (void) {                          unsigned char dat ;     SDAT = 0XFF;     while (!(SPSR & 0x80));        //等待发送完毕     SPSR = 0;                      //清除中断标志     dat = SDAT;                        //发送的过程中同时完成接收     return dat ;     //return SDAT;    } void SPIsendByte2(unsigned char temp) //软件模拟SPI发送接口 {     char i;     for (i = 0; i < 8; i++) {         SCK = 0 ;         SO  = (bit)(temp&0x80) ;         SCK = 1 ;         temp <<= 1;     }     SO = 1 ; } /* unsigned SPIrecvByte2(void)          //软件模拟SPI接收接口 {     char i ;     unsigned char temp;     for(i = 0; i < 8; i++) {         temp <<= 1;         SCK = 0 ;         temp = ((char)SI) | temp ;         SCK = 1 ;     }     return(temp); } */ #include "config.h"                                              delay.c void DelayMs(UINT16 ticks) {     UINT16 tmp;     while (ticks--) {         for (tmp=1000; tmp>0; tmp--);     } } void DelayUs(UINT16 ticks) {     while (ticks--); } #include "config.h"                                              vs1003.c char tmp; void SoftWrVs1003Cmd(unsigned char addr,unsigned int cmd) {     SPCR = 0;//关闭SPI     //SCK =  1;     //SO    = 1;     //SI    = 1;     WaitVs1003();     SelectCmdVs1003();                    //片选     DelayUs(5);     SPIsendByte2(0x02);     SPIsendByte2(addr);     SPIsendByte2((unsigned char)(cmd>>8));     SPIsendByte2((unsigned char)cmd);     DelayUs(5);     ReleaseCmdVs1003();                      //释放     SPCR = 0xdf; //打开SPI } void WrVs1003Cmd (unsigned char addr,unsigned int cmd) {     WaitVs1003();     SelectCmdVs1003();                    //片选     DelayUs(5);     SPIsendByte(0x02);     SPIsendByte(addr);     SPIsendByte((unsigned char)(cmd>>8));     SPIsendByte((unsigned char)cmd);     DelayUs(5);     ReleaseCmdVs1003();                      //释放 } void SoftRstVs1003(void) {     //WrVs1003Cmd(0,0x0804);      //具体功能见官方数据手册第28页(软件复位)     SoftWrVs1003Cmd(0,0x0804);     DelayMs(10);     SoftWrVs1003Cmd(2,0x00f6);    //低音     DelayMs(1);     SoftWrVs1003Cmd(3,0x9800);    //倍频     DelayMs(10);     SoftWrVs1003Cmd(5,0xbb81);    //采样率和通道数     DelayMs(1);     SoftWrVs1003Cmd(0x0b,0x2020);  //音量     DelayMs(1); } void RstVs1003(void) {     SelectRstVs1003();         //硬件复位     DelayMs(10);     SPIsendByte(0xff);     ReleaseRstVs1003();     DelayMs(10);     WrVs1003Cmd(0x0b,0xffff);  //音量     DelayMs(1);     SoftRstVs1003(); } /* void Sintest(void) {        WrVs1003Cmd(0,0x0820);  //进入正弦测试     WaitVs1003();     SelectDatVs1003();     DelayUs(5);     SPIsendByte(0x53);     SPIsendByte(0xef);     SPIsendByte(0x6e);     SPIsendByte(0x30);     SPIsendByte(0);     SPIsendByte(0);     SPIsendByte(0);     SPIsendByte(0);     DelayUs(5);     ReleaseDatVs1003(); } */ void PlaySector(void) {     UINT16 i ;     SelectDatVs1003();     for (i=0; i<512;) {//连续发32个字节(VS1003有32字节的缓冲区)         WaitVs1003(); // 查忙         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);         SPIsendByte(SectorBuf[i++]);     }     ReleaseDatVs1003(); } //定义CH375.c//// #include "config.h" #include #include //#include       //串口驱动函数 /* 定义CH375命令代码及返回状态 */ #include "CH375INC.H" /* CH375特性 */ #define CH375_BLOCK_SIZE        64        /* CH375 maximum data block size */ #define CH375_BLK_PER_SEC        8        /* CH375 block per sector, SECTOR_SIZE/CH375_BLOCK_SIZE */ /* 以下定义适用于MCS-51单片机,其它单片机参照修改,为了提供C语言的速度需要对本程序进行优化 */ #include unsigned char volatile xdata    CH375_CMD_PORT _at_ 0xff04;    /* CH375命令端口的I/O地址 */ unsigned char volatile xdata    CH375_DAT_PORT _at_ 0xfe04;    /* CH375数据端口的I/O地址 */ unsigned char xdata                DATA_BUFFER[512]    _at_ 0x0000;    /* 外部RAM数据缓冲区的起始地址,长度不少于一次读写的数据长度 */ sbit    CH375_INT_WIRE = 0xA0^5;    /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */ /* 在P1.4连接一个LED用于监控演示程序的进度,低电平LED亮,当U盘插入后亮 */ sbit P1_4  = P1^4; #define LED_OUT_ACT( )        { P1_4 = 0; }    /* P1.4 低电平驱动LED显示 */ #define LED_OUT_INACT( )    { P1_4 = 1; }    /* P1.4 低电平驱动LED显示 */ /* 延时2微秒,不精确 */ void    delay2us( ) {     unsigned char i;     for ( i = 2; i != 0; i -- ); } /* 延时1微秒,不精确 */ void    delay1us( ) {     unsigned char i;     for ( i = 1; i != 0; i -- ); } /* 延时100毫秒,不精确 */ void    mDelay100mS( ) {     unsigned char    i, j, c;     for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; } /* 基本操作 */ void CH375_WR_CMD_PORT( unsigned char cmd ) {  /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */     delay2us();     CH375_CMD_PORT=cmd;     delay2us(); } void CH375_WR_DAT_PORT( unsigned char dat ) {  /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */     CH375_DAT_PORT=dat;     delay1us();  /* 因为MCS51单片机较慢所以实际上无需延时 */ } unsigned char CH375_RD_DAT_PORT() {  /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */     delay1us();  /* 因为MCS51单片机较慢所以实际上无需延时 */     return( CH375_DAT_PORT ); } /* 等待CH375中断并获取状态 */ unsigned char mWaitInterrupt() {  /* 主机端等待操作完成, 返回操作状态 */     while( CH375_INT_WIRE );  /* 查询等待CH375操作完成中断(INT#低电平) */     CH375_WR_CMD_PORT( CMD_GET_STATUS );  /* 产生操作完成中断, 获取中断状态 */     return( CH375_RD_DAT_PORT( ) ); /*    c = CH375_RD_DAT_PORT( );  返回中断状态 */ /*    if ( c == USB_INT_DISCONNECT ) ?;  检测到USB设备断开事件 */ /*    else if ( c == USB_INT_CONNECT ) ?;  检测到USB设备连接事件 */ } /* 设置CH375为USB主机方式 */ unsigned char    mCH375Init( ) {     unsigned char    i; #ifdef    TEST_CH375_PORT     unsigned char    c;     CH375_WR_CMD_PORT( CMD_CHECK_EXIST );  /* 测试工作状态 */     CH375_WR_DAT_PORT( 0x55 );  /* 测试数据 */     c = CH375_RD_DAT_PORT( );  /* 返回数据应该是测试数据取反 */     if ( c != 0xaa ) {  /* CH375出错 */         for ( i = 100; i != 0; i -- ) {  /* 强制数据同步 */             CH375_WR_CMD_PORT( CMD_RESET_ALL );  /* CH375执行硬件复位 */             c = CH375_RD_DAT_PORT( );  /* 延时 */         }         mDelay100mS( );  /* 延时至少30mS */     } #end if     CH375_WR_CMD_PORT( CMD_SET_USB_MODE );  /* 设置USB工作模式 */     CH375_WR_DAT_PORT( 6 );  /* 模式代码,自动检测USB设备连接 */     for ( i = 0xff; i != 0; i -- )  /* 等待操作成功,通常需要等待10uS-20uS */         if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break;  /* 操作成功 */     if ( i != 0 ) return( 0 );  /* 操作成功 */     else return( 0xff );  /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */ } /* 初始化磁盘 */ unsigned char    mInitDisk( ) {     unsigned char mIntStatus;     CH375_WR_CMD_PORT( CMD_GET_STATUS );  /* 产生操作完成中断, 获取中断状态 */     mIntStatus = CH375_RD_DAT_PORT( );     if ( mIntStatus == USB_INT_DISCONNECT ) return( mIntStatus );  /* USB设备断开 */     CH375_WR_CMD_PORT( CMD_DISK_INIT );  /* 初始化USB存储器 */     mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */     if ( mIntStatus != USB_INT_SUCCESS ) return( mIntStatus );  /* 出现错误 */     CH375_WR_CMD_PORT( CMD_DISK_SIZE );  /* 获取USB存储器的容量 */     mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */     if ( mIntStatus != USB_INT_SUCCESS ) {  /* 出错重试 */         mDelay100mS( );         CH375_WR_CMD_PORT( CMD_DISK_SIZE );  /* 获取USB存储器的容量 */         mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */     }     if ( mIntStatus != USB_INT_SUCCESS ) return( mIntStatus );  /* 出现错误 */ /* 可以由CMD_RD_USB_DATA命令将容量数据读出 */     return( 0 );  /* U盘已经成功初始化 */ } /* 从U盘读取多个扇区的数据块到缓冲区 */ unsigned char    mReadSector( unsigned long iLbaStart, unsigned char iSectorCount ) /* iLbaStart 是准备读取的线性起始扇区号, iSectorCount 是准备读取的扇区数 */ {     unsigned char mIntStatus;     unsigned char *mBufferPoint;     unsigned int  mBlockCount;     unsigned char mLength;     CH375_WR_CMD_PORT( CMD_DISK_READ );  /* 从USB存储器读数据块 */     CH375_WR_DAT_PORT( (unsigned char)iLbaStart );  /* LBA的最低8位 */     CH375_WR_DAT_PORT( (unsigned char)( iLbaStart >> 8 ) );     CH375_WR_DAT_PORT( (unsigned char)( iLbaStart >> 16 ) );     CH375_WR_DAT_PORT( (unsigned char)( iLbaStart >> 24 ) );  /* LBA的最高8位 */     CH375_WR_DAT_PORT( iSectorCount );  /* 扇区数 */     mBufferPoint = DATA_BUFFER;  /* 指向缓冲区起始地址 */     for ( mBlockCount = iSectorCount * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- ) /* 数据块计数 */     {          mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */         if ( mIntStatus == USB_INT_DISK_READ )     /* USB存储器读数据块,请求数据读出 */         {              CH375_WR_CMD_PORT( CMD_RD_USB_DATA );  /* 从CH375缓冲区读取数据块 */             mLength = CH375_RD_DAT_PORT( );  /* 后续数据的长度 */             while ( mLength )  /* 根据长度读取数据 */             {                  SBUF = CH375_RD_DAT_PORT( );                 while(!TI) ;                 TI = 0 ;                 //*mBufferPoint = CH375_RD_DAT_PORT( );  /* 读出数据并保存 */                 //mBufferPoint ++;                 mLength --;                 delay2us( );             }             CH375_WR_CMD_PORT( CMD_DISK_RD_GO );  /* 继续执行USB存储器的读操作 */         }         else break;  /* 返回错误状态 */     }     if ( mBlockCount == 0 ) {         mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */         if ( mIntStatus == USB_INT_SUCCESS ) return( 0 );  /* 操作成功 */     }     return( mIntStatus );  /* 操作失败 */ } struct _HD_MBR_DPT {     unsigned char    PartState;     unsigned char    StartHead;     unsigned int    StartSec;     unsigned char    PartType;     unsigned char    EndHead;     unsigned int    EndSec;     unsigned long    StartSector;     unsigned long    TotalSector; }; /* 为printf和getkey输入输出初始化串口 */ void    mInitSTDIO( ) {     //定时器1工作在模式2,8Bit自动重装载模式     TMOD = (TMOD & 0X0F) | 0X21;      SCON = 0x50;     PCON |= 0x80;//波特率翻倍     TH1 = 0xff;     TL1 = 0xff; //12M晶振,12T模式,波特率为115200     TR1 =1;     TI = 1; } main( ) {     unsigned char c, mIntStatus;     mInitSTDIO( );     LED_OUT_ACT( );  /* 开机后LED亮一下以示工作 */     mDelay100mS( );  /* 延时100毫秒 */     LED_OUT_INACT( );         printf( "Start\n" );     c = mCH375Init( );  /* 初始化CH375 */     if ( c )     {         printf( "Error @CH375Init\n" );     }     printf( "Insert USB disk\n" );     do            /* 等待U盘连接 */     {          mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */     }     while ( mIntStatus != USB_INT_CONNECT );  /* U盘没有连接或者已经拔出 */     mDelay100mS( );  /* 延时等待U盘进入正常工作状态 */     mDelay100mS( );     printf( "InitDisk\n" );     c = mInitDisk( );  /* 初始化U盘,实际是识别U盘的类型,不影响U盘中的数据,在所有读写操作之前必须进行此步骤 */     if ( c )     {         printf( "Error @InitDisk, %02X\n", c );     }     LED_OUT_ACT( ); /* 检查U盘是否准备好,大多数U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ //    do { //        mDelay100mS( ); //        printf( "Disk Ready ?\n" ); //        i = CH375DiskReady( );  /* 查询磁盘是否准备好,如果省掉这个子程序可以节约将近1KB的程序代码 */ //    } while ( i != ERR_SUCCESS ); /* CH375DiskReady 在CH375的U盘文件子程序库中,因为代码较多,所以此处省去 */     printf( "ReadSector 0# to buffer\n" );     c = mReadSector(4110, 1 );     /*if ( c ) printf( "Error @ReadSector, %02X\n", c );     if ( DATA_BUFFER[0x01FF] == 0xAA ) {  /* 磁盘分区有效 */         /*printf( "WriteSector 1# from buffer\n" );         c = mWriteSector( 1, 1 );         if ( c ) printf( "Error @WriteSector, %02X\n", c );         memset( DATA_BUFFER, 0, 512 );  /* 清空数据缓冲区,代替原来的分区信息 */         /*printf( "WriteSector 0# for clear\n" );         c = mWriteSector( 0, 1 );         if ( c ) printf( "Error @WriteSector, %02X\n", c );     }     else {         printf( "ReadSector 1# to buffer\n" );         c = mReadSector( 1, 1 );         if ( c ) printf( "Error @ReadSector, %02X\n", c );         printf( "WriteSector 0# from buffer\n" );         c = mWriteSector( 0, 1 );         if ( c ) printf( "Error @WriteSector, %02X\n", c );     }*/     printf( "Stop\n" );     while ( 1 )     {         mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */         if ( mIntStatus == USB_INT_DISCONNECT )    /* U盘没有连接或者已经拔出 */         {             printf( "Out\n" );             LED_OUT_INACT( );         }         else if ( mIntStatus == USB_INT_CONNECT )  /* U盘已经连接 */         {             printf( "In\n" );             LED_OUT_ACT( );         }     } } #include "config.h"                      uart.c void UartInit (void) { //配置 #define MCLK        22118400L    //定义CPU主频(Hz) #define BAUD_RATE    19200L        //设置波特率     RXD = 1;     TXD = 1;     SCON = 0x50;    //串口方式1(8位Uart),允许接收     PCON |= 0x80;    //波特率加倍     TMOD &= 0x0F;     TMOD |= 0x20;     TH1 = 256 - ( MCLK / 12 ) / ( 16 * BAUD_RATE );     TL1 = TH1;        //设置波特率     TR1 = 1;     //ES = 1;            //允许串行口中断     //EA = 1;            //允许中断 } void UartSendByte (unsigned char dat) {     SBUF = dat;     while(!TI);     TI = 0; } void UartSendStr(char *str) {     while (*str != '\0'){                UartSendByte(*str);         str++ ;     } } #include "config.h"                lcd.c delay(unsigned char time) {         while(--time); } //LCD状态检测,根据最高位判断LCD是否忙 unsigned char LCD_BUSY(void) {         delay(20);//Protues仿真环境下必须延时         if((bit)(LCD_CR & 0x80)) return (1);         else  return (0); } //将要显示的字符写入LCD  void Print(unsigned char *str,unsigned char n){     unsigned char i;       for(i=0;i100)          //按键时间超过一秒,长按键码       { //      key=key_old+0x80;              //长按键码等于普通按键码加0x80       }     else if(key_pressed_time>1)       {       key=key_old;                    //按键值       }     key_old=0;     }   return;   } else                                  //按键按下   {   key_new=0;   if(BEGIN_KEY)key_new=KEY_BEGIN;            //BEGIN键按下   if(DOWN_KEY)key_new=KEY_DOWN;            //DOWN键按下   if(UP_KEY)key_new=KEY_UP;                  //UP键按下   if(VOL DOWN_KEY)key_new=KEY_DOWN;        //VOL  DOWN键按下   if(VOL UP_KEY)key_new=KEY_UP;                //VOL  UP键按下   if(key_new==key_old)                        //如果按键按下长于10ms     {     if(key_pressed_time>80)                  //如果按键按下超过1s       {       key_pressed_time-=5;                    //则自动按键。相当于每隔50ms按一次       key=key_new;       return;       }     else       {       key_pressed_time++;                      //按键按下计时加一       }     }   else     {     key_pressed_time=0;                      //如果本次按下跟上次按下不一样,则按键按下时间清零     }   key_old=key_new;                            //保存本次按键值   } } //fat.c #include "config.h" unsigned long int DosBootSector;    //操作系统引导扇区 unsigned char    SectorPerClus;    //每簇扇区数(一般很小,2-64) unsigned long int FatStartSector;    //FAT开始扇区 unsigned long int DataStartSector;    //数据开始扇区 /*读主引导******master boot record********/ void RdMBR (unsigned char *buf) {     READ_SECTOR(0, buf);     DosBootSector = buf[454]                   + buf[455]*256                   + buf[456]*65536                   + buf[457]*65536*256;  } /****读操作系统引导记录扇区***dos boot recode************/ void RdDBR (unsigned char *buf) {            idata unsigned long int fat_size ;        //文件分配表的大小     idata unsigned long int reserved_sector ;     READ_SECTOR(DosBootSector,buf);         SectorPerClus  = buf[13] ;          //每簇扇区数     reserved_sector = buf[14] ;          //保留扇区,一般为32,但有的不是,所以读出      fat_size = buf[36]             + buf[37]*256             + buf[38]*65536             + buf[39]*65536*256;     fat_size = fat_size * 2;     FatStartSector = DosBootSector + reserved_sector;     DataStartSector = FatStartSector + fat_size ; } //簇号转为逻辑扇区号 unsigned long int ClusToLba (unsigned long int clus)  //ok {     return (unsigned long int)((clus-2) * (unsigned long int)SectorPerClus + DataStartSector); } //通过当前簇,查找下一簇 unsigned long int SearchNextClus (unsigned long int this_clus, unsigned char *buf) {     unsigned long int fat_offset ;     unsigned char  offset ;     fat_offset = this_clus/128 ;          //每扇区存放128个FAT项     offset = this_clus % 128 ;     READ_SECTOR(FatStartSector + fat_offset, buf);     if (buf[4 * offset + 3] == 0X0F ) return 0 ;  //the end     return (unsigned long int)( buf[4*offset]                               + buf[4*offset+1]*256                               + buf[4*offset+2]*65536                               + buf[4*offset+3]*65536*256); } // void InitFat (unsigned char *buf) {     RdMBR(buf);      //读主引导扇区     RdDBR(buf);        //读操作系统引导扇区,获取该分区文件系统信息     sprintf(buf,"the DosBootSector = %ld . \r\n",DosBootSector);     UartSendStr(buf);     sprintf(buf,"the SectorPerClus = %ld . \r\n",(unsigned long int)SectorPerClus);     UartSendStr(buf);     sprintf(buf,"the FatStartSector = %ld . \r\n",FatStartSector);     UartSendStr(buf);     sprintf(buf,"the DataStartSector = %ld . \r\n",DataStartSector);     UartSendStr(buf); } #include "config.h"                                                file.c //查找以index为索引的文件 unsigned char SearchFile (unsigned long int entry,                           unsigned int index,                           char *type,                           unsigned char *buf,                           FILE *pfile) {     unsigned char i ;     unsigned int file_num = 0 ;     unsigned char sector_count = 0;         unsigned char *pdir;     unsigned char dir_count;     unsigned long int addr = ClusToLba(entry);     while (1)     {         if(sector_count++ < SectorPerClus) {             READ_SECTOR(addr++, buf);         } else {             SearchNextClus(entry++, buf);             addr = ClusToLba(entry);             sector_count = 1 ;             READ_SECTOR(addr++, buf);         }         for (dir_count = 0; dir_count < 16; dir_count++) //每扇区有16个目录项         {             pdir = &buf[dir_count*32];             if (pdir[0] == 0) {                          //结束,未找到                 return 0 ;             } else if ((pdir[0]  != 0xe5) &&            //未删除                        (pdir[8]  == type[0]) &&                       (pdir[9]  == type[1]) &&                       (pdir[10] == type[2])) {                 if (++file_num == index) {              //找到文件                     for (i = 0; i < 11; i++) {          // copy short name                         pfile -> short_name[i] = pdir[i];                     }                     pfile -> short_name[11] = '\0';                          pfile -> attr = pdir[11] ;          //属性字节                     pfile -> start_clus = pdir[20]*65536                                         + pdir[21]*256*65536                                         + pdir[26] + pdir[27]*256;                     pfile -> size = pdir[30]*65536 + pdir[31]*256*65536                                   + pdir[28] + pdir[29]*256;                     UartSendStr("file has found !\r\n");                     UartSendStr(pfile -> short_name);                                            }             }         }     } } //查找某一个目录下指定文件的个数 unsigned int StatFileNum (unsigned long int entry,      //入口簇                                        char *type,                  //查找类型                           unsigned char *buf)          //扇区缓冲区 {     idata unsigned int file_num = 0 ;     idata unsigned char sector_count = 0;         unsigned char *pdir;     idata unsigned char dir_count;     idata unsigned long int addr = ClusToLba(entry);     while (1)     {         if(sector_count++ < SectorPerClus) {             READ_SECTOR(addr++, buf);         } else {             SearchNextClus(entry++, buf);             addr = ClusToLba(entry);             sector_count = 1 ;             READ_SECTOR(addr++, buf);         }         for (dir_count = 0; dir_count < 16; dir_count++) //每扇区有16个目录项         {             pdir = &buf[dir_count*32];             if (pdir[0] == 0) {                      //查找结束,返回文件个数                 return file_num;             } else if ((pdir[0]  != 0xe5) &&            //未删除                        (pdir[8]  == type[0]) &&                       (pdir[9]  == type[1]) &&                       (pdir[10] == type[2])) {                 file_num++;                            //找到文件                 continue ;             }         }     } } 文档已经阅读完毕,请返回上一页!
/
本文档为【单片机MP3原理图+程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索