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

📄 sd_fat.c

📁 本代码主要是完成了一套基于FAT16
💻 C
📖 第 1 页 / 共 3 页
字号:

/* 读取指定扇区数据 */
void SD_DiskRead(void *buffer, UINT32 start, UINT16 count)
{
    FILE *fp;

    start += FatBpbStart;                           /* 绝对扇区换算成逻辑扇区 */
    start <<= 9;
    fp = fopen("jd.f16", "rb+");
    fseek(fp, start, SEEK_SET);
    fread(buffer, 512, count, fp);
    fclose(fp);

}


/* 写入指定扇区数据 */
void SD_DiskWrite(void *buffer, UINT32 start, UINT16 count)
{
    FILE *fp;

    start += FatBpbStart;                           /* 绝对扇区换算成逻辑扇区 */
    start <<= 9;
    fp = fopen("jd.f16", "rb+");
    fseek(fp, start, SEEK_SET);
    fwrite(buffer, 512, count, fp);
    fclose(fp);

}




/*******************************************************************************/
/* 进行被SDK初始化    */
void SD_InitMyFat(UINT8 Mode)
{
    UINT8   buffer[512];
    BOOT16  boot;

    SD_DiskRead(buffer, 0, 1);

    switch (Mode)
    {
        case JDFatMade: memcpy(&FatBpbStart, &buffer[454], 1); break;/*把buffer中的一个字节拷贝到FatBpbStart中*/
        case LJFatMade: FatBpbStart = 0; break;
    }

    SD_DiskRead(&boot, 0, 1);
    FatSecPerClus = boot.BPB_SecPerClus;            /* 记录每簇扇区数   */
    FatRsvdSecCnt = boot.BPB_RsvdSecCnt;            /* 记录保留扇区数   */
    FatFATSz = boot.BPB_FATSz16;                    /* 记录每FAT扇区数  */
    FatRootEntCnt = boot.BPB_RootEntCnt;            /* 记录根项目最大数 */
}


/* 打开文件,内包括解析目录 */
SD_FILE *SD_fopen(UINT8 *Dir, UINT8 Mode)
{
    UINT8   l, key = 0, t = 0, CmpStr[11], CreatIndex;
    UINT16  i, j, CuIndex, CuIndex2, CuIndexCreat = 0, OldFatIndex, *CuValue;
    SD_FILE *fp;
    DIR     Dirs[16];
    

    /* 将字符串化为大写字母 */
    strupr(Dir);


    /* Dir格式::\\......   */
    if (((*Dir)!=':') || ((*(++Dir))!=92)) return NULL;


    fp = (SD_FILE *)malloc(sizeof(SD_FILE));
    fp->FileSeek = 0;                /* 文件位置指针调在最前端 */
    memset(CmpStr, 32, 11);
    while (1)
    {
        switch (*(++Dir))
        {
            case 92:                /* \\ ************************************************************************/

                if (key == 0)               /* 说明是根目录         */
                {
                    key = 1;
                    for (i = 0; i < FatRootEntCnt/16; i++)
                    {
                        SD_DiskRead(Dirs, FatRsvdSecCnt+FatFATSz*2+i, 1);
                        for (j = 0; j < 16; j++)
                        {
                            if ((Dirs[j].DIR_Attr & 0x10) != 0x10) continue;    /* 若不为目录直接到下一个 */
                            for (l = 0; l < 11; l++)
                                if (Dirs[j].DIR_Name[l] != CmpStr[l]) break;

                            if (l == 11)    /* 说明找到匹配的文件名 */
                            {
                                CuIndex = Dirs[j].DIR_LFstClus;                 /* 记录此目录从第几簇开始 */
                                goto OUT1;
                            }
                        }	
                    }

                    free(fp);
                    return NULL;        /* 说明没有找到此根目录 */

OUT1: ;/********/
                }
                else
                {
OUT3:/**********/
                    for (i = 0; i < FatSecPerClus; i++)
                    {
                        SD_DiskRead(Dirs, FatRsvdSecCnt+FatFATSz*2+FatRootEntCnt/16+(CuIndex-2)*FatSecPerClus+i, 1);
                        for (j = 0; j < 16; j++)
                        {
                            if ((Dirs[j].DIR_Attr & 0x10) != 0x10) continue;    /* 若不为目录直接到下一个 */
                            for (l = 0; l < 11; l++)
                                if (Dirs[j].DIR_Name[l] != CmpStr[l]) break;

                            if (l == 11)    /* 说明找到匹配的文件名 */
                            {
                                CuIndex = Dirs[j].DIR_LFstClus;                 /* 记录此目录从第几簇开始 */
                                goto OUT2;
                            }
                        }
                    }
                    
                    SD_DiskRead(Dirs, FatRsvdSecCnt+CuIndex/256, 1);
                    CuValue = (UINT16 *)Dirs;
                    if (CuValue[CuIndex%256] == 0xFFFF)                         /* 说明没有此目录,返回空 */
                    {
                        free(fp);
                        return NULL;
                    }
                    else                                                        /* 继续搜索下一簇         */
                    {
                        CuIndex = CuValue[CuIndex%256];
                        goto OUT3;
                    }
OUT2: ; /**********/
                }
                memset(CmpStr, 32, 11);
                t = 0;
                break;

            case '.':                       /* .                    **************************************************/
                t = 8;
                break;
                                            /*************************************************************************/
            default:
                if (t == 11)
                {
                    free(fp);
                    return NULL;
                }
                CmpStr[t++] = *Dir;
                    
        }

        if ((*(Dir+1)) == '\0')
        {
            if (key == 0)                   /* 说明在根目录下       */
            {
                for (i = 0; i < FatRootEntCnt/16; i++)
                {
                    SD_DiskRead(Dirs, FatRsvdSecCnt+FatFATSz*2+i, 1);
                    for (j = 0; j < 16; j++)
                    {
                        for (l = 0; l < 11; l++)
                            if (Dirs[j].DIR_Name[l] != CmpStr[l]) break;

                        /* 若为创建文件 */
                        if (Mode == CRWBinary)
                        {
                            /* 说明找到名匹配的目录,不能创建文件 */
                            if (l == 11 && (Dirs[j].DIR_Attr & 0x10) == 0x10)
                            {
                                free(fp);
                                return NULL;
                            }
                        }


                        if ((Dirs[j].DIR_Attr & 0x20) != 0x20) continue;    /* 若不为文件直接到下一个 */
                        if (l == 11)        /* 说明找到匹配的文件名 */
                        {
                            switch (Mode)
                            {
                                case ORWBinary:     /* 以读写方式打开二进制文件 */
                                    fp->FDT_Num = FatRsvdSecCnt+FatFATSz*2+i;
                                    fp->FDT_Index = j;

                                    fp->FileSize = Dirs[j].DIR_FileSize;
                                    fp->FileStart = Dirs[j].DIR_LFstClus;
                                    return fp;                                 /* 记录相关信息并返回     */


                                case DelFile:       /* 删除指定文件             */
                                case CRWBinary:     /* 以读写方式创建二进制文件 */
                                    fp->FDT_Num = FatRsvdSecCnt+FatFATSz*2+i;
                                    fp->FDT_Index = j;
                                    fp->FileSize = 0;
                                    fp->FileStart = CuIndex = Dirs[j].DIR_LFstClus;

                                    /* 改写文件条目信息 */
                                    Dirs[j].DIR_FileSize = Dirs[j].DIR_LFstClus = 0;
                                    SD_DiskWrite(Dirs, FatRsvdSecCnt+FatFATSz*2+i, 1);




                                    /* 若为删除文件 */
                                    if (Mode == DelFile)
                                    {   
                                        Dirs[j].DIR_Name[0] = 0xE5;
                                        SD_DiskWrite(Dirs, FatRsvdSecCnt+FatFATSz*2+i, 1);
                                    }


                                    if (CuIndex > 0)    /* 说明此文件存在内容 */
                                    {

OUT6: /*****************************/
                                        OldFatIndex = CuIndex/256;
                                        SD_DiskRead(Dirs, FatRsvdSecCnt+OldFatIndex, 1);
                                        CuValue = (UINT16 *)Dirs;

OUT7: /*********************************/
                                        if ((CuIndex2=CuValue[CuIndex%256]) != 0xFFFF)
                                        {
                                            CuValue[CuIndex%256] = 0;
                                            CuIndex = CuIndex2;

                                            if (OldFatIndex != CuIndex/256)
                                            {
                                                SD_DiskWrite(Dirs, FatRsvdSecCnt+OldFatIndex, 1);
                                                goto OUT6;
                                            }
                                            else
                                            {
                                                goto OUT7;
                                            }
                                        }
                                        else
                                        {
                                            CuValue[CuIndex%256] = 0;
                                            SD_DiskWrite(Dirs, FatRsvdSecCnt+OldFatIndex, 1);
                                        }

                                        return fp;
                                    }
                                    else                /* 不存在内容,开始搜索空闲簇 */
                                    {
                                        /* 若为删除文件 */
                                        if (Mode == DelFile) return fp;


                                        for (i = 0; i < FatFATSz; i++)
                                        {
                                            SD_DiskRead(Dirs, FatRsvdSecCnt+i, 1);
                                            CuValue = (UINT16 *)Dirs; 
                                            for (j = 0; j < 256; j++)
                                            {
                                                if (CuValue[j] == 0x0000)       /* 说明找到空闲位置 */
                                                {
                                                    fp->FileStart = i*256+j;    /* 记录此文件开始簇 */
                                                    return fp;
                                                }
                                            }
                                        }

                                        free(fp);
                                        return NULL;    /* 说明空间不足,退出 */
                                    }

                            }
                        }
                    }
                }

                switch (Mode)
                {
                    case DelFile:       /* 删除指定文件,没找到指定文件     */
                    case ORWBinary:
                        free(fp);
                        return NULL;                /* 说明没有此文件返回空 */

                    case CRWBinary:                 /* 新建此文件           */
                        for (i = 0; i < FatFATSz; i++)
                        {
                            SD_DiskRead(Dirs, FatRsvdSecCnt+i, 1);
                            CuValue = (UINT16 *)Dirs;
                            for (j = 0; j < 256; j++)
                            {
                                if (CuValue[j] == 0x0000)       /* 说明找到空闲位置 */
                                {
                                    fp->FileSize = 0;
                                    fp->FileStart = i*256+j;     /* 记录此文件开始簇 */
                                    

                                    /* 搜索是否有空闲条目位置 */
                                    for (i = 0; i < FatRootEntCnt/16; i++)

⌨️ 快捷键说明

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