我現(xiàn)在用了PHILIPS的P89V51RD2xx單片機,在之前做的板子上做讀寫U盤實驗,文件大小40K左右,晶振為24M,都是正常的,換了新板子,晶振為12M,單片機都為12clock模式,這樣,讀寫U盤就會有個別字節(jié)出現(xiàn)亂碼的現(xiàn)象,請問:這里面有什么要注意的地方?!
那你把晶振換成24M也會出現(xiàn)亂碼的現(xiàn)象嗎?這個和晶振沒有多大的關系,估計是的程序有問題
晶振換成24M不會出現(xiàn)亂碼現(xiàn)象的!
你用的是模擬I/O口的方式來讀寫U盤的話,如果是模擬I/O口的話,晶振速度太慢會出現(xiàn)出錯的問題的
在用12M晶振時,使用的單片機的雙時鐘模式,應該跟之前的是一樣的了,偶爾有個別字節(jié)的亂碼現(xiàn)象,試了幾塊板子都是這樣,有時候又是好的,感覺是不穩(wěn)定。用的128M的優(yōu)盤,F(xiàn)AT32文件系統(tǒng),這是不是不夠最優(yōu)?說是要優(yōu)先用FAT16文件系統(tǒng)!
你可以不可以將你的三個讀寫子程序帖出來看下??
CH375的詳細數(shù)據(jù)手冊,你們是不是封裝了國外的某個usb接口IC呀?我想自己寫一寫CH375的驅動
/* CH375 主機文件系統(tǒng)接口 */ /* 支持: FAT12/FAT16/FAT32 */ /* 讀取優(yōu)盤中第n個花樣文件 */
#include "CH375.H" #include"Memory.h"
UINT32I tempPos; UINT32I tempAddr;
#ifdef NO_DEFAULT_CH375_INT /* 自行編寫中斷處理程序,加上了超時處理,并且在等待中斷的過程中可以做其它事 */ void xQueryInterrupt( void ) /* 查詢CH375中斷并更新中斷狀態(tài),該程序基本框架可以參考CH375HF?.H文件 */ { UINT16 i; for ( i = 65535; i != 0; i -- ) { /* 正常情況下該過程為幾毫秒到幾十毫秒,偶爾也會達到幾百毫秒 */ if ( CH375_INT_WIRE == 0 ) break; /* 如果CH375的中斷引腳輸出低電平則說明CH375操作完成 */ 在等待CH375中斷的過程中,可以做些需要及時處理的事情 } if ( i == 0 ) CH375超時,通常是硬件問題; CH375_CMD_PORT = CMD_GET_STATUS; /* 獲取當前中斷狀態(tài) */ mDelay2uS( ); /* 操作無意義,用于至少延時2uS,可以用多個NOP空操作指令實現(xiàn) */ CH375IntStatus = CH375_DAT_PORT; /* 獲取中斷狀態(tài) */ if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT; /* 檢測到USB設備斷開事件 */ else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT; /* 檢測到USB設備連接事件 */ } #endif //================================================================================================== /* 以毫秒為單位延時,不精確,適用于24MHz時鐘 */ void mDelaymS( UINT8I delay ) { UINT8I i; UINT8I j; UINT8I c; for ( i = delay; i != 0; i -- ) { for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz時鐘下延時500uS */ for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz時鐘下延時500uS */ } } //================================================================================================== /* 將程序空間的字符串復制到內部RAM中,返回字符串長度 */ UINT8 mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); } //================================================================================================== /* 檢查操作狀態(tài),如果錯誤則顯示錯誤代碼并停機 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ while ( 1 ) { mDelaymS( 100 ); mDelaymS( 100 ); } } //================================================================================================== void host( UINT8I n )/*typedef unsigned char idata UINT8I;*/ { UINT8 str[4]; /* 用以存放花樣文件名*/ UINT32I i,c,d; /*typedef unsigned long idata UINT32I;*/ UINT32I TotalReadCount,TotalWriteCount;
tempPos = 0x0010000; tempAddr = 0x0010000;
i = CH375LibInit( ); /* 初始化CH375程序庫和CH375芯片,操作成功返回0 */ mDelaymS( 100 ); //等待初始化完成 mStopIfError( i ); while ( P1_0 == 0 ) { while ( CH375DiskStatus < DISK_CONNECT ) { /* 等待U盤插入 */ if ( P1_0 == 1 ) { return; } if ( CH375_INT_WIRE == 0 ) xQueryInterrupt( ); /* 如果CH375中斷,那么查詢CH375中斷并更新中斷狀態(tài),可以改成中斷方式 */ mDelaymS( 100 ); /* 沒必要頻繁查詢 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 查詢方式: 檢查磁盤是否連接,返回成功說明連接 */ } mDelaymS( 250 ); /* 延時,可選操作,有的USB存儲器需要幾十毫秒的延時 */ //================================================================================================== /* 檢查U盤是否準備好,有些U盤不需要這一步,但是某些U盤必須要執(zhí)行這一步才能工作 */ for ( i = 0; i < 5; i ++ ) { /* 有的U盤總是返回未準備好,不過可以被忽略 */ mDelaymS( 100 ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢磁盤是否準備好 */ } //================================================================================================== /* 讀取文件名為CONFID.TXT的花樣配置文件,獲得需要的第n個花樣文件名! */ i = mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "/CONFIG.TXT"); /* 搜索文件名,*為通配符,適用于所有文件或者子目錄*/ i = CH375FileOpen( ); /* 打開文件 */ mStopIfError( i ); if ( i == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已經沒有匹配的文件名 */ if ( i != ERR_SUCCESS ) break; /* 出錯 */
mCmdParam.ByteLocate.mByteOffset = (n-1)*4;/* 跳過文件的前(n-1)*4 個字節(jié)開始讀寫*/ CH375ByteLocate( ); mCmdParam.ByteRead.mByteCount = 4; /* 讀取4個字節(jié)(花樣的主文件名長度為4)*/ CH375ByteRead( ); /*直接讀取文件的第((n-1)*4+1)個字節(jié)到((n-1)*4+4)個字節(jié)數(shù)據(jù),前(n-1)*4個字節(jié)被跳過*/ mStopIfError( i ); for ( i=0; i!=4; i++ ) { str[i]=mCmdParam.ByteRead.mByteBuffer[i]; /* 要讀取的花樣文件名 */ } i = CH375FileClose( ); /* 關閉文件 */ mStopIfError( i );
/* 讀取第n個花樣文件! */ mCmdParam.Open.mPathName[0] = '/';
mCmdParam.Open.mPathName[1] = str[0]; /* 要讀取的花樣文件名 */ mCmdParam.Open.mPathName[2] = str[1]; mCmdParam.Open.mPathName[3] = str[2]; mCmdParam.Open.mPathName[4] = str[3];
mCmdParam.Open.mPathName[5] = '.'; mCmdParam.Open.mPathName[6] = 'T'; mCmdParam.Open.mPathName[7] = 'X'; mCmdParam.Open.mPathName[8] = 'T'; mCmdParam.Open.mPathName[9] = 0x00;
i = CH375FileOpen( ); /* 打開文件 */ mStopIfError( i ); if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) break; /* 出錯 */ else /* 找到文件 */ { TotalReadCount = CH375vFileSize; /* 準備讀取總長度 */ TotalWriteCount = CH375vFileSize; while ( TotalReadCount ) { /* 如果文件比較大,一次讀不完,可以再調用CH375ByteRead繼續(xù)讀取,文件指針自動向后移動 */ if ( TotalReadCount > MAX_BYTE_IO ) c = MAX_BYTE_IO; /* 剩余數(shù)據(jù)較多,限制單次讀寫的長度不能超過 sizeof( mCmdParam.ByteRead.mByteBuffer ) */ else c = TotalReadCount; /* 最后剩余的字節(jié)數(shù) */ mCmdParam.ByteRead.mByteCount = c; /* 請求讀出幾十字節(jié)數(shù)據(jù) */ i = CH375ByteRead( ); /* 以字節(jié)為單位讀取數(shù)據(jù)塊,單次讀寫的長度不能超過MAX_BYTE_IO,第二次調用時接著剛才的向后讀 */ mStopIfError( i ); TotalReadCount -= mCmdParam.ByteRead.mByteCount; /* 計數(shù),減去當前實際已經讀出的字符數(shù) */ Setbytes_UDisk( tempPos, c, mCmdParam.ByteRead.mByteBuffer ); tempPos+=mCmdParam.ByteRead.mByteCount;/*修改當前地址*/ } i = CH375FileClose( ); /* 關閉文件 */ mStopIfError( i ); } //================================================================================================== /* 往U盤寫文件 */ mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); /* 新文件名,在根目錄下,中文文件名 */ i = CH375FileCreate( ); /* 新建文件并打開,如果文件已經存在則先刪除后再新建 */ mStopIfError( i ); while( TotalWriteCount ) { if ( TotalWriteCount > MAX_BYTE_IO ) d = MAX_BYTE_IO; /* 剩余數(shù)據(jù)較多,限制單次讀寫的長度不能超過 sizeof( mCmdParam.ByteRead.mByteBuffer ) */ else d = TotalWriteCount; /* 最后剩余的字節(jié)數(shù) */ Getbytes_UDisk( tempAddr,d,mCmdParam.ByteWrite.mByteBuffer ); tempAddr += d; mCmdParam.ByteWrite.mByteCount = d; TotalWriteCount -= mCmdParam.ByteWrite.mByteCount; i = CH375ByteWrite( ); /* 向文件寫入數(shù)據(jù) */ mStopIfError( i ); } mCmdParam.Close.mUpdateLen = 1; /* 自動計算文件長度,以字節(jié)為單位寫文件,建議讓程序庫關閉文件以便自動更新文件長度 */ i = CH375FileClose( ); mStopIfError( i ); while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態(tài),等待U盤拔出 */ mDelaymS( 100 ); } }
注解:是將U盤中的文件讀到512K的外部RAM中,在從此RAM中讀出寫到U盤中!
外部晶振用的12M,對內為PHILIPS單片機P89V51RD2xx的6時鐘模式! 函數(shù):Setbytes_UDisk()、Getbytes_UDisk()為訪問外部RAM的子程序。
另外對“模擬I/O口的方式”的概念不解!
用的是CH375HF6.LIB庫!
CH375工作于并口方式!
也就是模擬I/O口方式!
模擬I/O口方式讀寫優(yōu)盤,連CH375的晶振一直用的是12M,現(xiàn)在只是將連單片機的晶振由24M換成了12M!
那你有沒有測試你的RAM是不是好的呢???還有就是你的程序好象少了很多庫里面的定義