?? ch375hft.c
字號:
mDelaymS( 1 ); /* 寫后延時,可選的,大多數U盤不需要 */
memcpy( FILE_DATA_BUF+0, FILE_DATA_BUF+(total & ~ 511), total & 511 ); /* 將剛才已寫入U盤的零頭數據復制到緩沖區的頭部 */
total &= 511; /* 緩沖區中只剩下剛才已寫入U盤的零頭數據,繼續保留在緩沖區中是為了方便以后在其后面追加數據 */
if ( total ) NewSize = CH375vFileSize - 512 + total; /* 以扇區為單位,有零頭數據,計算出真正的文件長度(有效數據的長度) */
else NewSize = CH375vFileSize; /* 以扇區為單位,沒有零頭數據,文件長度是512的倍數 */
mCmdParam.Modify.mFileSize = NewSize; /* 輸入參數: 新的文件長度,扇區模式下涉及到零頭數據不便自動更新長度 */
mCmdParam.Modify.mFileAttr = 0xff; /* 輸入參數: 新的文件屬性,為0FFH則不修改 */
mCmdParam.Modify.mFileTime = 0xffff; /* 輸入參數: 新的文件時間,為0FFH則不修改 */
mCmdParam.Modify.mFileDate = 0xffff; /* 輸入參數: 新的文件日期,為0FFH則不修改 */
i = CH375FileModify( ); /* 修改當前文件的信息,修改文件長度 */
mStopIfError( i );
printf( "Current file size is %ld\n", CH375vFileSize );
mCmdParam.Locate.mSectorOffset = 0xffffffff; /* 移到文件的尾部,以扇區為單位,所以會忽略文件尾部的零頭數據 */
i = CH375FileLocate( ); /* 重新回到原文件的尾部,下面如果再寫入數據將覆蓋尾部零頭數據,不過該零頭數據有一份副本保留在緩沖區中,所以請放心 */
mStopIfError( i );
}
else if ( total >= FILE_DATA_BUF_LEN - 512 ) { /* 緩沖區中的數據快要滿了,所以應該先將緩沖區中的原有數據寫入U盤 */
mCmdParam.Write.mSectorCount = total >> 9; /* 將緩沖區中的字節數轉換為扇區數(除以512),最后的零頭數據先不管 */
i = CH375FileWrite( ); /* 以扇區為單位向文件寫入數據,寫入緩沖區中的所有數據,不含最后的零頭 */
mStopIfError( i );
memcpy( FILE_DATA_BUF+0, FILE_DATA_BUF+(total & ~ 511), total & 511 ); /* 將剛才未寫入U盤的零頭數據復制到緩沖區的頭部 */
total &= 511; /* 緩沖區中只剩下剛才未寫入U盤的零頭數據 */
/* mCmdParam.Write.mSectorCount = 0; 如果全局變量CH375LibConfig的位4為0,可以指定寫入0扇區,用于刷新文件的長度
CH375FileWrite( ); 以扇區為單位向文件寫入數據,因為是0扇區寫入,所以只用于更新文件的長度,當階段性寫入數據后,可以用這種辦法更新文件長度 */
}
}
main( ) {
UINT8 i, month, date, hour;
UINT16 year, adc;
LED_OUT_INIT( );
LED_OUT_ACT( ); /* 開機后LED亮一下以示工作 */
mDelaymS( 100 ); /* 延時100毫秒 */
LED_OUT_INACT( );
mInitSTDIO( ); /* 為了讓計算機通過串口監控演示過程 */
printf( "Start\n" );
i = CH375LibInit( ); /* 初始化CH375程序庫和CH375芯片,操作成功返回0 */
mStopIfError( i );
/* 其它電路初始化 */
while ( 1 ) {
printf( "Wait Udisk\n" );
while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態,等待U盤插入 */
LED_OUT_ACT( ); /* LED亮 */
mDelaymS( 200 ); /* 延時,可選操作,有的USB存儲器需要幾十毫秒的延時 */
/* 檢查U盤是否準備好,有些U盤不需要這一步,但是某些U盤必須要執行這一步才能工作 */
for ( i = 0; i < 10; i ++ ) { /* 有的U盤總是返回未準備好,不過可以被忽略 */
mDelaymS( 100 );
printf( "Ready ?\n" );
if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢磁盤是否準備好 */
}
/* 查詢磁盤物理容量 */
printf( "DiskSize\n" );
i = CH375DiskSize( );
mStopIfError( i );
printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec >> 11 ) ); /* 顯示為以MB為單位的容量 */
LED_RUN_ACT( ); /* 開始操作U盤 */
/* 如果MY_ADC.TXT文件已經存在則添加數據到尾部,如果不存在則新建文件 */
printf( "Open\n" );
mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "/MY_ADC.TXT" ); /* 文件名,該文件在根目錄下 */
i = CH375FileOpen( ); /* 打開文件 */
if ( i == ERR_SUCCESS ) { /* 文件存在并且已經被打開,移動文件指針到尾部以便添加數據 */
printf( "File size = %ld\n", CH375vFileSize ); /* V1.5以上子程序庫在成功打開文件后,全局變量CH375vFileSize中是文件當前長度 */
printf( "Locate tail\n" );
mCmdParam.Locate.mSectorOffset = 0xffffffff; /* 移到文件的尾部,CH375子程序庫內部是將文件長度按扇區長度512進行取整處理 */
i = CH375FileLocate( ); /* 以扇區為單位移到文件尾部,如果文件尾部有不足一個扇區的零頭數據則被忽略,如果不做處理那么零頭數據將可能被寫入數據覆蓋 */
mStopIfError( i );
total = CH375vFileSize & 511; /* 上次保存文件時如果尾部有零頭數據,那么先取得零頭字節數,不滿扇區長度的零碎數據 */
printf( "Read last tail = %d Bytes\n", total );
CH375vFileSize += 511; /* 人為地將文件長度增加一個扇區減1,以便讀出最后一個扇區中的零頭數據 */
mCmdParam.Read.mSectorCount = 1; /* 讀取文件尾部的零頭數據,如果不人為增加文件長度,那么由于文件長度按512取整,導致尾部零頭數據無法讀出 */
i = CH375FileRead( ); /* 從文件讀取尾部零頭數據,如果原尾部沒有零頭數據,那么什么也讀不到,返回時mCmdParam.Read.mSectorCount為實際讀出扇區數 */
mStopIfError( i );
CH375vFileSize -= 511; /* 恢復真正的文件長度 */
mCmdParam.Locate.mSectorOffset = 0xffffffff; /* 移到文件的尾部,以扇區為單位,所以會忽略文件尾部的零頭數據 */
i = CH375FileLocate( ); /* 重新回到原文件的尾部,下面如果寫入數據將覆蓋原尾部零頭數據,不過原零頭數據剛才已經被讀入內存,所以請放心 */
mStopIfError( i );
}
else if ( i == ERR_MISS_FILE ) { /* 沒有找到文件,必須新建文件 */
LED_WR_ACT( ); /* 寫操作 */
printf( "Create\n" );
// mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/MY_ADC.TXT" ); /* 文件名,該文件在根目錄下,剛才已經提供給CH375FileOpen */
i = CH375FileCreate( ); /* 新建文件并打開,如果文件已經存在則先刪除后再新建 */
mStopIfError( i );
total = 0; /* 此前沒有零頭數據 */
}
else mStopIfError( i ); /* 打開文件時出錯 */
LED_WR_ACT( ); /* 寫操作 */
printf( "Write begin\n" );
total += sprintf( FILE_DATA_BUF + total, "在本次添加數據之前,該文件已有數據的長度是 %ld 字節\xd\xa", CH375vFileSize ); /* 將新數據添加到緩沖區的尾部,累計緩沖區內的數據長度 */
mFlushBufferToDisk( 0 ); /* 自動刷新緩沖區,檢查緩沖區是否已滿,滿則寫盤 */
printf( "Write ADC data\n" );
TR0=1; /* 用定時器0的計數值代替ADC數據 */
for ( month = 1; month != 12; month ++ ) { /* 因為測試板上沒有實時時鐘芯片,所以用循環方式模擬月份 */
for ( date = 1; date != 30; date ++ ) { /* 因為測試板上沒有實時時鐘芯片,所以用循環方式模擬日期 */
year = 2004; /* 假定為2004年 */
hour = TL1 & 0x1F; /* 因為測試板上沒有實時時鐘芯片,所以用定時器1的計數代替進行演示 */
/* adc = get_adc_data( ); */
adc = ( (UINT16)TH0 << 8 ) | TL0; /* 因為測試板上沒有ADC,所以用定時器0的計數代替ADC數據演示 */
total += sprintf( FILE_DATA_BUF + total, "Year=%04d, Month=%02d, Date=%02d, Hour=%02d, ADC_data=%u\xd\xa", year, (UINT16)month, (UINT16)date, (UINT16)hour, adc ); /* 將二制制數據格式為一行字符串 */
if ( month == 6 && ( date & 0x0F ) == 0 ) mFlushBufferToDisk( 1 ); /* 強制刷新緩沖區,定期強制刷新緩沖區,這樣在突然斷電后可以減少數據丟失 */
else mFlushBufferToDisk( 0 ); /* 自動刷新緩沖區,檢查緩沖區是否已滿,滿則寫盤 */
printf( "Current total is %d\n", total ); /* 用于監控檢查 */
}
}
printf( "Write end\n" );
total += sprintf( FILE_DATA_BUF + total, " ********************************* " ); /* 將新數據添加到緩沖區的尾部,累計緩沖區內的數據長度 */
total += sprintf( FILE_DATA_BUF + total, "這次的ADC數據到此結束,程序即將退出\xd\xa" ); /* 將新數據添加到緩沖區的尾部,累計緩沖區內的數據長度 */
mFlushBufferToDisk( 1 ); /* 強制刷新緩沖區,因為系統要退出了,所以必須強制刷新 */
printf( "Close\n" );
mCmdParam.Close.mUpdateLen = 0; /* 因為強制刷新緩沖區時已經更新了文件長度,所以這里不需要自動更新文件長度 */
i = CH375FileClose( ); /* 關閉文件 */
mStopIfError( i );
LED_WR_INACT( );
LED_RUN_INACT( );
printf( "Take out\n" );
while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態,等待U盤拔出 */
LED_OUT_INACT( ); /* LED滅 */
mDelaymS( 200 );
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -