《基于51单片机FAT32文件系统程序.doc》由会员分享,可在线阅读,更多相关《基于51单片机FAT32文件系统程序.doc(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、基于51单片机FAT32文件系统程序基于51单片机FAT32文件系统程序ifndef _ZNFAT_H_define _ZNFAT_H_#include mytype。h” /类型重定义/*/ /znFAT的裁减宏-/#define ZNFAT_ENTER_DIR /有此宏,函数 znFAT_Enter_Dir() 参与编译#define ZNFAT_OPEN_FILE /有此宏,函数 znFAT_Open_File() 参与编译/#define ZNFAT_SEEK_FILE /有此宏,函数 znFAT_Seek_File() 参与编译/#define ZNFAT_READ_FILE /有此
2、宏,函数 znFAT_Read_File() 参与编译/#define ZNFAT_READ_FILEX /有此宏,函数 znFAT_Read_FileX() 参与编译/define ZNFAT_ADD_DAT /有此宏,函数 znFAT_Add_Dat() 参与编译/define ZNFAT_CREATE_DIR /有此宏,函数 znFAT_Create_Dir() 参与编译/#define ZNFAT_CREATE_FILE /有此宏,函数 znFAT_Create_File() 参与编译/#define ZNFAT_DEL_FILE /有此宏,函数 znFAT_Del_File() 参与
3、编译/#define ZNFAT_XCOPY_FILE /有此宏,函数 znFAT_XCopy_File() 参与编译/#define ZNFAT_RENAME_FILE /有此宏,函数 znFAT_Rename_File() 参与编译/#define ZNFAT_GET_TOTAL_SIZE /有此宏,函数 znFAT_Get_Total_Size() 参与编译/#define znFAT_GET_REMAIN_CAP /有此宏,函数 znFAT_Get_Remain_Cap() 参与编译include ”cj.hinclude ”cj.h/-define SOC(c) ((cpArgFir
4、stDirClust)(pArg-SectorsPerClust))+pArg-FirstDirSector) / 用于计算簇的开始扇区#define CONST const/设备表#define SDCARD 0 /SD卡#define UDISK 1 /U盘define CFCARD 2 /CF卡define OTHER 3 /其它 /这里的存储设备表,可以灵活扩充,以实现对更多存储设备的支持/-define MAKE_FILE_TIME(h,m,s)(((unsigned int)h)11)+(unsigned int)m)1))/ 生成指定时分秒的文件时间数据 /define MAKE
5、_FILE_DATE(y,m,d)((((unsigned int)y)+20)9)+((unsigned int)m)5)+((unsigned int)d))/* 生成指定年月日的文件日期数据 /DPT:分区记录结构如下struct PartRecord UINT8 Active; /0x80表示此分区有效 UINT8 StartHead; /分区的开始磁头 UINT8 StartCylSect2;/开始柱面与扇区 UINT8 PartType; /分区类型 UINT8 EndHead; /分区的结束头 UINT8 EndCylSect2; /结束柱面与扇区 UINT8 StartLBA4
6、; /分区的第一个扇区 UINT8 Size4; /分区的大小 ;/MBR:分区扇区(绝对0扇区)定义如下struct PartSector UINT8 PartCode446; /MBR的引导程序 struct PartRecord Part4; /4个分区记录 UINT8 BootSectSig0; /55 UINT8 BootSectSig1; /AA;/znFAT中对BPB的定义如下 一共占用90个字节struct znFAT_BPB UINT8 BS_jmpBoot3; /跳转指令 offset: 0 UINT8 BS_OEMName8; / offset: 3 UINT8 BPB_
7、BytesPerSec2;/每扇区字节数 offset:11 UINT8 BPB_SecPerClus1; /每簇扇区数 offset:13 UINT8 BPB_RsvdSecCnt2; /保留扇区数目 offset:14 UINT8 BPB_NumFATs1; /此卷中FAT表数 offset:16 UINT8 BPB_RootEntCnt2; /znFAT为0 offset:17 UINT8 BPB_TotSec162; /znFAT为0 offset:19 UINT8 BPB_Media1; /存储介质 offset:21 UINT8 BPB_FATSz162; /znFAT为0 off
8、set:22 UINT8 BPB_SecPerTrk2; /磁道扇区数 offset:24 UINT8 BPB_NumHeads2; /磁头数 offset:26 UINT8 BPB_HiddSec4; /FAT区前隐扇区数 offset:28 UINT8 BPB_TotSec324; /该卷总扇区数 offset:32 UINT8 BPB_FATSz324; /一个FAT表扇区数 offset:36 UINT8 BPB_ExtFlags2; /znFAT特有 offset:40 UINT8 BPB_FSVer2; /znFAT特有 offset:42 UINT8 BPB_RootClus4;
9、 /根目录簇号 offset:44 UINT8 FSInfo2; /保留扇区FSINFO扇区数offset:48 UINT8 BPB_BkBootSec2; /通常为6 offset:50 UINT8 BPB_Reserved12; /扩展用 offset:52 UINT8 BS_DrvNum1; / offset:64 UINT8 BS_Reserved11; / offset:65 UINT8 BS_BootSig1; / offset:66 UINT8 BS_VolID4; / offset:67 UINT8 BS_FilSysType11; / offset:71 UINT8 BS_F
10、ilSysType18; /znFAT offset:82;struct znFAT_FAT_Item UINT8 Item4;;struct znFAT_FAT struct znFAT_FAT_Item Items128;;struct direntry UINT8 deName8; / 文件名,不足部分以空格补充 UINT8 deExtension3; / 扩展名,不足部分以空格补充 UINT8 deAttributes; / 文件属性 UINT8 deLowerCase; / 0 UINT8 deCHundredth; / 世纪 UINT8 deCTime2; / 创建时间 UINT8
11、 deCDate2; / 创建日期 UINT8 deADate2; / 访问日期 UINT8 deHighClust2; / 开始簇的高字 UINT8 deMTime2; / 最近的修改时间 UINT8 deMDate2; / 最近的修改日期 UINT8 deLowCluster2; / 开始簇的低字 UINT8 deFileSize4; / 文件大小 ;/znFAT初始化时初始参数装入如下结构体中struct znFAT_Init_Arg UINT8 DEV_No; UINT8 BPB_Sector_No; /BPB所在扇区号 UINT32 Total_Size; /磁盘的总容量 UINT3
12、2 FirstDirClust; /根目录的开始簇 UINT32 BytesPerSector;/每个扇区的字节数 UINT32 FATsectors; /FAT表所占扇区数 UINT32 SectorsPerClust; /每簇的扇区数 UINT32 FirstFATSector; /第一个FAT表所在扇区 UINT32 FirstDirSector; /第一个目录所在扇区;struct Date UINT16 year; UINT8 month; UINT8 day;;struct Time UINT8 hour; UINT8 min; UINT8 sec;;struct FileInfo
13、Struct UINT8 FileName15; /文件名 UINT32 FileStartCluster; /文件的开始簇 UINT32 FileCurCluster;/文件的当前簇 UINT32 FileSize; /文件大小 UINT32 FileCurSector; /文件的当前扇区 UINT16 FileCurPos; /文件在当前扇区中的位置 UINT32 FileCurOffset; /文件的当前偏移量 UINT32 Rec_Sec; /文件的文件/目录项所在的扇区 UINT16 nRec; /文件的文件/目录项所在扇区中的位置 UINT8 FileAttr; /文件属性 str
14、uct Time FileCreateTime; /文件的创建时间 struct Date FileCreateDate; /文件的创建日期 struct Time FileMTime; /文件的修改时间 struct Date FileMDate; /文件的修改日期 struct DateFileADate; /文件的访问日期;struct FSInfo /znFAT的文件系统信息结构 UINT8 Head4; UINT8 Resv1480; UINT8 Sign4; UINT8 Free_Cluster4; UINT8 Last_Cluster4; UINT8 Resv214; UINT8
15、 Tail2;;extern struct znFAT_Init_Arg pArg; /初始化参数结构体指针,用以指向某一存储设备的初始化参数结构体,由外部提供extern UINT8 Dev_No;/设备号,外部变量/函数声明void znFAT_Device_Init();UINT32 znFAT_Get_Total_Size(void); /获取总容量UINT32 znFAT_Get_Remain_Cap(void); /获取剩余容量void znFAT_Init(void); /文件系统初始化UINT32 znFAT_Enter_Dir(CONST INT8 path); /进入目录U
16、INT8 znFAT_Open_File(struct FileInfoStruct pfi,CONST INT8 *filepath,UINT32 item,UINT8 is_file); /打开文件,支持通配UINT8 znFAT_Seek_File(struct FileInfoStruct pfi,UINT32 offset); /文件定位 UINT32 znFAT_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf); /读取文件数据UINT32 znFAT_Read_FileX(stru
17、ct FileInfoStruct pfi,UINT32 offset,UINT32 len,void (*pfun)(UINT8); /读取文件数据并进行数据处理UINT32 znFAT_Add_Dat(struct FileInfoStruct pfi,UINT32 len,UINT8 pbuf); /向文件追加数据UINT8 znFAT_Create_Dir(CONST INT8 dirpath,UINT8 ptd); /创建目录,支持创建时间UINT8 znFAT_Create_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,U
18、INT8 ptd); /创建文件,支持创建时间UINT8 znFAT_Del_File(CONST INT8 filepath); /删除文件unsigned char znFAT_XCopy_File(struct znFAT_Init_Arg pArg1,struct znFAT_Init_Arg *pArg2,CONST INT8 sfilename,CONST INT8 tfilename,UINT8 file_buf,UINT32 buf_size,unsigned char pt); /文件拷贝,支持多设备中文件互拷UINT8 znFAT_File_Close(struct Fil
19、eInfoStruct *pfi); /文件关闭UINT8 znFAT_Rename_File(CONST INT8 *filename,CONST INT8 newfilename); /文件重命名#endif#include ”znfat。h”include sd。h /存储设备的扇区读写驱动,这里是SD卡/#include ”ch375。h” /存储设备的扇区读写驱动,这里是U盘/#include ”cf.h”/存储设备的扇区读写驱动,这里是CF盘include ”string.h/全局变量定义struct direntry temp_rec;INT8 temp_dir_name13;
20、UINT32 temp_dir_cluster;UINT32 temp_last_cluster;UINT8 znFAT_Buffer512; /扇区数据读写缓冲区,由外部提供/* 功能描述:znFAT的存储设备初始化函数 - 隶属模块:znFAT文件系统模块 - 函数属性:外部(用于对存储设备进行初始化) - 参数说明:无 返回说明:无 注:在调znFAT其它函数之前,必须先对存储设备进行成功的初始化。 */void znFAT_Device_Init() SD_Reset(); SD_Init(); /* 功能描述:znFAT的存储设备底层驱动接口,读取存储设备的addr扇区的 512个字
21、节的数据放入buf数据缓冲区中 - 隶属模块:znFAT文件系统模块 - 函数属性:内部(用于与存储设备的底层驱动对接) 参数说明:addr:扇区地址 buf:指向数据缓冲区的指针 返回说明:0表示读取扇区成功,否则失败 注:这里加入了天狼星精华板上的三种存储设备,即SD卡(有效)、U盘、 CF卡通过在程序中动态的切换不同的设备驱动,从而实现多设备(即同 时对多种存储设备进行操作,比如从SD卡拷贝文件到U盘等等),不同 驱动的切换,只需要在程序中改变Dev_No这个全局变量的值即可 */UINT8 znFAT_ReadSector(UINT32 addr,UINT8 buf) switch(D
22、ev_No)/由Dev_No来决定所使用的存储设备驱动 case SDCARD: return SD_Read_Sector(addr,buf); break; case UDISK: /return CH375_Read_Sector(addr,buf); break; case CFCARD: /return CF_Read_Sector(addr,buf); break; case OTHER: /return XXX_Read_Sector(addr,buf); break; /* 功能描述:znFAT的存储设备底层驱动接口,将buf数据缓冲区中的512个 字节的数据写入到存储设备的a
23、ddr扇区中 隶属模块:znFAT文件系统模块 函数属性:内部(用于与存储设备的底层驱动对接) 参数说明:addr:扇区地址 buf:指向数据缓冲区 - 返回说明:0表示读取扇区成功,否则失败 注:略 */UINT8 znFAT_WriteSector(UINT32 addr,UINT8 buf) switch(Dev_No)/由Dev_No来决定所使用的存储设备驱动 case SDCARD: return SD_Write_Sector(addr,buf); break; case UDISK: /return CH375_Write_Sector(addr,buf); break; cas
24、e CFCARD: /return CF_WriteSector(addr,buf); break; case OTHER: /return XXX_Write_Sector(addr,buf); break; /* - 功能描述:小端转大端,即LittleEndian车BigEndian 隶属模块:znFAT文件系统模块 - 函数属性:内部 - 参数说明:dat:指向要转为大端的字节序列 len:要转为大端的字节序列长度 - 返回说明:转为大端模式后,字节序列所表达的数据 - 注:比如:小端模式的 0x33 0x22 0x11 0x00 (低字节在前) 转为大端模式后为 0x00 0x11
25、0x22 0x33 (高字节在前) 所表达的数值为 0x00112233 (CISC的CPU通常是小端的,所以znFAT也设计为小端,而单片机 这种RISC的CPU,通常来说都是大端的,所以需要这个函数将字 节的存放次序进行调整,才能得到正确的数值) */UINT32 LE2BE(UINT8 *dat,UINT8 len) UINT32 temp=0; UINT32 fact=1; UINT8 i=0; for(i=0;ilen;i+) temp+=datifact; /将各字节乘以相应的权值后累加 fact*=256; /更新权值 return temp;/* - 功能描述:清空某个簇的所有
26、扇区,填充0 隶属模块:znFAT文件系统模块 函数属性:内部 - 参数说明:cluster:要清空的簇的簇号 - 返回说明:无 */ifdef ZNFAT_EMPTY_CLUSTERvoid znFAT_Empty_Cluster(UINT32 Cluster) UINT32 iSec; UINT16 i; for(i=0;iBytesPerSector;i+) znFAT_Bufferi=0; for(iSec=SOC(Cluster);iSecSectorsPerClust;iSec+) znFAT_WriteSector(iSec,znFAT_Buffer); #endif/* 功能描
27、述:获取剩余容量 隶属模块:znFAT文件系统模块 函数属性:外部,使用户使用 - 参数说明:无 - 返回说明:剩余容量,单位字节 注:从FSInfo中读取空闲簇数,而从计算得到剩余的容量,单位字节 */ifdef znFAT_GET_REMAIN_CAPUINT32 znFAT_Get_Remain_Cap(void) znFAT_ReadSector(1+pArgBPB_Sector_No,znFAT_Buffer); if(((struct FSInfo )znFAT_Buffer)-Free_Cluster0=0xff & ((struct FSInfo )znFAT_Buffer)F
28、ree_Cluster1=0xff & ((struct FSInfo )znFAT_Buffer)-Free_Cluster2=0xff & ((struct FSInfo )znFAT_Buffer)Free_Cluster3=0xff) return pArg-Total_Size; else return LE2BE((struct FSInfo *)znFAT_Buffer)-Free_Cluster,4)pArg-SectorsPerClust*pArg-BytesPerSector; endif/* 功能描述:将小字字符转为大写 隶属模块:znFAT文件系统模块 - 函数属性:内
29、部 - 参数说明:c:要转换为大写的字符 返回说明:要转换的字节的相应的大写字符 - 注:只对小写字符有效,如果不是az的小写字符,将直接返回 */INT8 L2U(INT8 c) if(c=a & c=z) return c+A-a; else return c;/* 功能描述:得到DBR所在的扇区号(如果没有MBR,则DBR就在0扇区) 隶属模块:znFAT文件系统模块 - 函数属性:内部 参数说明:无 返回说明:DBR的扇区地址 - 注:DBR中包含了很多有用的参数信息,因此正确定位DBR扇区的位置,是极为 重要的,后面将有专门的函数对DBR进行解析,正确解析DBR是实现znFAT的 基
30、础 */UINT16 znFAT_Find_DBR(void) UINT16 sec_dbr; znFAT_ReadSector(0,znFAT_Buffer); if(znFAT_Buffer0!=0xeb) sec_dbr=LE2BE((((struct PartSector *)(znFAT_Buffer))-Part0).StartLBA),4); else sec_dbr=0; return sec_dbr;/* 功能描述:获取分区的总容量 隶属模块:znFAT文件系统模块 - 函数属性:外部,使用户使用 - 参数说明:无 返回说明:分区容量值,单位为字节 注:这里得到的总容量是zn
31、FAT分区的容量,一定小于实际的物理容量 */ifdef ZNFAT_GET_TOTAL_SIZEUINT32 znFAT_Get_Total_Size(void) return pArg-Total_Size;endif/* 功能描述:读取FSInfo获取最近的一个可用空闲簇 - 隶属模块:znFAT文件系统模块 - 函数属性:内部 - 参数说明:无 返回说明:最近的一个可用空闲簇 注:znFAT中的FSInfo扇区(绝对1扇区)中记录了最近的一个可用空闲簇 */UINT32 Search_Last_Usable_Cluster(void) znFAT_ReadSector(1+pArg-B
32、PB_Sector_No,znFAT_Buffer); return LE2BE(struct FSInfo )znFAT_Buffer)Last_Cluster,4);/* - 功能描述:znFAT文件系统初始化 - 隶属模块:znFAT文件系统模块 - 函数属性:外部,使用户使用 - 参数说明:znFAT_Init_Arg类型的结构体指针,用于装载一些重要的参数信息, 以备后面使用 返回说明:无 注:在使用znFAT前,这个函数是必须先被调用的,将很多参数信息装入到 arg指向的结构体中,比如扇区大小、根目录的位置、FAT表大小等等。 这些参数绝大部分是来自于DBR的BPB中,因此此函数主
33、要在作对DBR的参数解析 */void znFAT_Init(void) struct znFAT_BPB bpb; bpb=(struct znFAT_BPB )(znFAT_Buffer); /将数据缓冲区指针转为struct znFAT_BPB 型指针 pArg-DEV_No=Dev_No; /装入设备号 pArg-BPB_Sector_No =znFAT_Find_DBR(); /znFAT_FindBPB()可以返回BPB所在的扇区号 znFAT_ReadSector(pArg-BPB_Sector_No,znFAT_Buffer); pArg-FATsectors =LE2BE(b
34、pbBPB_FATSz32) ,4);/装入FAT表占用的扇区数到FATsectors中 pArgFirstDirClust =LE2BE(bpbBPB_RootClus) ,4);/装入根目录簇号到FirstDirClust中 pArgBytesPerSector =LE2BE(bpbBPB_BytesPerSec),2);/装入每扇区字节数到BytesPerSector中 pArgSectorsPerClust =LE2BE((bpbBPB_SecPerClus) ,1);/装入每簇扇区数到SectorsPerClust 中 pArgFirstFATSector =LE2BE((bpbBP
35、B_RsvdSecCnt) ,2)+pArgBPB_Sector_No;/装入第一个FAT表扇区号到FirstFATSector 中 pArgFirstDirSector =(pArgFirstFATSector)+(bpbBPB_NumFATs0)*(pArgFATsectors); /装入第一个目录扇区到FirstDirSector中 pArg-Total_Size =LE2BE(bpbBPB_TotSec32),4)pArgBytesPerSector; /磁盘的总容量,单位是字节 temp_last_cluster=Search_Last_Usable_Cluster();/* - 功能描述:更新FSInfo中的可用空闲簇的数量 - 隶属模块:znFAT文件系统模块 函数属性:内部 - 参数说明:PlusOrMinus:可用空闲簇数加1或减1