⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatprocess.c

📁 单片机读写U盘源码 基于51单片机和国产USB芯片CH374
💻 C
📖 第 1 页 / 共 3 页
字号:
     files[ i ].clus.fat16.NextClus = x16List( files[ i ].clus.fat16.StartClus, 0, ModeZ2 ) ;
     
     //调试语句
     #ifdef  DEBUG_OPEN
     printf( " 显示文件信息: \n " ) ;
     printf( " 本文件编号: %d\n ", ( UINT16 )i ) ;
     printf( " 本文件起始簇簇号:%d\n ", files[ i ].clus.fat16.StartClus ) ;
     printf( " 本文件长度:%ld\n ", files[ i ].FileSize ) ;
     printf( " 本文件所用扇区数:%ld\n ", files[ i ].Sectors) ;
     printf( " 本文件零碎数据长度 : %d 字节\n ", files[ i ].ShortLength ) ;
     printf( " 本文件占用扇区数: %ld\n ", files[ i ].UsedSectors ) ;
     printf( " 即将要操作的下个簇簇号: %d\n ", files[ i ].clus.fat16.NextClus ) ;
     #endif

     if ( ProcessMode == ModeA1 || ProcessMode == ModeA3 || ProcessMode == ModeB1 || ProcessMode == ModeB3 )
     {
          //为读取文件初始化
          files[ i ].Flags &= 0xF7 ;
          if ( files[ i ].clus.fat16.NextClus == 0xFFFF )
          {
               files[ i ].wr.read.LastClu = 0x01 ;
               files[ i ].wr.read.RemainSectors = files[ i ].UsedSectors ;
          }
          else
          {
               files[ i ].wr.read.LastClu = 0x00 ;
               files[ i ].wr.read.RemainSectors = FAT.SecPerClus ;
          }
     }
     else  if ( ProcessMode == ModeA2 || ProcessMode == ModeA4 || ProcessMode == ModeA5 || ProcessMode == ModeB2 || ProcessMode == ModeB4 || ProcessMode == ModeB5 )
     { 
          //为写入文件初始化
          files[ i ].Flags |= 0x08 ;
          if ( ! files[ i ].clus.fat16.StartClus && ! files[ i ].FileSize )//说明这是一个空文件,没有任何信息
          {
               files[ i ].wr.write.extra = 0 ;
               //查新簇
               files[ i ].clus.fat16.StartClus = x16CheckClus( ) ;
               if ( files[ i ].clus.fat16.StartClus == 0x00 )
                    return( ERR_FullDisk ) ;
               else  if ( files[ i ].clus.fat16.StartClus == ERR_CheckClus )
                    return( ERR_CheckClus ) ;
               //更新根目录中起始簇信息
               //调试语句
               #ifdef  DEBUG_OPEN
               printf( " 该文件本来是一个空文件.\n " ) ;
               printf( " 更新根目录中起始簇信息: " ) ;
               #endif
          
               ProcessSector = files[ i ].find.Sector ;
               POINT0 = files[ i ].find.Offset ;
               TransNum = files[ i ].find.TransNum ;
               s = mReadSector( ProcessSector, TransNum, DISKBUF );
		             if ( s != USB_INT_SUCCESS )
		                  return( ERR_Write ) ;
               *( POINT0 + 26 ) = ( UINT8 )files[ i ].clus.fat16.StartClus ;
               *( POINT0 + 27 ) = ( UINT8 )( files[ i ].clus.fat16.StartClus >> 8 ) ;
               //调试语句
               #ifdef  DEBUG_OPEN
               printf( " 更新的起始簇号:%d \n ", files[ i ].clus.fat16.StartClus ) ;
               #endif
               s = mWriteSector( ProcessSector, TransNum, DISKBUF );
		             if ( s != USB_INT_SUCCESS )
		                  return( ERR_Write ) ;
		                  
		             files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.StartClus ;
		             files[ i ].StartSector = ( ( files[ i ].clus.fat16.StartClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
               files[ i ].EndSector = files[ i ].StartSector ;
               files[ i ].wr.write.WritedSectors = 0 ;
          }
          else
          {
               UINT8  mainsectors = files[ i ].Sectors % FAT.SecPerClus ;
           
               #ifdef  DEBUG_OPEN
               printf( " 该文件本来就有数据.\n " ) ;
               #endif
            
               while ( (  Cluster = x16List( files[ i ].clus.fat16.EndClus, 0, ModeZ2 ) ) != 0xFFFF )
                    files[ i ].clus.fat16.EndClus = Cluster ;
               
               printf( " files[ i ].clus.fat16.EndClus = %d\n ", files[ i ].clus.fat16.EndClus ) ;
               
               if ( ! mainsectors && ! files[ i ].ShortLength )        //如果一簇正好满
               {
                    files[ i ].wr.write.extra = 0 ;
                    Cluster = x16CheckClus( ) ;
                    if ( Cluster == 0x00 )
                         return( ERR_FullDisk ) ;
                    else  if ( Cluster == ERR_CheckClus )
                         return( ERR_CheckClus ) ;    
                    
                    s = x16List( files[ i ].clus.fat16.EndClus, Cluster, ModeZ1 ) ;
                    if( s != ListSuccess )
                         return( s ) ;
                    
                    files[ i ].clus.fat16.EndClus = Cluster ; 
                    files[ i ].wr.write.WritedSectors = 0 ;
               }
               else  if ( ! files[ i ].ShortLength )
               {    
                    files[ i ].wr.write.extra = 0 ;
                    files[ i ].wr.write.WritedSectors = mainsectors ;
               }
               else 
               {
                    files[ i ].wr.write.extra = files[ i ].ShortLength ;
                    files[ i ].wr.write.WritedSectors = mainsectors ;
                    printf( " files[ i ].wr.write.WritedSectors = %d\n ", ( UINT16 )files[ i ].wr.write.WritedSectors ) ;
                    printf( " files[ i ].wr.write.extra = %d\n ", files[ i ].wr.write.extra ) ;
               }
               files[ i ].EndSector = ( ( files[ i ].clus.fat16.EndClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector + mainsectors ;
               printf( " files[ i ].EndSector = %d\n ", ( UINT16 )files[ i ].EndSector ) ;
               //若有零碎数据,将其读出
               if ( files[ i ].wr.write.extra )
               {
                    s = mReadSector( files[ i ].EndSector, 1, FILEBUF );
		                  if ( s != USB_INT_SUCCESS )
		                       return( ERR_Write ) ;
		             }
          }
     }                    
     return( OpenSuccess ) ;
}

/*********************************************************************************************************
** 函数名称: x16ReadFile
** 功能描述: FAT16读取文件
**
** 输 入: ReadNums: 可选的读取扇区数,若文件数据小于要求量,只会读取文件实际长度
** 输 出: 将所要求数量的文件数据读取到文件缓冲区FILE_BUF  
**           A.返回ERR_Read报告异常传输错误  
**           B.返回Clu_End表示一簇已读完,由于程序算法问题,此时FILEBUF中有效数据可能不足2048字节
**           C.返回File_End表示文件已读完,由于程序算法问题,此时FILEBUF中应有零碎数据( 不满一个扇区 )
**           D.返回ReadSuccess表示读取成功完成,并且不属于上述情况 
**
** 全局变量: files[ i ].find.Offset, FAT.SecPerClus, rFILEBUF
** 调用模块: x16ReadFAT, mReadSector, 
** 调试码:   DEBUG_READ
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  x16ReadFile( UINT8 ReadNums, UINT8 FileNum )
{
     UINT8  i ;
     UINT8  s ;
     UINT8  TransNum ;
     UINT32 ProcessSector ;
     
     /*
     for ( i = 0; i < 2; i ++ )
          printf( "files[ i ].Flags = %d\n", ( UINT16 )files[ i ].Flags ) ;
     //确定指定文件是否有效
     for ( i = 0; i < 2; i ++ )
          if ( ( files[ i ].Flags & 0x07 ) == FileNum )
               break ;
     if ( ! ( files[ i ].Flags & 0x80 ) || files[ i ].Flags & 0x08 || ( ( files[ i ].Flags & 0x07)  != i ) )
     {
          printf( " 错误的文件编号: %d\n ", ( UINT16 )i ) ;
          return( ERR_Read ) ;
     }*/
     /*  下面这段实际只是为保险起见,在程序测试无错后可以用下面这句代替 */
    i = FileNum ;
     
     //调试语句
     #ifdef  DEBUG_READ
     printf( " 开始读取文件. \n " ) ;
     printf( " 显示所读文件相关信息: \n " ) ;
     printf( " 本文件起始簇簇号:%d\n ", files[ i ].clus.fat16.StartClus ) ;
     printf( " 目前已读到簇号: %d\n ", files[ i ].clus.fat16.EndClus ) ;
     printf( " 将要读取的起始扇区号 : %lu\n ", files[ i ].EndSector ) ;
     printf( " 本文件长度:%ld\n ", files[ i ].FileSize ) ;
     printf( " 目前还有%ld扇区未读.\n ", files[ i ].Sectors ) ; 
     printf( " 本文件零碎数据长度 : %d 字节\n ", files[ i ].ShortLength ) ;
     #endif
  
     ProcessSector =  files[ i ].EndSector ;
     TransNum = ( files[ i ].wr.read.RemainSectors >= FileNums ) ? FileNums : files[ i ].wr.read.RemainSectors ;
     TransNum = ( TransNum > ReadNums ) ? ReadNums : TransNum ;
     
     //调试语句
     #ifdef  DEBUG_READ
     printf( " 要读取的扇区数:%d\n ", ( UINT16 )TransNum ) ;
     printf( " 现在是文件的最后一个簇了吗 ? Answer = %d\n ", ( UINT16 )files[ i ].wr.read.LastClu ) ;
     #endif
     
     s = mReadSector( ProcessSector, TransNum, rFILEBUF );
		   if ( s != USB_INT_SUCCESS )
		        return( ERR_Read ) ;
		   files[ i ].wr.read.ReadSectors = TransNum ;
		   files[ i ].wr.read.RemainSectors -= TransNum ;
		  
		   //调试语句
     #ifdef  DEBUG_READ
		   printf( " 该簇剩余扇区数 = %d\n ", ( UINT16 )files[ i ].wr.read.RemainSectors ) ;
		   #endif
		   
		   if( ! files[ i ].wr.read.RemainSectors )     //剩余扇区数为0,即一簇已读完
		   {
          if( ! files[ i ].wr.read.LastClu  )          
          //上次读取的不是文件的最后一个簇,下次继续读取文件
          {
               //调试语句
               #ifdef  DEBUG_READ
               printf( " 一簇已读完!\n " ) ;
               #endif
               files[ i ].UsedSectors -= ( UINT32 )FAT.SecPerClus ;
               files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.NextClus ;
               if ( ( files[ i ].clus.fat16.NextClus = x16List( files[ i ].clus.fat16.EndClus, 0, ModeZ2 ) ) == 0xFFFF ) 
               {
                    files[ i ].wr.read.LastClu = 1 ;
                    files[ i ].wr.read.RemainSectors = files[ i ].UsedSectors ;
               }
               else
               {
                    files[ i ].wr.read.LastClu = 0 ;
                    files[ i ].wr.read.RemainSectors = FAT.SecPerClus ;
               }
               files[ i ].EndSector = ( ( files[ i ].clus.fat16.EndClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
               return( Clu_End ) ;
          } 
          else            //最后一个簇,与前一if嵌套实际说明文件已经全部读完
		        {
		             //调试语句
		             #ifdef  DEBUG_READ
		             printf( " 文件已经读取完毕!\n " ) ;
		             #endif
		             return( File_End ) ;
		        }
     }
     else      //未读到簇完
     {
          files[ i ].EndSector += TransNum ;
     }
     return( ReadSuccess ) ;
}

/*********************************************************************************************************
** 函数名称: x16WriteFile
** 功能描述: FAT16写文件
**
** 输 入: WriteNums: 可选的写入字节数
** 输 出: 将FILE_BUF中的数据写入文件
**           A.返回ERR_Write报告异常传输错误  
**           B.返回WriteSuccess则写入成功返回
**           C.返回ERR_FullDisk表示磁盘已写满,无法正常写入数据
**
** 全局变量: FAT.SecPerClus, FAT.SecPerClus, files[ i ].wr.write.extra
** 调用模块: x16CheckClus, mReadSector, mWriteSector, x16List, memmove, memcpy
** 调试码:   DEBUG_WRITE
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  x16WriteFile( UINT16 WriteNums, UINT8 FileNum ) 
{
     UINT8  i ;
     UINT8  s ;
     UINT8  TransNum ;
     UINT8  writesectors ;
     UINT16 TransBytes ;      //传输的字节数
     UINT16 Cluster ;
     UINT16 bytes ;
     UINT32 ProcessSector ;
     
     /*
     for ( i = 0; i < 2; i ++ )
          printf( "files[ i ].Flags = %d\n", ( UINT16 )files[ i ].Flags ) ;
     //确定指定文件是否有效
     for ( i = 0; i < 2; i ++ )
          if ( ( files[ i ].Flags & 0x07 ) == FileNum )
               break ;
     if ( ! ( files[ i ].Flags & 0x80 ) || ! ( files[ i ].Flags & 0x08 ) || ( ( files[ i ].Flags & 0x07 ) != i ) )
     {
          printf( " 错误的文件编号: %d\n ", ( UINT16 )i ) ;
          return( ERR_Write ) ;
     }*/
     /*  上面这段实际只是为保险起见,在程序测试无错后可以用下面这句代替 */
     i = FileNum ;
     
     //判断WriteNums是否合理
     WriteNums = ( WriteNums > 2048 ) ? 2048 : WriteNums ;
       
     //计算FILE_BUF中数据长度
     //调试语句
     #ifdef  DEBUG_WRITE
     printf( " 更新文件长度信息 .\n " ) ;
     printf( " 文件原长度 = %lu\n ", files[ i ].FileSize ) ;
     #endif
     files[ i ].FileSize += ( UINT32 )WriteNums ;
     //调试语句
     #ifdef  DEBUG_WRITE
     printf( " 更新文件长度信息 .\n " ) ;
     printf( " 数据最新长度 = %lu\n ", files[ i ].FileSize ) ;
     #endif
     
     /*--------------------------------------------------------------------     
               以下if-else结构用来写入数据到文件中
               分两种情况考虑: 
               A:一次传输的数据越界了
               B:未越界,全部传输到一个簇内
     -------------------------------------------------------------------- */
     //调试语句
     #ifdef  DEBUG_WRITE
     printf( "写入数据 !\n" ) ;
     printf( " 用以判断越界的数据信息 :\n " ) ;
     printf( " 簇内已写的扇区数: " ) ;
     printf( " %d \n ", ( UINT16 )files[ i ].wr.write.WritedSectors ) ;
     printf( " 文件缓冲区内一次能传输的扇区数 :\n " ) ;
     printf( " FileNums  = %d \n ", ( UINT16 )FileNums ) ;
     printf( " DISK每簇扇区数: " ) ;
     printf( " FAT.SecPerClus = %d \n ", ( UINT16 )FAT.SecPerClus ) ;
     #endif
     
     //处理零碎数据
     memcpy ( FILEBUF + files[ i ].wr.write.extra, rFILEBUF, WriteNums ) ;  
     
     if ( WriteNums == 2048 )
     {
          writesectors = FileNums ;
          bytes = 0 ;
     }
     else  if ( bytes = WriteNums - ( WriteNums >> FAT.shift << FAT.shift ) )
     { 
          writesectors = ( WriteNums + files[ i ].wr.write.extra ) >> FAT.shift ;
          if ( ! writesectors )
          { 
               files[ i ].wr.write.extra = files[ i ].wr.write.extra + bytes ;
		             #ifdef  DEBUG_WRITE 
		             printf( " 写入成功 ! \n " ) ;
		             #endif
		             return( WriteSuccess ) ;
		        }
		        else
		        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -