2013年4月23日 星期二

FatFs使用修改

FatFs可以動作:讀取檔案、寫出檔案皆有執行。


但寫出檔案的日期有問題,因為沒有RTC故無時間資料。


時間資料可以給一個固定值,但固定值由人來填寫不太有利。


利用C語言中的__TIME____DATE__來做為時間常數。


__TIME__的格式為”hh:mm:ss”


是固定的ASCII碼,所以轉成數值無問題。


__DATE__的格式為”Mmm dd yy”


dd yy也是ASCII也無問題。


Mmm為三個英文字,要轉成1~12變得很麻煩。


三個英文字要分成12個月,只要判定後二字就可以分。


只好寫一個switch case去做12個月字母去分類。


最後將__TIME____DATE__const字串去存。


設定有最佳化的Compiler設定後,可以看到反組譯的結果為:


   \                     get_fattime:


   \   00000000   0x....             LDR.N    R0,??DataTable7_4  ;; 0x42938746


   \   00000002   0x4770             BX       LR               ;; return


結果只有二個指令,只回傳定值。


寫了近90行程式,只會編成二個指令,就是4Byte


測試寫入檔案的時間是對的,會是編譯的時間。


程式碼:


#define DC(t,a,b)   (((a)<<8)+(b))
unsigned char const Date[] = __DATE__;
unsigned char const Time[] = __TIME__;

DWORD get_fattime (void)
{
    BYTE rtcYear , rtcMon , rtcMday, rtcHour, rtcMin, rtcSec;
    DWORD time;

#ifdef USE_FS_RTC
    RTC_TimeTypeDef   RTC_TimeStructure;
    RTC_DateTypeDef   RTC_DateStructure;
    /* Get info from RTC here */
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);

    rtcSec    =  RTC_TimeStructure.RTC_Seconds;
    rtcMin    =  RTC_TimeStructure.RTC_Minutes;
    rtcHour   =  RTC_TimeStructure.RTC_Hours;

    RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);

    rtcYear =  RTC_DateStructure.RTC_Year;
    rtcMon =  RTC_DateStructure.RTC_Month;
    rtcMday =  RTC_DateStructure.RTC_Date;
#else
    rtcSec    =  ((Time[6]-'0')*10+(Time[7]-'0'));
    rtcMin    =  ((Time[3]-'0')*10+(Time[4]-'0'));
    rtcHour   =  ((Time[0]-'0')*10+(Time[1]-'0'));
    rtcYear   =  ((Date[9]-'0')*10+(Date[10]-'0')+20);


    rtcMday   =  (Date[4]==' ')? (Date[5]-'0'): ((Date[4]-'0')*10+(Date[5]-'0'));
    switch ((Date[1]<<8)+Date[2])
    {
    case DC('J','a','n') :
        rtcMon = 1;
        break;
    case DC('F','e','b') :
        rtcMon = 2;
        break;
    case DC('M','a','r') :
        rtcMon = 3;
        break;
    case DC('A','p','r') :
        rtcMon = 4;
        break;
    case DC('M','a','y') :
        rtcMon = 5;
        break;
    case DC('J','u','n') :
        rtcMon = 6;
        break;
    case DC('J','u','l') :
        rtcMon = 7;
        break;
    case DC('A','u','g') :
        rtcMon = 8;
        break;
    case DC('S','e','p') :
        rtcMon = 9;
        break;
    case DC('O','c','t') :
        rtcMon = 10;
        break;
    case DC('N','o','v') :
        rtcMon = 11;
        break;
    case DC('D','e','c') :
        rtcMon = 12;
        break;
    default :
        rtcMon = 1;
        break;
    }
#endif
    /* Pack date and time into a DWORD variable */
    time =      (((DWORD)rtcYear) << 25)
             | ((DWORD)rtcMon << 21)
             | ((DWORD)rtcMday << 16)
             | (WORD)(rtcHour << 11)
             | (WORD)(rtcMin << 5)
             | (WORD)(rtcSec >> 1);
    return time;
}







1 則留言:

  1. 在有些編譯器上日期格式雖然是”Mmm dd yy”
    但會顯示成這樣:"Dec  1 2013" 而不是顯示"Dec 01 2013"
    這時候 ((Date[4]-'0')*10+(Date[5]-'0'))會出大問題
    [版主回覆06/21/2013 09:37:41]確實有這個問題。
    我記得二週後有發現,沒有立刻改就忘了。
    所以現在使用中的程式碼也是錯的。
    有Bug真的要馬上改。

    回覆刪除