基于FAT32系统的删除数据区数据

来源:互联网 发布:医院等级评审软件 编辑:程序博客网 时间:2024/05/29 13:04

首先给出我之前做的任务

在数据区删除对应的数据:
步骤分解:
(1)首先要在根目录找到起始簇

    例如以上图为例,文件名为ILLUST这个txt文件,他的起始簇即为06。

    具体如何找起始簇此文暂且不讨论。

(2)如果不止1簇,找到下一簇
(3)处理最后一簇

    假设我们已经找到起始簇,接下来的步骤就是:

    1、找到FAT表,读取一个簇的数据出来(4096个字节)


如图所画为第一簇、第二簇,依次类推。

    2、分析上图所画的对应簇的数据(4个字节为一个簇的标志符),将其转换成32为长字符,如第一簇转换后为:0FFFFFFF (小端存储)

    3、若为结束符,则删除该簇的数据(包括FAT表该簇数据、根目录对应簇数据4096个字节);若不为结束符,则按其指向簇继续查找,直至查找到结束符。


首先给出对SD卡读取的函数代码:

//******************************************************
//CMD17读SD卡单块数据命令
//´从第N扇区读取num个字节到buff对应的地址
//******************************************************
uchar CMD17(ulong N,uint offset,uint num,uchar *p)
{
uchar ACK=0xff,A3,A2,A1,A0;
uchar cnt1=0,cnt2=0;
uint i=0;
SD_CS=0; //拉低CS
if(num>512) //超过512字节
num=512; //按512字节处理
N=N<<9; //N也就是起始地址
N=N+(ulong)offset;//offset偏移地址
A3=(uchar)(N>>24);
A2=(uchar)(N>>16);
A1=(uchar)(N>>8);
A0=(uchar)N;


while(cnt1<10&&ACK!=0xfe)
{
cnt1++;cnt2=0;
W_BYTE(0x51,0);  //写入单块读命令
W_BYTE(A3,0); //这里A3,A2,A1为地址参数
W_BYTE(A2,0);   //A3Î为32位地址最高位
W_BYTE(A1,0);
W_BYTE(A0,0);
W_BYTE(0xff,0);
while(cnt2<30&&ACK!=0x00) //等待SD卡0X00的答复
{
cnt2++;
ACK=R_BYTE(0);
}
if(ACK==0x00)

cnt2=0;
while(cnt2<30&&ACK!=0xfe) //SD卡发送0XFE数据头
{
cnt2++;
ACK=R_BYTE(0);
}
if(ACK==0xfe) 
{
for(i=0;i<num;i++)  //开始读取512个字节数据
{
p[i]=R_BYTE(0);
}
if(num==512)
{
R_BYTE(0);
R_BYTE(0);
}
}
}
}
SD_CS=1;   //拉高CS
clock8(); //·发送8个空时钟
if(ACK==0xfe)
return(1);
else
return(0);
}

然后给出对SD卡写函数代码:

/*
功能:CMD24写SD卡单块数据命令
写入num个字节P到对应的地址N
*/
uchar CMD24(ulong N,uint offset,uint num,uchar *p)
{
uchar ACK=0xff,A3,A2,A1,A0;
uchar cnt1=0,cnt2=0;
uint i=0;


SD_CS=0;
if(num>512)
num=512;
    N=N<<9;
N=N+(ulong)offset;
A3=(uchar)(N>>24);
A2=(uchar)(N>>16);
A1=(uchar)(N>>8);
A0=(uchar)N;


while(cnt1<10&&ACK!=0x05)
{
cnt1++;
cnt2=0;
W_BYTE(0x58,0); 
W_BYTE(A3,0);
W_BYTE(A2,0);  
W_BYTE(A1,0);
W_BYTE(A0,0);
W_BYTE(0xff,0);
while(cnt2<30&&ACK!=0x00)
{
cnt2++;
ACK=R_BYTE(0);
}
if(ACK==0x00)

W_BYTE(0xfe,0);
for(i=0;i<num;i++)  //开始写入512个字节数据
{
W_BYTE(p[i],0);
}
if(num==512)
{
W_BYTE(0xff,0);
W_BYTE(0xff,0);
}
ACK=R_BYTE(0)&0x1f;
}
}


SD_CS=1;  
clock8();
if(ACK==0x05)
return(1);
else
return(0);
}

//******************************************************
//向SPI写一个字节x,速度由flag标志
//******************************************************
void W_BYTE(uchar x,uchar flag)
{
dat=x;


SD_CLK=1;
SD_DO=dat7;
if(flag)
DL(DELAY_TIME);
SD_CLK=0;
if(flag)
DL(DELAY_TIME);


SD_CLK=1;
SD_DO=dat6;
if(flag)
DL(DELAY_TIME);
SD_CLK=0;
if(flag)
DL(DELAY_TIME);


SD_CLK=1;SD_DO=dat5;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;SD_DO=dat4;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;SD_DO=dat3;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;SD_DO=dat2;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;SD_DO=dat1;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;SD_DO=dat0;if(flag) DL(DELAY_TIME);SD_CLK=0;if(flag) DL(DELAY_TIME);
SD_CLK=1;

//******************************************************
//从SPI读一个字节并返回,速度由flag标志
//******************************************************
uchar R_BYTE(uchar flag)
{ SD_CLK=1;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat7=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat6=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat5=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat4=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat3=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat2=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat1=SD_DI;if(flag) DL(DELAY_TIME);
SD_CLK=0;if(flag) DL(DELAY_TIME);SD_CLK=1;dat0=SD_DI;
SD_CLK=1;
return(dat);
}

//读整个簇数据

void Clus_Read(ulong x,uchar *Root)
{
uchar i=0;
for(i=0;i<SecPerClus;i++)  //SecPerClus=每簇扇区数(每个SD卡不同)
{
CMD17(x+i,0x0000,512,Root);  //x+i=簇数+每簇扇区偏移数=总的要读的扇区数
Root+=512; //0x0000为偏移地址
}  
}

//写每簇数据

void Clus_Write(ulong x,uchar *Root)
{
uchar i=0;
for(i=0;i<SecPerClus;i++)  //SecPerClus=每簇扇区数(每个SD卡不同)
{
CMD24(x+i,0x0000,512,Root);  //x+i=簇数+每簇扇区偏移数=总的要读的扇区数
Root+=512; //0x0000为偏移地址
}  

//清除根目录对应簇数据(Zero为4096长度数组,值为0)

void Clus_Clear(ulong x)
{
ulong i;
ulong Cu_Adr;
Cu_Adr = RootSec_No + ((x - 2)*8);
Clus_Write(Cu_Adr,Zero);
}

//清除FAT表对应簇数据,即写0

void Clus_Clear_FAT()
{
ulong temp = 9;//假设要删除簇的簇号为9
ulong CuNum = 0;
char i;
Clus_Read(FAT1_NO,Root);
do
{
CuNum = Root[temp*4+3];     //将FAT表对应簇的数据(4个字节)转换成长字符
for(i=2;i>=0;i--)
{
CuNum = CuNum<<8;
CuNum += Root[temp*4+i];
}
for(i=0;i<4;i++)//对应簇(即4个字节)清0
{
Root[temp*4+i]=0;
}
Clus_Clear(temp);//清除根目录对应簇的数据
temp = CuNum;
}while(CuNum !=0x0FFFFFFF);//若FAT表对应簇的标志符不为结束,则继续
Clus_Write(FAT1_NO,Root);//将更新的数据全部写进SD卡的FAT表
}


1 0
原创粉丝点击