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

📄 fat.c

📁 文件系统,运行硬件环境:单片机,软件环境:keilc
💻 C
📖 第 1 页 / 共 5 页
字号:
#define  PRODUCE_LOCAL_VARIABLES    /*完成对变量等定义*/
#include "FAT.H"

/*#define FAT_DEBUG*/               /*调试用*/
/*#define FAT_SHOW_DATA               输出一些有用的数据*/

/*基础接口函数*/
STATIC UINT8 hard_read_sector(UINT32 sector)
{
UINT8 i;
UINT8 cc = F_RE_TIME;

    while(cc)
    {
        i =RBC_Read(sector, 1, fat_disk_buffer);
        if(i == F_OK)
            return  F_OK;
        cc--;
    }
    return F_ERROR;
}/*读取一个扇区到磁盘缓存区*/

STATIC UINT8 hard_read_file_sector(UINT32 sector, UINT8 n, UINT8 offset)
{
UINT8 i;
UINT8 cc = F_RE_TIME;

    while(cc)
    {
        i =RBC_Read(sector, n, fat_file_buffer + (offset*512));
        if(i == F_OK)
            return  F_OK;
        cc--;
    }
    return  F_ERROR;
}/*读取一个扇区到磁盘缓存区*/

#if F_EN_WRITE ==1
STATIC UINT8 hard_write_sector(UINT32 sector)
{
UINT8 i;
UINT8 cc=F_RE_TIME;

    while(cc)
    {
        i =RBC_Write(sector, 1, fat_disk_buffer);
        if(i ==F_OK)
            return  F_OK;
        cc--;
    }
    return  F_ERROR;
}/*把磁盘缓存区里的数据写入U盘*/
#endif

#if F_EN_WRITE ==1
STATIC UINT8 hard_write_file_sector(UINT32 sector, UINT8 n, UINT8 offset)
{
UINT8 i;
UINT8 cc=F_RE_TIME;

    while(cc)
    {
        i =RBC_Write(sector, n, fat_file_buffer + (offset*512));
        if(i ==F_OK)
            return  F_OK;
        cc--;
    }
    return  F_ERROR;
}/*读取一个扇区到磁盘缓存区*/
#endif

STATIC UINT16 ushort_read_data(UINT16 i)
{
UINT16 d;
    #if MCU_USE_DSP ==1
    d =  fat_disk_buffer[i++];              /*读出低有效字节*/
    d |= (fat_disk_buffer[i]<<8);           /*高有效字节*/
    #else
    #if MCU_USE_BIG_ENDIAN == 1   /*默认为大端否则为小端*/
    ((UINT8 *)&d)[1] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[0] = fat_disk_buffer[i];
    #else
    ((UINT8 *)&d)[0] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[1] = fat_disk_buffer[i];
    #endif
    #endif
    return d;
}/*从磁盘缓存区里读取一个ushort型数,i为缓冲区位置索引*/

STATIC UINT32 ulong_read_data(UINT16 i)
{
UINT32 d;

    #if MCU_USE_DSP ==1
    d =  fat_disk_buffer[i++];              /*得到低有效字节*/
    d |= (fat_disk_buffer[i++]<<8);         /*得到低第二有效字节*/
    d |= ((UINT32)fat_disk_buffer[i++])<<16;
    d |= ((UINT32)fat_disk_buffer[i])<<24;
    #else
    #if MCU_USE_BIG_ENDIAN == 1
    ((UINT8 *)&d)[3] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[2] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[1] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[0] = fat_disk_buffer[i];
    #else
    ((UINT8 *)&d)[0] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[1] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[2] = fat_disk_buffer[i++];
    ((UINT8 *)&d)[3] = fat_disk_buffer[i];
    #endif
    #endif
    return d;
}/*从磁盘缓存区里读取一个ulong型数,i为缓冲区位置索引*/

#if F_EN_WRITE ==1
STATIC void ushort_write_data(UINT16 i,UINT16 d)
{
    #if MCU_USE_DSP ==1
    fat_disk_buffer[i++] = d&0x00ff;
    fat_disk_buffer[i]   = (d>>8)&0x00ff;
    #else
    #if MCU_USE_BIG_ENDIAN == 1
    fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
    fat_disk_buffer[i]   = ((UINT8 *)&d)[0];
    #else
    fat_disk_buffer[i++] = ((UINT8 *)&d)[0];
    fat_disk_buffer[i]   = ((UINT8 *)&d)[1];
    #endif
    #endif
}/*写入一个ushort型数到缓冲区,i为缓冲区位置索引*/
#endif

#if F_EN_WRITE ==1
STATIC void ulong_write_data(UINT16 i,UINT32 d)
{
    #if MCU_USE_DSP ==1
    fat_disk_buffer[i++] = d&0x000000ff;
    fat_disk_buffer[i++] = (d>>8)&0x000000ff;
    fat_disk_buffer[i++] = (d>>16)&0x000000ff;
    fat_disk_buffer[i]   = (d>>24)&0x000000ff;
    #else
    #if MCU_USE_BIG_ENDIAN == 1
    fat_disk_buffer[i++] = ((UINT8 *)&d)[3];
    fat_disk_buffer[i++] = ((UINT8 *)&d)[2];
    fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
    fat_disk_buffer[i]   = ((UINT8 *)&d)[0];
    #else
    fat_disk_buffer[i++] = ((UINT8 *)&d)[0];
    fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
    fat_disk_buffer[i++] = ((UINT8 *)&d)[2];
    fat_disk_buffer[i]   = ((UINT8 *)&d)[3];
    #endif
    #endif
}/*写入一个ulong型数到缓冲区,i为缓冲区位置索引*/
#endif

/*内部辅助函数*/
/*==============================================================================
函数名: file_name_deal
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:检测文件名是否合法,并初始化目录总深度(文件名不能小写,但可以汉字ANSI编码)
-------------------------------------------------------------------------------
由于考虑到汉字编码,所以没有对小写字母进行检测,使用时需要注意.
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 file_name_deal(void)
{
UINT8  len;
UINT8  i;
UINT8  cc;              /*用于检测文件名长度,是否是8+3格式*/

    cc =1;              /*此值默认为和法文件名长度*/
    fat_dir_all_l =0;   /*初始化目录深度初始为0*/
    for(len=0; len!=FAT_CMD_BUF_LEN; len++)
    {
        if(fat_cmd.open.buffer[len] == 0)               /*得到字符串长度*/
            break;
    }

    for(i=0; i!=len; i++)
    {
        if((fat_cmd.open.buffer[i] != '.') && (fat_cmd.open.buffer[i] != '\\')
            && (fat_cmd.open.buffer[i] != '/'))
            cc++;

        if((fat_cmd.open.buffer[i] == '\\') || (fat_cmd.open.buffer[i] == '/'))
        {
            if((cc > 11) || (cc == 0))
                return PARAMETER_CMD_ERR;               /*文件名不合法*/
            cc = 0;
            fat_dir_all_l++;                            /*计算打开目录深度*/
        }
    }

    if(fat_dir_all_l == 0)
    {
        return PARAMETER_CMD_ERR;
    }
    return F_OK;
}/* 文件名处理*/

/*==============================================================================
函数名: fat_read_cluster
-------------------------------------------------------------------------------
参数:(BOOL fat12_parity用于FAT12),对与FAT16/32不需要此值,bufferer_index为缓冲区里的偏移
-------------------------------------------------------------------------------
函数返回: 簇号
-------------------------------------------------------------------------------
函数作用: 从缓冲区里得到簇
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT32 fat_read_cluster (BOOL fat12_parity, UINT16 bufferer_index)
{
UINT32 temp32;

    #if F_USE_FAT32 == 1
    if(fat_type_sign == F_TYPE_FAT32)
    {
        temp32 = ulong_read_data(bufferer_index);
        temp32 &=0x0FFFFFFF;
        return temp32;
    }
    #endif

    #if F_USE_FAT16 == 1
    if (fat_type_sign == F_TYPE_FAT16)
    {
        temp32 = (UINT32)(ushort_read_data(bufferer_index));
        return temp32;
    }
    #endif

    #if F_USE_FAT12 == 1
    if(fat_type_sign == F_TYPE_FAT12)
    {
    UINT16 cluster;

        cluster=ushort_read_data(bufferer_index);
        if (fat12_parity == 0)      /*簇号是是偶数取低12-bits*/
        {
            temp32 = (UINT32)(cluster & 0x0FFF);
            return temp32;
        }
        else                        /*簇号为奇数取高12位*/
        {
            cluster = cluster >> 4;
            temp32 = (UINT32)cluster;
            return temp32;
        }
    }
    #else
    fat12_parity = 0;               /*为了让编译器不产生警告*/
    #endif
    return F_ERROR;                 /*为了让编译器不产生警告*/
}

/*==============================================================================
函数名: fat12_divid_cluster
-------------------------------------------------------------------------------
参数:i 为簇离FAT开始扇区的偏移
-------------------------------------------------------------------------------
函数返回: 簇号
-------------------------------------------------------------------------------
函数作用: 用在FAT12边界扇区时读簇号
-------------------------------------------------------------------------------
==============================================================================*/
#if F_USE_FAT12 == 1
STATIC UINT16  fat12_divid_cluster(UINT16 i)
{
UINT8  t;
UINT8  t2;
UINT8  temp8;
UINT16 new_cluster;

    t2 =i/SECTOR_SIZE;
    if((t2==0) || (t2==3) || (t2==6) || (t2==9))   /*2^12*1.5/512=12最多占用12个扇区*/
    {
        t =uchar_read_data(SECTOR_SIZE-1);   /*读取此簇的低4BIT*/
        t &=0XF0;
        t >>=4;                              /*取高4BIT*/
        temp8=hard_read_sector(fat_start_sector + i/SECTOR_SIZE + 1);
        if(temp8!=F_OK)
             return F_ERROR;
        temp8=uchar_read_data(0);            /*读取此簇的高8BIT*/
        new_cluster =(UINT16)temp8;
        new_cluster <<=4;

        new_cluster |=(UINT32)t;
        #ifdef FAT_DEBUG
        com_prints("###new_cluster0:",0);
        com_send_arry(&new_cluster,4,1);
        #endif
    }
    else
    {
        t = uchar_read_data(SECTOR_SIZE - 1);
        temp8 = hard_read_sector(fat_start_sector + i/SECTOR_SIZE + 1);
        if(temp8 != F_OK)
             return F_ERROR;
        temp8 =uchar_read_data(0);          /*读取此簇的高8BIT*/
        temp8 &=0X0F;                       /*取其高4BIT*/
        new_cluster =(UINT16)temp8;
        new_cluster <<=8;
        new_cluster |=(UINT16)t;
        #ifdef FAT_DEBUG
        com_prints("###new_cluster1:", 0);
        com_send_arry(&new_cluster, 4, 1);
        #endif
    }
    return new_cluster;
}
#endif

/*==============================================================================
函数名: fat_write_cluster
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:cluster_index为连续簇的开始,number为此簇之后有多少个连续的簇.而last_cluster
-------------------------------------------------------------------------------
为下个连续开始簇或结束簇,w_mode分为构建FAT表及清空FAT表
-------------------------------------------------------------------------------
==============================================================================*/
#if F_EN_WRITE ==1
STATIC UINT8 fat_write_cluster(UINT32 cluster_index, UINT16 number, UINT32 last_cluster, BOOL w_mode)
{
UINT8  temp8;
UINT16 index;
UINT32 temp32;

⌨️ 快捷键说明

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