📄 sdfilelib.c
字号:
SPI0DAT = 0xfe; //Start Byte
while(!SPIF);
SPIF = 0;
for (n=0;n<512;n++) //512+2 Bytes CRC(Don't Care)
{
SPI0DAT =FAT32_Buffer[n];
while(!SPIF);
SPIF = 0;
}
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
if((SPI0DAT & 0x1F)!=0x05) // xxx0 0101b
CS=1; //Failed!
do
{
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
}
while (SPI0DAT!=0xff); //Busy
CS=1;
/*if((SPI0DAT & 0x1F)==0x05)
CS=1;
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;*/
}
//---------------------------------------------------------------------------
/*void FAT32_Init(struct FAT32_Init_Arg *Arg )
{
struct FAT32_BPB *bpb=(struct FAT32_BPB *)(FAT32_Buffer); //将数据缓冲区指针转为struct FAT32_BPB 型指针
se=0;
Read_SD_Sector(se);
Arg->Total_Sectors =Little_To_Big((bpb->BPB_TotSec32) ,4); //????? //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆
Arg->FATsectors =Little_To_Big((bpb->BPB_FATSz32) ,4); //装入FAT表占用的扇区数到FATsectors中
Arg->FirstDirClust =Little_To_Big((bpb->BPB_RootClus) ,4); //装入根目录簇号到FirstDirClust中
Arg->BytesPerSector =Little_To_Big((bpb->BPB_BytesPerSec),2); //装入每扇区字节数到BytesPerSector中
Arg->SectorsPerClust =Little_To_Big((bpb->BPB_SecPerClus) ,1); //装入每簇扇区数到SectorsPerClust 中
Arg->FirstFATSector =Little_To_Big((bpb->BPB_RsvdSecCnt) ,2); //装入第一个FAT表扇区号到FirstFATSector 中
// Arg->RootDirCount =Little_To_Big((bpb->BPB_RootEntCnt) ,2); //装入根目录项数到RootDirCount中
// Arg->RootDirSectors =(Arg->RootDirCount)*32>>9; //装入根目录占用的扇区数到RootDirSectors中
Arg->FirstDirSector =(Arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(Arg->FATsectors); //装入第一个到FirstDirSector中
Arg->FirstDataSector =(Arg->FirstDirSector)+(Arg->SectorsPerClust); //装入第一个数据扇区到FirstDataSector中,目录扇区与数据扇区相差一个簇
}*/
void FAT32_Init()
{
struct FAT32_BPB *bpb=(struct FAT32_BPB *)(FAT32_Buffer); //将数据缓冲区指针转为struct FAT32_BPB 型指针
se=0;
Read_SD_Sector(se);
Init_Arg1.Total_Sectors =Little_To_Big((bpb->BPB_TotSec32) ,4); //????? //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆
Init_Arg1.FATsectors =Little_To_Big((bpb->BPB_FATSz32) ,4); //装入FAT表占用的扇区数到FATsectors中
Init_Arg1.FirstDirClust =Little_To_Big((bpb->BPB_RootClus) ,4); //装入根目录簇号到FirstDirClust中
Init_Arg1.BytesPerSector =Little_To_Big((bpb->BPB_BytesPerSec),2); //装入每扇区字节数到BytesPerSector中
Init_Arg1.SectorsPerClust =Little_To_Big((bpb->BPB_SecPerClus) ,1); //装入每簇扇区数到SectorsPerClust 中
Init_Arg1.FirstFATSector =Little_To_Big((bpb->BPB_RsvdSecCnt) ,2); //装入第一个FAT表扇区号到FirstFATSector 中
// Arg->RootDirCount =Little_To_Big((bpb->BPB_RootEntCnt) ,2); //装入根目录项数到RootDirCount中
// Arg->RootDirSectors =(Arg->RootDirCount)*32>>9; //装入根目录占用的扇区数到RootDirSectors中
Init_Arg1.FirstDirSector =(Init_Arg1.FirstFATSector)+(bpb->BPB_NumFATs[0])*(Init_Arg1.FATsectors); //装入第一个到FirstDirSector中
Init_Arg1.FirstDataSector =(Init_Arg1.FirstDirSector)+(Init_Arg1.SectorsPerClust); //装入第一个数据扇区到FirstDataSector中,目录扇区与数据扇区相差一个簇
}
//--------------------------------------------------------------------------------
//-----------------小端转为大端----------------------------------
unsigned long Little_To_Big(unsigned char *dat,unsigned char len)
{
unsigned long temp=0;
unsigned long fact=1;
unsigned char i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact*=256;
}
return temp;
}
ulong FAT32_GetNextCluster(ulong LastCluster)
{
ulong temp;
struct FAT32_FAT *pFAT;
struct FAT32_FAT_Item *pFAT_Item;
temp=((LastCluster/128)+Init_Arg1.FirstFATSector);
//计算给定簇号对应的簇项的扇区号
se=temp;
Read_SD_Sector(se);
pFAT=(struct FAT32_FAT *)FAT32_Buffer;
pFAT_Item=&((pFAT->Items)[LastCluster%128]);
//在算出的扇区中提取簇项
return Little_To_Big((unsigned char*)pFAT_Item,4); //返回下一簇号
}
//------------匹配文件名,相同返回1,不同返回0-------------------
uchar file_name_compare(uchar *file_name,uchar *Name)
{
uchar i,a=0;
for(i=0;i<8;i++)
{
if(file_name[i]==Name[i])
a=1;
else
{
a=0;
break;
}
}
return a;
}
//---------------------打开文件数--------------------
/**/void filenum()
{
unsigned char i;
for(i=0;i<7;i++)
{
file_byte>>=1;
//file_byte|=0x80; //保持高位一直为‘1’
if(CY)
{
file_num=i;
file_byte<<=(i+1);
break;
}
}
}
//-----------------关闭文件---------------------
void fclose(unsigned pfile)
{
switch(pfile)
{
case 7: file_byte|=0x80; break;
case 6: file_byte|=0x40; break;
case 5: file_byte|=0x20; break;
case 4: file_byte|=0x10; break;
case 3: file_byte|=0x08; break;
case 2: file_byte|=0x04; break;
case 1: file_byte|=0x02; break;
case 0: file_byte|=0x01; break;
default: {}break;
}
}/*extern*/
//------------打开某个文件,文件名不足8个字节用空格表示--------------只能打开某个文件而不能创建,若没有该文件则返回值为0x5B
uchar fopen(char *file_name)
{
uchar name[8],a,b,flag=0;
ulong dir,i,emptyclust;
dir=Init_Arg1.FirstDirSector;
for(i=dir;i<dir+Init_Arg1.SectorsPerClust;i++)
{
se=i;
Read_SD_Sector(se);
for(a=0;a<16;a++)
{
for(b=0;b<8;b++)
name[b]=FAT32_Buffer[32*a+b];
if(file_name_compare(file_name,name)==1) //或if(file_name_compare(file_name,p))直接采用指针名即可,*p;p=&name[0]
{
filenum();
file[file_num].frist_clust=(FAT32_Buffer[32*a+21]*65536*256
+FAT32_Buffer[32*a+20]*65536 //得到文件的起始簇号
+FAT32_Buffer[32*a+27]*256
+FAT32_Buffer[32*a+26]);
//-------------文件位置定在初始位置------------------
file[file_num].current_clust=file[file_num].frist_clust;
file[file_num].current_sector=0;
file[file_num].current_byte=0;
//---------------------------------------------------
file[file_num].file_size=(FAT32_Buffer[32*a+31]*65536*256
+FAT32_Buffer[32*a+30]*65536 //得到文件的大小
+FAT32_Buffer[32*a+29]*256
+FAT32_Buffer[32*a+28]);
file[file_num].file_name_sector=se;
file[file_num].file_name_byte=32*a;
//file_num++
flag=1;
break;
}
else
{
flag=0;
//file_num=0x5B;
}
}
if(flag)
break;
}
if(flag)
return file_num;
else //没有文件时创建TXT文档
{
emptyclust=find_emptyclust();//找到一空簇
// se1=emptyclust;
for(i=dir;i<dir+Init_Arg1.SectorsPerClust;i++)
{
se=i;
Read_SD_Sector(se);
for(a=0;a<16;a++)
{
if(FAT32_Buffer[32*a]==0||FAT32_Buffer[32*a]==0xE5)
{
for(b=0;b<8;b++)
FAT32_Buffer[32*a+b]=file_name[b];
FAT32_Buffer[32*a+8]=0x54;
FAT32_Buffer[32*a+9]=0x58;
FAT32_Buffer[32*a+10]=0x54;
FAT32_Buffer[32*a+11]=0x20;
FAT32_Buffer[32*a+12]=0;
FAT32_Buffer[32*a+13]=0x68;
FAT32_Buffer[32*a+14]=0x70;
FAT32_Buffer[32*a+15]=0x80;
FAT32_Buffer[32*a+16]=0x96;
FAT32_Buffer[32*a+17]=0x39;
FAT32_Buffer[32*a+18]=0x96;
FAT32_Buffer[32*a+19]=0x39;
dir=emptyclust;
FAT32_Buffer[32*a+20]=(dir&0x00FF0000)>>16;
dir=emptyclust;
FAT32_Buffer[32*a+21]=(dir&0xFF000000)>>24;
FAT32_Buffer[32*a+22]=0x7E;
FAT32_Buffer[32*a+23]=0x7E;
FAT32_Buffer[32*a+24]=0x39;
FAT32_Buffer[32*a+25]=0x03;
dir=emptyclust;
FAT32_Buffer[32*a+26]=(dir&0x000000FF);
dir=emptyclust;
FAT32_Buffer[32*a+27]=(dir&0x0000FF00)>>8;
FAT32_Buffer[32*a+28]=4; //文件起始占4个字节
FAT32_Buffer[32*a+29]=0;
FAT32_Buffer[32*a+30]=0;
FAT32_Buffer[32*a+31]=0;
Write_SD_Sector(se);
filenum();
file[file_num].frist_clust=emptyclust; //得到文件的起始簇号
//-------------文件位置定在初始位置------------------
file[file_num].current_clust=file[file_num].frist_clust;
file[file_num].current_sector=0;
file[file_num].current_byte=0;
//---------------------------------------------------
file[file_num].file_size=4; //得到文件的大小
file[file_num].file_name_sector=se;
file[file_num].file_name_byte=32*a;
//file_num++
flag=1;
break;
}
else
flag=0;
}
if(flag)
break;
}
return file_num;
}
}
//------------------找到一个空簇-------------------
unsigned long find_emptyclust()
{
// static unsigned int Save_Fat_Sectors;
unsigned char flag=0,j;
unsigned long Clust_thing,current_clust,i;
struct FAT32_FAT *Test;
struct FAT32_FAT_Item *Test_Item,Test_Item_2={0xff,0xff,0xff,0x0f};
for(i=Init_Arg1.FirstFATSector;i<=Init_Arg1.FirstFATSector+Init_Arg1.FATsectors;i++)//查询整个FAT表中的空簇
{
se=i;
Read_SD_Sector(se);
Test=(struct FAT32_FAT*)FAT32_Buffer;
for(j=0;j<128;j++)
{
Test_Item=&(Test->Items[j]);
Clust_thing=Little_To_Big((unsigned char*)Test_Item,4);
if(Clust_thing==0) //找到一个空簇
{
Test->Items[j]=Test_Item_2; //创建一个簇
Write_SD_Sector(se);
current_clust=j+(i-Init_Arg1.FirstFATSector)*128; //计算该处簇号
flag=1;
break;
//return current_clust=j+(i-Init_Arg1.FirstFATSector)*128; //计算该处簇号
}
}
if(flag==1)
break;
}
return current_clust;
}
//------------移动文件指针的位置,确定在那一簇--------------------------------------
void fseek(uchar pfile,ulong len)
{
unsigned char i;
unsigned int a;
unsigned long m,n;
n=len;
m=file[pfile].frist_clust;
a=n/(Init_Arg1.SectorsPerClust*512);
//clust_num=a;
for(i=0;i<a;i++)
m=FAT32_GetNextCluster(m);
file[pfile].current_clust=m;
//====================查看的
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -