| 本帖最后由 petp 于 2014-11-16 21:22 编辑 
 petp 发表于 2014-11-16 18:52  ***************************
 复杂的open file 函数—— 第一个拦路虎
**************************
 把 Open file 再简单些
 
 ********************************
 
 上面的 open file 函数之所以显得很复杂,是因为 要 查到最后一级目录,相对于曲折了很多。
 
 如果直接打开根目录中的文件,函数就会简化很多。
 //自创函数,非znFAT中函数,只是为了展示open file 函数,而简化,类似伪代码
 
 UINT8 znFAT_Open_File_of_Root(structFileInfo *pfi)  {  UINT8 flag=0;  UINT32 sec_temp=0,Cur_Cluster=2,fn_pos=1;  UINT32 iSec=0,iFDI=0; INT8 *filename;    struct FDIesInSEC *pitems; //指向文件目录项扇区数据的指针  struct FDI *pitem; //指向文件目录项数据的指针   //================================================  do  {  sec_temp=SOC(Cur_Cluster); //当前簇首扇区  for(iSec=0;iSec<(pInit_Args->SectorsPerClust);iSec++)    {   znFAT_Device_Read_Sector(sec_temp+(UINT32)iSec,znFAT_Buffer);   pitems=(struct FDIesInSEC *)znFAT_Buffer;      for(iFDI=0;iFDI<NFDI_PER_SEC;iFDI++) //访问扇区中各文件目录项    {    pitem=&(pitems->FDIes[iFDI]); //指向一个文件目录项数据           To_File_Name((INT8*)(pitem->Name),temp_filename);  //将FDI中的文件名字段转为8.3文件名                     if(!SFN_Match(filename,temp_filename)) //短文件名通配            {             Analyse_FDI(pfi,pitem); //解析匹配的文件目录项              pfi->FDI_Sec=sec_temp+iSec; //文件目录项所在的扇区              pfi->nFDI=(UINT8)iFDI; //文件目录项在扇区中的索引              return ERR_SUCC;              flag=1;            }// if(!SFN_Match(filename,temp_filename))                }// for   }//for    Cur_Cluster=Get_Next_Cluster(Cur_Cluster); //获取下一簇  }while(!IS_END_CLU(Cur_Cluster)); //如果不是最后一个簇,则继续循环    return ERR_NO_FILE; 
 } 这个函数的核心是 Analyse_FDI(pfi,pitem); //解析匹配的文件目录项
 这样才能将文件相关参数填入文件信息集合,如目录创建时间等
 
 **************************************
 
 看起来非常简单的 文件目录项解析函数
 
 /************************************************************************  功能:解析一个文件目录项,将解析得到的参数装入到文件信息集合中  形参:pfi:指向文件信息集合的指针pFDI:指向文件目录项的指针  返回:0  详解:此函数被打开文件的函数调用,对符合匹配条件的文件目录项进行解析,并将参数装入到文件信       息集合中,以便对文件进行进一步的操作时使用。 *************************************************************************/ UINT8 Analyse_FDI(struct FileInfo*pfi,struct FDI *pFDI) {  UINT32 temp=0,i=0; just_file=pfi;   pfi->File_Attr=pFDI->Attributes; //文件属性  pfi->File_StartClust=Bytes2Value(pFDI->LowClust,2)+Bytes2Value(pFDI->HighClust,2)*65536;  pfi->File_Size=Bytes2Value(pFDI->FileSize,4);     //解析文件创建时间与日期  temp=Bytes2Value(pFDI->CTime,2);  pfi->File_CTime.sec=(UINT8)((temp&TIME_SEC_MARK)*2);temp>>=TIME_SEC_NBITS;  //创建时间的2秒位  pfi->File_CTime.min=(UINT8)(temp&TIME_MIN_MARK);   temp>>=TIME_MIN_NBITS; //创建时间的分位  pfi->File_CTime.hour=(UINT8)(temp&TIME_HOUR_MARK);//创建时间的时位  pfi->File_CTime.sec+=(UINT8)((UINT16)(pFDI->CTime10ms)/100);//在秒上加上10毫秒位    temp=Bytes2Value(pFDI->CDate,2);  pfi->File_CDate.day=(UINT8)(temp&DATE_DAY_MARK);     temp>>=DATE_DAY_NBITS;   //创建日期的日位  pfi->File_CDate.month=(UINT8)(temp&DATE_MONTH_MARK);temp>>=DATE_MONTH_NBITS; //创建日期的月位  pfi->File_CDate.year=(UINT16)((temp&DATE_YEAR_MARK)+DATE_YEAR_BASE);//创建日期的年位(加上年份基数)    pfi->File_CurClust=pfi->File_StartClust;  pfi->File_CurSec=(pfi->File_CurClust)?SOC(pfi->File_CurClust):0;  pfi->File_CurPos=0;  pfi->File_CurOffset=0;  pfi->File_IsEOF=(UINT8)((pfi->File_StartClust)?BOOL_FALSE:BOOL_TRUE);    return 0; } *************************************
 再回到主函数,
 。。。
 UART_Send_Num(fileinfo.File_CDate.year); UART_Send_Str("年");
 UART_Send_Num(fileinfo.File_CDate.month);UART_Send_Str("月");
 。。。。
 
 主函数中的结构体中数据就来自解析函数的贡献。
 
 |