📄 sd_fat.c
字号:
/* 读取指定扇区数据 */
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 + -