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

📄 fatprocess.c

📁 单片机读写U盘源码 基于51单片机和国产USB芯片CH374
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************Copyright (c)**************************************************
**                               CH374做主机操作U盘读写程序
**                                     FAT16文件系统层
**                                        接口函数
**
**                                        VBeat 0.5
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: FATProcess.C
**创   建   人: 徐亦朱
**最后修改日期: 2007年9月27日
**描        述: FAT文件系统层接口函数
**              
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 徐亦朱
** 版  本: VBeat 0.3
** 日 期: 2007年9月21日
** 描 述: 完善程序风格
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007年9月27日
** 描 述: 优化数据结构及算法
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

#include  <stdio.h>
#include  <string.h>

#include  "HAL.H"
#include  "HAL_BASE2.C"
#include  "PARA_HW2.C"
#include  "FAT.H"
#include  "FATProcess.H"

/*********************************************************************************************************
** 函数名称: FATInit
** 功能描述: FAT文件系统参数初始化
**
** 输 入: 无
** 输 出: FAT文件系统各项参数初始化
**           A.返回ERR_Init报告异常传输错误
**           B.返回InitSuccess表示初始化成功完成
**         
** 全局变量: FAT.SecPerClus, FAT.BytesPerSec, FAT.RsvdSecCnt, FAT.shift, FAT.RootDirSectors
**           FAT.FirstRootSector, FAT.FirstDataSector, DiskNums, FileNums 
** 调用模块: mReadSector
** 调试码:   DEBUG_Init
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  FATInit( void ) 
{
     UINT8  s ;
     UINT8  NumFATs ;
     UINT16 RootEntCnt ;
     UINT16 TotSec16 ;             //该卷总扇区数( FAT16 )
     UINT32 TotSec32 ;             //该卷总扇区数( FAT32 ) 
     UINT16 FATSz16  ;             //FAT16表所占扇区数
     UINT32 FATSz32  ;             //FAT32表所占扇区数 
     UINT32 TotSec ;
     UINT32 FATSz ;
     UINT32 DataSec ;
     UINT32 RootClus ;
     UINT32 Count_of_Cluster ;
 
     //读取DBR扇区
		   s = mReadSector( 0x00000000, 1, DISKBUF);
		   if ( s != USB_INT_SUCCESS )
		        return( ERR_Init ) ;
		   
		   //DISK每簇扇区数
		   FAT.SecPerClus =  ( ( ( PUSB_BPB )DISKBUF ) ) -> base.SecPerClus ; 
     //DISKFAT表数目
     NumFATs = ( ( ( PUSB_BPB )DISKBUF ) ) -> base.NumFATs ;
     //DISK每扇区字节数
     FAT.BytesPerSec = ( UINT16 )( ( ( ( PUSB_BPB )DISKBUF ) ) -> base.BytesPerSec[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.BytesPerSec[ 1 ] ) << 8  ;
     //DISK保留扇区数
     FAT.RsvdSecCnt = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RsvdSecCnt[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RsvdSecCnt[ 1 ] ) << 8 ;
     //DISK根目录项数
     RootEntCnt = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RootEntCnt[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RootEntCnt[ 1 ] ) << 8 ;
     //FAT32根目录所在第一簇的簇号
     RootClus = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 3 ] ) << 24 ;
     //FAT16表所占扇区数
     FATSz16 = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.FATSz16[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.FATSz16[ 1 ] ) << 8 ;
     //该卷总扇区数( FAT16 )
     TotSec16 = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec16[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec16[ 1 ] ) << 8 ;
     //FAT32表所占扇区数
     FATSz32 = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 3 ] ) << 24 ;
     //该卷总扇区数( FAT32 )
     TotSec32 = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 3 ] ) << 24 ;
     
     //将每扇区字节数转换成2的整数次方,以方便运算
     switch( FAT.BytesPerSec >> 9 )
     {
          case 1 :  FAT.shift = 9 ;     break ;
          case 2 :  FAT.shift = 10 ;    break ;
          case 4 :  FAT.shift = 11 ;    break ;
          default:  printf( " Sorry,this system is not suit for this type ! \n " ) ;
                    break ;
     }
     
     //DISK根目录所占的扇区数
     FAT.RootDirSectors = ( ( RootEntCnt << 5 ) + ( FAT.BytesPerSec - 1 ) ) >> FAT.shift ;
     //确定FAT表所占扇区数
     FATSz = FATSz16 ? FATSz16 : FATSz32 ;
     //DISK根目录第一个扇区的扇区号
     FAT.FirstRootSector = ( UINT32 )( FAT.RsvdSecCnt + FATSz * NumFATs ) ;
     //DISK簇2的第一个扇区的扇区号
     FAT.FirstDataSector = FAT.FirstRootSector + FAT.RootDirSectors ;
     
     //  FAT类型辨别
     TotSec = TotSec16 ? TotSec16 : TotSec32 ;     
     //DISK数据区中扇区数
     DataSec = TotSec - FAT.FirstDataSector ;
     //DISK簇数
     Count_of_Cluster = DataSec / FAT.SecPerClus ;
     if ( Count_of_Cluster < 4085 )
     {
          FAT.Type = FAT12 ;
          printf( " This FS is FAT12.\n " ) ;
          printf( " This System is not suit for FAT12 !\n " ) ;
          return( ERR_Init ) ;
     }
     else  if ( Count_of_Cluster < 65525 )
     {
          FAT.Type = FAT16 ;
          printf( " This FS is FAT16.\n " ) ;
          printf( " Welcome to you !\n " ) ;
     }
     else
     {
          FAT.Type = FAT32 ;
          printf( " This FS is FAT32.\n " ) ;
          printf( " Welcome to you !\n " ) ;
     }
     
     //DISK根目录第一个扇区的扇区号
     FAT.FirstRootSector = ( FAT.Type == FAT32 ) ? ( UINT32 )( ( ( RootClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ) : FAT.FirstRootSector ;
     //DISK_BUF能存储的扇区数
     DiskNums = DISKBUF_BYTES >> FAT.shift ;
     //FILE_BUF能存储的扇区数
     FileNums = ( FILEBUF_BYTES >> FAT.shift ) - 1 ;

     //调试语句
     #ifdef DEBUG_Init 
     printf( "This FS Type is %d\n", ( UINT16 )FAT.Type ) ;
     printf( "FAT表份数 = %d\n", ( UINT16 )NumFATs ) ;
     printf( "FAT表所占扇区数 = %ld\n", ( UINT32 )FATSz ) ;
     printf( "数据区域总簇数 = %ld\n", ( UINT32 )Count_of_Cluster ) ;
     printf( "总扇区数 = %ld\n", ( UINT32 )TotSec ) ;
     printf( "数据扇区总数 = %ld\n", ( UINT32 )DataSec ) ;
     printf( "根目录扇区总数 = %d\n", FAT.RootDirSectors ) ;
     printf( "保留扇区数 = %d\n", FAT.RsvdSecCnt ) ;
     printf( "根目录项数 = %d\n", RootEntCnt  ) ;
     printf( "每簇扇区数 = %d\n", ( UINT16 )FAT.SecPerClus ) ;
     printf( "每扇区字节数 = %d", FAT.BytesPerSec ) ;
     printf( "即2的%d次方\n", ( UINT16 )FAT.shift ) ;
     printf( "根目录起始扇区数 = %ld\n", ( UINT32 )FAT.FirstRootSector ) ;
     printf( "数据区域起始扇区数 = %ld\n", ( UINT32 )FAT.FirstDataSector ) ;
     #endif 
     
     //初始化文件结构变量
     for ( s = 0; s < 2; s ++ )
          files[ s ].Flags = 0 ;
     
     rFILEBUF = FILEBUF + FAT.BytesPerSec ;
     
     return( InitSuccess ) ;
}

/*********************************************************************************************************
** 函数名称: FATOpen
** 功能描述: 打开文件函数
**
** 输 入: string: 指向要打开的文件名( 路径形式,例如: "/……/……/文件名" )
**         ProcessMode: 操作模式ProcessMode:
**                  ModeA1:  0x00 -- 打开文件,以便读,若文件不存在则退出
**                  ModeA2:  0x80 -- 打开文件,以便写,若文件不存在则退出
**                  ModeA3:  0x01 -- 打开文件,以便读,先将文件长度截为0,如果文件不存在则退出
**                  ModeA4:  0x81 -- 打开文件,以便写,先将文件长度截为0,如果文件不存在则退出
**                  ModeA5:  0x82 -- 打开文件,以便写,向已有文件的尾部追加内容,如果文件不存在则退出
**                  ModeB1:  0x10 -- 打开文件,以便读,若文件不存在则创建之
**                  ModeB2:  0x90 -- 打开文件,以便写,若文件不存在则创建之
**                  ModeB3:  0x11 -- 打开文件,以便读,先将文件长度截为0,若文件不存在则创建之
**                  ModeB4:  0x91 -- 打开文件,以便写,先将文件长度截为0,若文件不存在则创建之
**                  ModeB5:  0x92 -- 打开文件,以便写,向已有文件的尾部追加内容,若文件不存在则创建之  
**                  ModeC1:  0xF1 -- 打开目录,以便读写,若目录不存在则创建之
**                  ModeC2:  0xF2 -- 删除文件/目录,如果文件/目录不存在则退出
** 输 出: 逐级打开,需先打开上层目录
**         找到的文件/目录在簇内的地址信息记录在FIND结构中
**           A.返回ERR_Check报告异常传输错误
**           B.返回OpenSuccess则操作成功
**           C.返回ERR_NOFile查找文件失败,磁盘中无此文件
**           D.返回ERR_OPEN打开文件失败,没有可用的文件结构
**         
** 全局变量: FAT.filenum 
** 调用模块: ProcessPath, CheckFirst16, x16CheckFile, xProcessDirectory, x16RootDirectory, x16Creat
** 调试码:   DEBUG_OPEN
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱 
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  FATOpen( const UINT8 *string, UINT8 ProcessMode )
{
     UINT8  i ;
     UINT8  s ;
     UINT8  r ;
     UINT8  Count ;
     UINT8  *POINT0 ;
     UINT8  TransNum ;
     UINT16 Cluster ;
     UINT32 ProcessSector ;
     
     //系统时间初始化
     sysclock.date.day = 27;
     sysclock.date.month = 9 ;
     sysclock.date.year = 27 ;
     sysclock.time.sec = 0 ;
     sysclock.time.min = 0 ;
     sysclock.time.hour = 12 ;
     
     //查询可用文件结构
     for ( i = 0; i < 2; i ++ )
     {
          if ( ! ( files[ i ].Flags & 0x80 ) )
               break ;
     }
     if ( files[ i ].Flags & 0x80 )
          return( ERR_OPEN ) ;
     files[ i ].Flags = 0x80 ;          //标记为已用
     files[ i ].Flags |= i ;            //编号
     FAT.filenum = i ;
     
     //查找路径,记录上级目录地址信息
     Count = 0 ;
     while ( 1 )
     {
          //处理路径
          r = ProcessPath( string, files[ i ].Name ) ;
          //查找操作
          if ( ! Count )
          {
               if ( FAT.Type == FAT16 )
                    s = CheckFirst16( &files[ i ] ) ;
               //if ( FAT.Type == FAT32 ) 
                    //s = CheckFirst32( FileName ) ;
               Count ++ ;
          }
          else
          {
               if ( FAT.Type == FAT16 )
                    s = x16CheckFile( &files[ i ] ) ;
               //if ( FAT.Type == FAT32 ) 
                    //s = x32CheckFile( FileName ) ;
               if ( ++ Count == 10 )
                    Count = 2 ; 
          }
          //判断查找结果
          if ( s == ERR_Check )
               return( s ) ;
          if ( s == 0x00 )
               break ;
          if ( r == EndPath )
               break ;
     }
     //处理文件查找结果
     
     if ( s == 0x00 )
     {
          if ( ProcessMode == ModeA1 || ProcessMode == ModeA2 || ProcessMode == ModeA3 || ProcessMode == ModeA4 || ProcessMode == ModeA5 || ProcessMode == ModeC2 )
               return( ERR_NOFile ) ;
          else  if ( ProcessMode == ModeB1 || ProcessMode == ModeB2 || ProcessMode == ModeB3 || ProcessMode == ModeB4 || ProcessMode == ModeB5 )
          {
               if ( Count == 1 )
               {
                    s = x16RootDirectory( &files[ i ], ModeX1 ) ;
                    if ( s != DirectorySuccess )
                         return( s ) ;
               }
               else
               {
                    s = x16Creat( &files[ i ], ModeX1 ) ;
                    if ( s != CreatSuccess )
                         return( s ) ;
               }
          }
          else  if ( ProcessMode == ModeC1 )
          {
               if ( Count == 1 )
               {
                    s = x16RootDirectory( &files[ i ], ModeX2 ) ;
                    if ( s != DirectorySuccess )
                         return( s ) ;
               }
               else
               {
                    s = x16Creat( &files[ i ], ModeX2 ) ;
                    if ( s != CreatSuccess )
                         return( s ) ;
               }
               files[ i ].Flags = 0 ;
          }
     }
     else
     {
          if ( ProcessMode == ModeA3 || ProcessMode == ModeA4 || ProcessMode == ModeB3 || ProcessMode == ModeB4 )   
          {
               s = xProcessDirectory( &files[ i ], ModeX3 ) ;
               if ( s != DirectorySuccess )
                    return( s ) ;
          }
          else  if ( ProcessMode == ModeC2 )
          {
               s = xProcessDirectory( &files[ i ], ModeX4 ) ;
               if ( s != DirectorySuccess )
                    return( s ) ;
               files[ i ].Flags = 0 ;
          }
     }

     if ( ProcessMode == ModeC1 || ProcessMode == ModeC2 )
          return( OpenSuccess ) ;
     
     //  更新所打开的文件信息
     POINT0 = files[ i ].find.Offset ;
     files[ i ].clus.fat16.StartClus = ( UINT16 )( *( POINT0 + 26 ) ) | ( ( UINT16 )( *( POINT0 + 27 ) ) << 8 ) ;
     files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.StartClus ;
     files[ i ].FileSize = ( UINT32 )( *( POINT0 + 28 ) ) | ( ( UINT32 )( *( POINT0 + 29 ) ) << 8 ) | ( ( UINT32 )( *( POINT0 + 30 ) ) << 16 ) | ( ( UINT32 )( *( POINT0 + 31 ) ) << 24 ) ;
     files[ i ].Sectors = ( UINT32 )( files[ i ].FileSize >> FAT.shift ) ;
     files[ i ].ShortLength = ( UINT16 )( files[ i ].FileSize - ( UINT32 )( files[ i ].FileSize >> FAT.shift << FAT.shift ) ) ;
     files[ i ].StartSector = ( ( files[ i ].clus.fat16.StartClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
     files[ i ].EndSector = files[ i ].StartSector ;
     files[ i ].UsedSectors = files[ i ].ShortLength ? ( files[ i ].Sectors + 1 ) : files[ i ].Sectors ;

⌨️ 快捷键说明

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