最近由于玩STM32,里面原子的实例用到FAT系统,所以专门花了几天时间(只能抽业余时间)研究了FAT系统,发现原子实例中对FAT初始化代码有些问题,后咨询原子,经原子的反映,有些网友的SD卡也用不了,所以今晚就花了点时间重新整理了一下这个FAT初始化函数,经原子测试,原本不能用的SD卡可以使用了,现在把代码共享出来,让更多的M3友可以共享,如SD卡还不能用,可以跟贴反映。以下是代码(内含详细注释):
//以下FAT_Init1()函数为螃蟹重写的FAT初始化函数
u8 dat[512];
u8 FAT_Init1(void)
{
bootsector710 *bs = 0; //定义DBR结构体,包含BPB部分(12~90字节是BPB)
bpb710 *bpb = 0; //定义BPB结构体
partrecord *pr = 0; //定义硬盘信息 结构休 (16字节)
DWORD hidsec=0; //隐藏的扇区数即为DBR在物理扇区的偏移量
u32 Capacity;
Capacity = SD_GetCapacity(); //得到SD容量,单位为字节
if(Capacity<0xff)return 1;
if(SD_ReadSingleBlock(0,fat_buffer))return 2; //读物理扇区0。即MBR(其中MBR内的硬盘分区表中有DBR的地址信息),如没有MBR,则为DBR。经测试,我的SD卡是有MBR的
if(fat_buffer[0]!=0XEB&&fat_buffer[0]!=0XE9) //如物理0扇区第一字节不为0XEB或0XE9,则存在MBR,否则不存在
{
printf("此SD卡的物理扇区0为MBR\n");
pr = (partrecord *)((partsector *)fat_buffer)->psPart;//first partition 第一分区
hidsec=pr->prStartLBA; //隐藏的扇区 即DBR的物理扇区偏移
printf("此SD卡的DBR的物理扇区为=%d\n",hidsec) ;
}
else
{
hidsec=0; //无MBR,物理扇区0即为DBR
printf("此SD卡不存在MBR,物理扇区0即为DBR,物理扇区0即为逻辑扇区0.\n");
}
if(SD_ReadSingleBlock(hidsec,fat_buffer))return 3; //取DBR数据,512字节
printf("DBR物理扇区偏移量:%d \n",hidsec);
bs = (bootsector710 *)fat_buffer;
bpb = (bpb710 *)bs->bsBPB;
if(bpb->bpbFATsecs)//detemine thd FAT type //do not support FAT12
{
FAT32_Enable=0; //FAT16
FATsectors = bpb->bpbFATsecs;//FAT表占用的扇区数
FirstDirClust = 2;
}
else
{
FAT32_Enable=1; //FAT32
FATsectors = bpb->bpbBigFATsecs;//FAT占用的扇区数
FirstDirClust = bpb->bpbRootClust;
}
BytesPerSector = bpb->bpbBytesPerSec; //每扇区字节数
SectorsPerClust = (BYTE)bpb->bpbSecPerClust;//每簇扇区数
FirstFATSector = bpb->bpbResSectors+hidsec;//第一个FAT表扇区
RootDirCount = bpb->bpbRootDirEnts; //根目录项数
RootDirSectors = (RootDirCount*32)>>9; //根目录占用的扇区数
FirstDirSector = FirstFATSector+bpb->bpbFATs*FATsectors;//第一个目录扇区
FirstDataSector = FirstDirSector+RootDirSectors;//第一个数据扇区
printf("每扇区字节数:%d \n",BytesPerSector);
printf("每簇扇区数:%d \n",SectorsPerClust);
printf("第一个FAT表扇区:%d \n",FirstFATSector);
printf("根目录项数:%d \n",RootDirCount);
printf("根目录占用的扇区数:%d \n",RootDirSectors);
return 0;
} |