fat.c

来自「Atmega64单片机程序(完整工程)」· C语言 代码 · 共 377 行

C
377
字号

#define   IN_FAT 

#include "SYS_Config.h" 
#include "SD_Config.h" 
#include "SD_Drive.h" 
#include "Fat.h" 


/*********************************************************************************************************
** 函数名称: FATGetNextClus
** 功能描述: 返回FAT表指定簇的下一个簇号
** 输   入: Drive:驱动器号
**           Index:簇号
** 输   出: 下一个簇号
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT32U FATGetNextClus(INT8U Drive,INT32U Index)
{
    INT16U temp,ByteIndex ;
    INT32U SecIndex ;
    INT8U  *Buf ;
    Disk_Info *Disk ;
    INT32U Rt ;
    
    Disk=GetDiskInfo(Drive);
    if(Disk==NULL)
    {
        return BAD_CLUS ;
    }
    
    if(Index>=(Disk->ClusPerData))
    {
        return BAD_CLUS ;
    }
    
    /* 计算扇区号和字节索引 */
    switch(Disk->FATType)
    {
        case FAT12 :
             SecIndex=Index*3/(2*Disk->BytsPerSec);
             ByteIndex=((Index*3)/2)-(SecIndex*Disk->BytsPerSec);
             SecIndex+=Disk->FATStartSec ;
             break ;
        case FAT16 :
             SecIndex=Index*2/Disk->BytsPerSec+Disk->FATStartSec ;
             ByteIndex=(Index*2)&(Disk->BytsPerSec-1);
             break ;
        case FAT32 :
             SecIndex=Index*4/Disk->BytsPerSec+Disk->FATStartSec ;
             ByteIndex=(Index*4)&(Disk->BytsPerSec-1);
             break ;
        default :
             return BAD_CLUS ;
    }
    
    Buf=OpenSec(Drive,SecIndex);
    if(Buf==NULL)
    {
        return BAD_CLUS ;
    }
    ReadSec(Drive,SecIndex);
    
    /* 读取FAT表数据 */
    switch(Disk->FATType)
    {
        case FAT12 :
             temp=Buf[ByteIndex];
             ByteIndex++;
             /* 下一个字节是否在下一个扇区 */
             if(ByteIndex>=Disk->BytsPerSec)
             {
                 Buf=OpenSec(Drive,SecIndex+1);
            	 if(Buf==NULL)
            	 {
                     return BAD_CLUS ;
            	 }
            	 ReadSec(Drive,SecIndex+1);
           	 temp=temp|((INT16U)Buf[0]<<8);
           	 CloseSec(Drive,SecIndex+1);
             }
       	     else 
             {
                 temp=temp|((INT16U)Buf[ByteIndex]<<8);
             }
             /* 判断哪12位有效 */
             if((Index&0x01)!=0)
             {
                 temp=temp/16 ;
             }
             else 
             {
                 temp=temp&0x0fff ;
             }
             Rt=temp ;
             /* 是否有特殊意义 */
             if(temp>=(BAD_CLUS&0x0fff))
             {
                 Rt=((INT32U)0x0fffL<<16)|(temp|0xf000);
             }
             break ;
        case FAT16 :
             temp=Buf[ByteIndex]|((INT16U)Buf[ByteIndex+1]<<8);
             Rt=temp ;
             /* 是否有特殊意义 */
             if(temp>=(BAD_CLUS&0xffff))
             {
                 Rt=((INT32U)0x0fffL<<16)|temp ;
             }
             break ;
        case FAT32 :
             Rt=Buf[ByteIndex]|((INT32U)Buf[ByteIndex+1]<<8);
             Rt|=((INT32U)Buf[ByteIndex+2]<<16)|((INT32U)Buf[ByteIndex+3]<<24);
             Rt=Rt&0x0fffffff ;
             break ;
        default :
             Rt=BAD_CLUS ;
             break ;
    }
    CloseSec(Drive,SecIndex);
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FATSetNextClus
** 功能描述: 设置下一个簇
**
** 输 入: Drive:驱动器号
**        Index:簇号
**        Next:下一个簇号
** 输 出: 无
**
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void FATSetNextClus(INT8U Drive,INT32U Index,INT32U Next)
{
    INT16U temp ;
    INT16U SecIndex,ByteIndex ;
    INT8U *Buf ;
    Disk_Info *Disk ;
    
    Disk=GetDiskInfo(Drive);
    if(Disk==NULL)
    {
        return ;
    }
    if(Index<=EMPTY_CLUS_1)
    {
        return ;
    }
    
    if(Index>=Disk->ClusPerData)
    {
        return ;
    }
    
    /* 计算扇区号和字节索引 */
    switch(Disk->FATType)
    {
        case FAT12 :
             SecIndex=Index*3/(2*Disk->BytsPerSec);
             ByteIndex=((Index*3)/2)-(SecIndex*Disk->BytsPerSec);
             SecIndex+=Disk->FATStartSec ;
             break ;
        case FAT16 :
             SecIndex=Index*2/Disk->BytsPerSec+Disk->FATStartSec ;
             ByteIndex=(Index*2)&(Disk->BytsPerSec-1);
             break ;
        case FAT32 :
             SecIndex=Index*4/Disk->BytsPerSec+Disk->FATStartSec ;
             ByteIndex=(Index*4)&(Disk->BytsPerSec-1);
             break ;
        default :
             return ;
    }
    
    Buf=OpenSec(Drive,SecIndex);
    if(Buf==NULL)
    {
        return ;
    }
    ReadSec(Drive,SecIndex);
    
    switch(Disk->FATType)
    {
        case FAT12 :
             temp=Next&0x0fff ;/* 判断哪12位有效 */
             if((Index&0x01)!=0)
             {
                 temp=temp*16 ;
            	 temp|=(Buf[ByteIndex]&0x0f);
            	 Buf[ByteIndex]=temp ;
             }
       	     else 
       	     {
                 Buf[ByteIndex]=temp ;
             }
             ByteIndex++;
             temp=temp>>8 ;
             /* 下一个字节是否在下一个扇区 */
             if(ByteIndex>=Disk->BytsPerSec)
             {
                 Buf=OpenSec(Drive,SecIndex+1);
                 if(Buf==NULL)
                     break ;
                 ReadSec(Drive,SecIndex+1);
                 /* 判断哪12位有效 */
                 if((Index&0x01)!=0)
                 {
                     Buf[0]=temp ;
                 }
                 else 
                 {
                     Buf[0]=(Buf[0]&0xf0)|temp ;
                 }
                 WriteSec(Drive,SecIndex+1);
                 CloseSec(Drive,SecIndex+1);
             }
             else 
             {
                 /* 判断哪12位有效 */
                if((Index&0x01)!=0)
                {
                    Buf[ByteIndex]=temp ;
                }
                else 
                {
                    Buf[ByteIndex]=(Buf[ByteIndex]&0xf0)|temp ;
                }
             }
             break ;
        case FAT16 :
             Buf[ByteIndex]=Next ;
             Buf[ByteIndex+1]=Next>>8 ;
             break ;
        case FAT32 :
             Buf[ByteIndex]=Next ;
             Buf[ByteIndex+1]=Next>>8 ;
             Buf[ByteIndex+2]=Next>>16 ;
             Buf[ByteIndex+3]=(Buf[ByteIndex+3]&0xf0)|((Next>>24)&0x0f);
             break ;
        default :
             break ;
    }
    WriteSec(Drive,SecIndex);
    CloseSec(Drive,SecIndex);
    return ;
}

/*********************************************************************************************************
** 函数名称: FATAddClus
** 功能描述: 为指定簇链增加一个簇
** 输   入: Drive:驱动器号
**           Index:簇链中任意一个簇号,如果为0,则为一个空链增加一个簇
** 输   出: 增加的簇号
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT32U FATAddClus(INT8U Drive,INT32U Index)
{
    INT32U NextClus,ThisClus,MaxClus ;
    Disk_Info *Disk ;
    
    Disk=GetDiskInfo(Drive);
    if(Disk==NULL)
    {
        return BAD_CLUS ;
    }
    
    if(Index>=BAD_CLUS)
    {
        return BAD_CLUS ;
    }
    
    
    MaxClus=Disk->ClusPerData ;
    
    /* 查找最后一个簇 */
    ThisClus=Index ;
    if(ThisClus!=EMPTY_CLUS&&ThisClus!=EMPTY_CLUS_1)
    {
        while(1)
        {
            NextClus=FATGetNextClus(Drive,ThisClus);
            if(NextClus>=EOF_CLUS_1)
            {
                break ;
            }
            if(NextClus<=EMPTY_CLUS_1)
            {
                break ;
            }
            if(NextClus==BAD_CLUS)
            {
                return BAD_CLUS ;
            }
            ThisClus=NextClus ;
        }
    }
    else 
    {
        ThisClus=EMPTY_CLUS_1 ;
    }
    
    for(NextClus=ThisClus+1;NextClus<MaxClus;NextClus++)
    {
        if(FATGetNextClus(Drive,NextClus)==EMPTY_CLUS)
        {
            break ;
        }
    }
    if(NextClus>=MaxClus)
    {
        for(NextClus=EMPTY_CLUS_1+1;NextClus<ThisClus;NextClus++)
        {
            if(FATGetNextClus(Drive,NextClus)==EMPTY_CLUS)
            {
                break ;
            }
        }
    }
    if(FATGetNextClus(Drive,NextClus)==EMPTY_CLUS)
    {
        if(ThisClus>EMPTY_CLUS_1)
        {
            FATSetNextClus(Drive,ThisClus,NextClus);
        }
        FATSetNextClus(Drive,NextClus,EOF_CLUS_END);
        return NextClus ;
    }
    else 
    {
        return BAD_CLUS ;
    }
}
/*********************************************************************************************************
** 函数名称: FATDelClusChain
** 功能描述: 删除指定簇链
** 输   入: Drive:驱动器号
**           Index:簇链中首簇号
** 输   出: 无
** 全局变量: 无
** 调用模块: FATGetNextClus,FATSetNextClus
********************************************************************************************************/
void FATDelClusChain(INT8U Drive,INT32U Index)
{
    INT32U NextClus,ThisClus ;
    
    if(Index<=EMPTY_CLUS_1)
    {
        return ;
    }
    if(Index>=BAD_CLUS)
    {
        return ;
    }
    ThisClus=Index ;
    while(1)
    {
        NextClus=FATGetNextClus(Drive,ThisClus);
        FATSetNextClus(Drive,ThisClus,EMPTY_CLUS);
        if(NextClus>=BAD_CLUS)
        {
            break ;
        }
        if(NextClus<=EMPTY_CLUS_1)
        {
            break ;
        }
        ThisClus=NextClus ;
    }
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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