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

📄 fatfunction.c

📁 单片机读写U盘源码 基于51单片机和国产USB芯片CH374
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************Copyright (c)**************************************************
**                               CH374做主机操作U盘读写程序
**                                     FAT16文件系统层
**                                        功能函数
**
**                                        VBeat 0.5
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: FATFunction.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  "FATFunction.H"

/*********************************************************************************************************
** 函数名称: ProcessName
** 功能描述: 8 + 3文件名处理
**
** 输 入: string:   指向一个普通的文件名
**         filename: 指向一个11字节的空数组
** 输 出: string指向的文件名被处理为11字节大小8 + 3文件名数组
**         
** 全局变量: 无
** 调用模块: 无
** 调试码:   DEBUG_NAME
**  
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void  ProcessName( const UINT8 * string, UINT8 * filename )
{ 
     #ifdef DEBUG_NAME
     UINT8  i ;
     #endif
     UINT8  ExtFlag ;
     UINT8  * POINT0 ;
     UINT8  * POINT1 ;
     UINT8  * POINT2 ;
     
     //文件名数组初始化
     for ( POINT0 = filename; POINT0 < ( filename + 11 ); POINT0 ++ )
               * POINT0 = ' ' ;
     //确认是否有扩展名
     ExtFlag = 0 ;
     for ( POINT0 = string ; *POINT0 != '\0' && POINT0 < ( string + 9 ) ; POINT0 ++ )
     {
          if ( *POINT0 != '.' )
               continue ;
          ExtFlag = 1 ;
          break ;
     }
     //文件名处理
     if ( ExtFlag )
     {
          for ( POINT0 = string, POINT1 = filename ; *POINT0 != '.' && POINT0 < string + 8 ; POINT0 ++, POINT1 ++ )
               * POINT1 = * POINT0 ;
          POINT2 = ++ POINT0 ;
          for ( POINT1 = filename + 8 ; *POINT0 != '\0' && POINT0 < POINT2 + 3 ; POINT0 ++, POINT1 ++ )
               * POINT1 = * POINT0 ;
     }
     else
     {
          for ( POINT0 = string, POINT1 = filename ; *POINT0 != '\0' && POINT0 < string + 8 ; POINT0 ++, POINT1 ++ )
               * POINT1 = * POINT0 ;
     }
     //调试语句,查看转换是否正确
     #ifdef DEBUG_NAME
     for ( i = 0; i < 11; i ++ )
          printf( " Process the conversion result : %c\n ", filename[ i ] ) ;
     #endif
}

/*********************************************************************************************************
** 函数名称: ProcessPath
** 功能描述: 文件路径处理
**
** 输 入: string:   指向要操作的文件路径,路径输入格式: /……/……/……
**         filename: 指向一个11字节的空数组
** 输 出: string指向的文件路径被处理为8 + 3字符数组
**           A.返回EndPath报告路径处理结束,当前处理的是最终文件名
**           B.否则返回继续标识符NextContinue
**         
** 全局变量: 无
** 调用模块: ProcessName
** 调试码:   DEBUG_PATH
**
**PS:      A.暂时文件名输入需要尽可能准确,例如不要输入10个字符的基本名   
**         B.此程序因为没有对static变量Count初始化而导致POINT2指针乱飞,由于编译器会经常出现莫名其妙的问题
**           对static显式初始化很有必要  
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  ProcessPath( const UINT8 *string, UINT8 * filename )
{
     UINT8  s ;
     UINT8  *POINT0 ;
     UINT8  *POINT1 ;
     UINT8  *POINT3 ;
     UINT8  temp[ 13 ] ;
     static UINT8  *POINT2 ;
     static UINT8 Count = 0 ;
     
     POINT3 = strrchr( string, '/' ) ;
     if ( ! Count )
          POINT2 = string + 1 ;
     //调试语句
     #ifdef DEBUG_PATH
     printf( " 路径字符串内存地址 = %p\n ", string ) ;
     printf( " 静态指针变量POINT2地址 = %p\n ", POINT2 ) ;
     printf( " 最后一个路径符号POINT3地址 = %p\n " , POINT3 ) ;
     #endif 
     //临时数组初始化
     for ( POINT0 = temp; POINT0 < ( temp + 13 ); POINT0 ++ )
          * POINT0 = ' ' ;
     
     if( POINT2 != POINT3 + 1 )
     {
          s = NextContinue ;
          //将路径截取到临时数组中
          for ( POINT0 = POINT2, POINT1 = temp; *POINT0 != '/' && POINT0 < ( POINT2 + 13 ) ; POINT0 ++, POINT1 ++ )
               * POINT1 = * POINT0 ;
          ( * ++ POINT1 ) = '\0' ;
          POINT2 = ++ POINT0 ;
          ProcessName( temp, filename ) ;
          Count ++ ;
     }
     else
     {
          Count = 0 ;    
          s = EndPath ;
          ProcessName( POINT3+1, filename ) ;
     }
     //调试语句
     #ifdef DEBUG_PATH
     printf( " 本次要查找的文件/目录名 = %s\n ", filename ) ;
     #endif
     
     return( s ) ;       
}  

/*********************************************************************************************************
** 函数名称: x16List
** 功能描述: 根据簇号计算并读取FAT16表中相关信息
**
** 输 入: clus  : 要计算的簇号
**         value : 要更新的值
**         ProcessMode: 函数工作模式
**           A.ModeZ1: 更新FAT表
**           B.ModeZ2: 查找FAT表中下个簇的值
** 输 出: A.返回ERR_List报告异常传输错误
**         B.返回ListSuccess表示操作成功完成
**         C.ModeZ2下会返回下个簇的值
** 全局变量: FAT.SecPerClus, FAT.FirstDataSector, DISKBUF
** 调用模块: mReadSector, mWriteSector
** 调试码:   DEBUG_LIST
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

UINT16 x16List( UINT16 clus, UINT16 value, UINT8 ProcessMode ) 
{
     UINT8  s ; 
     UINT16 Cluster ;
     UINT16 ThisFATEntOffset ;
     UINT32 FATOffset ;
     UINT32 ThisFATSecNum ;
     
     //计算该簇号对应的起始扇区数以及FAT中偏移
     FATOffset = clus << 1 ;            //簇N在FAT16表中的偏移 
     ThisFATSecNum = FAT.RsvdSecCnt + ( FATOffset >> FAT.shift ) ;        //簇N在FAT16表中的扇区号
     ThisFATEntOffset = FATOffset - ( FATOffset >> FAT.shift << FAT.shift ) ;  //簇N在FAT16表中的相对偏移
     
     #ifdef DEBUG_LIST
     printf( "簇%d在FAT16表中的相对偏移 = %d\n", clus, ThisFATEntOffset ) ;
     printf( "簇N在FAT16表中的偏移 = %ld\n", FATOffset ) ;
     printf( "簇N在FAT16表中的扇区号 = %ld\n", ThisFATSecNum ) ;
     #endif
     
     s = mReadSector( ThisFATSecNum , 0x01, DISKBUF );
     if ( s != USB_INT_SUCCESS )
          return( ERR_List ) ;
     
     if ( ProcessMode == ModeZ2 )
     {     
          Cluster = ( UINT16 )DISKBUF[ ThisFATEntOffset ] | ( UINT16 )DISKBUF[ ThisFATEntOffset + 1 ] << 8 ;
          return( Cluster ) ;
     }
     else  if ( ProcessMode == ModeZ1 )
     {
          DISKBUF[ ThisFATEntOffset ] = ( UINT8 )value ;
		        DISKBUF[ ThisFATEntOffset + 1 ] = ( UINT8 )( value >> 8 ) ;  
		        s = mWriteSector( ThisFATSecNum , 0x01, DISKBUF );
		        if ( s != USB_INT_SUCCESS )
		             return( ERR_List ) ;    
          return( ListSuccess ) ;
     } 
}

/*********************************************************************************************************
** 函数名称: x16CheckClus
** 功能描述: FAT16查可写簇以便写入数据
**
** 输 入: 无
** 输 出: 返回找到的可写簇簇号
**           A.返回ERR_CheckClus报告异常传输错误
**           B.若磁盘簇已写满,返回簇号0
**         
** 全局变量: FAT.RsvdSecCnt, FAT.FirstRootSector, FAT.BytesPerSec
** 调用模块: mReadSector, mWriteSector
** 调试码:   无
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT16  x16CheckClus( void ) 
{
     UINT8  s ;
     UINT8  FindFlag ;                  //查找成功标记
     UINT8  *POINT0 ;
     UINT16 Cluster ;                   
     UINT32 ProcessSector ;
     
     //初始化查找标记
     FindFlag = 0 ;
     
     for ( ProcessSector = FAT.RsvdSecCnt, POINT0 = DISKBUF + 4; ProcessSector < FAT.FirstRootSector; ProcessSector ++ )
     {
          s = mReadSector( ProcessSector, 0x01, DISKBUF );       //每次读取一个扇区的FAT表到DISKBUF中
		        if ( s != USB_INT_SUCCESS )
		             return( ERR_CheckClus ) ;
          
          for ( ; POINT0 < DISKBUF + FAT.BytesPerSec; POINT0 += 2 )   //在DISKBUF里查找可写簇
          {
               if( ! ( *POINT0 ) && ! ( *( POINT0 + 1 ) ) )
               {
                    FindFlag = 1 ;
                    break ;
               }
          }
          //判断本次查找情况:
          //  A. 查到可写簇 -- 跳出查找循环
          //  B. 没有查到 -- 重置DISK_BUF内偏移量,继续下一次查找循环
          if( ! FindFlag )
          {
               POINT0 = DISKBUF ;
               continue ;
          }
          break ;
     }
     
     //查找结束,根据结果判断返回值
     //  A. 找到簇,返回实际簇号
     //  B. 磁盘簇已写满,返回0x00
     if( FindFlag )

⌨️ 快捷键说明

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