請(qǐng)問(wèn)一下,寫(xiě)U盤(pán)。 用字節(jié)的方式寫(xiě),速度是多少??? 用扇區(qū)寫(xiě)的話(huà),速度又是多少啊? 資料上只是說(shuō)扇區(qū)比字節(jié)略快。。。。
這個(gè)和單片機(jī)有關(guān)系??焖俚腗CU,多扇區(qū)讀寫(xiě)速度會(huì)快的多。庫(kù)最多支持255個(gè)字節(jié)同時(shí)寫(xiě)。 支持255個(gè)扇區(qū)同時(shí)寫(xiě)。
關(guān)于速度方面的詳細(xì)說(shuō)明,請(qǐng)下載CH375EVT.ZIP,參考CH375EVT.PDF中的5.3. 單片機(jī)讀寫(xiě)U盤(pán)
你好,我基本上按照你們的例程用128單片機(jī)做的并口操作375芯片,文件好像也新建了,因?yàn)榇蜷_(kāi)優(yōu)盤(pán)文件名存在,但是內(nèi)容好像沒(méi)有寫(xiě)進(jìn)去,是不是基礎(chǔ)程序有問(wèn)題?單片機(jī)是8m晶體 基礎(chǔ)程序如下 void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定義的被CH375程序庫(kù)調(diào)用的子程序,向CH375寫(xiě)命令 */ { mDelay1uS( ); mDelay1uS( ); /* 至少延時(shí)1uS */ /* *(volatile unsigned char *)CH375_CMD_PORT_ADDR = mCmd; 通過(guò)并口直接讀寫(xiě)CH375而非普通I/O模擬 */ //PORTB |= 0x08; /* 輸出A0=1 */ SET_CH375_A0; PORTC = mCmd; /* 向CH375的并口輸出數(shù)據(jù) */ DDRC = 0xFF; /* 并口D0-D7輸出 */ /* PORTB &= 0xF9; // 輸出有效寫(xiě)控制信號(hào), 寫(xiě)CH375芯片的命令端口, A0=1; CS=0; WR=0; RD=1; DDRA = 0xFF; // 該操作無(wú)意義,僅作延時(shí),CH375要求讀寫(xiě)脈沖寬度大于100nS PORTB |= 0x07; // 輸出無(wú)效的控制信號(hào), 完成操作CH375芯片, A0=1; CS=1; WR=1; RD=1; DDRA = 0x00; // 禁止數(shù)據(jù)輸出 PORTB &= 0xF7; // 輸出A0=0; 可選操作 */ //寫(xiě)命令的狀態(tài) CLR_CH375_WR;// CLR_CH375_CS; SET_CH375_RD; NOP();//延時(shí) mDelay1uS( ); SET_CH375_WR;// SET_CH375_CS; CLR_CH375_RD; DDRC = 0x00; // 禁止數(shù)據(jù)輸出 CLR_CH375_A0; mDelay1uS( ); mDelay1uS( ); /* 至少延時(shí)2uS */ }
void xWriteCH375Data( UINT8 mData ) /* 外部定義的被CH375程序庫(kù)調(diào)用的子程序,向CH375寫(xiě)數(shù)據(jù) */ { /* *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData; 通過(guò)并口直接讀寫(xiě)CH375而非普通I/O模擬 */ CLR_CH375_A0; PORTC = mData; /* 向CH375的并口輸出數(shù)據(jù) */ DDRC = 0xFF; /* 并口D0-D7輸出 */ CLR_CH375_WR;// CLR_CH375_CS; SET_CH375_RD; NOP();//延時(shí) mDelay1uS( ); SET_CH375_WR;// SET_CH375_CS; CLR_CH375_RD; DDRC = 0x00; // 禁止數(shù)據(jù)輸出 /* PORTB &= 0xF1; // 輸出有效寫(xiě)控制信號(hào), 寫(xiě)CH375芯片的數(shù)據(jù)端口, A0=0; CS=0; WR=0; RD=1; DDRA = 0xFF; //該操作無(wú)意義,僅作延時(shí),CH375要求讀寫(xiě)脈沖寬度大于100nS PORTB |= 0x07;//輸出無(wú)效的控制信號(hào), 完成操作CH375芯片, A0=0; CS=1; WR=1; RD=1; DDRA = 0x00; //禁止數(shù)據(jù)輸出 */ mDelay1uS( ); //至少延時(shí)1.2uS }
UINT8 xReadCH375Data( void ) /* 外部定義的被CH375程序庫(kù)調(diào)用的子程序,從CH375讀數(shù)據(jù) */ { UINT8 mData; //mData = *(volatile unsigned char *)CH375_DAT_PORT_ADDR; 通過(guò)并口直接讀寫(xiě)CH375而非普通I/O模擬 */ mDelay1uS( ); /* 至少延時(shí)1.2uS */ /* PORTB &= 0xF2; // 輸出有效讀控制信號(hào), 讀CH375芯片的數(shù)據(jù)端口, A0=0; CS=0; WR=1; RD=0; / DDRA = 0x00; // 該操作無(wú)意義,僅作延時(shí),CH375要求讀寫(xiě)脈沖寬度大于100nS / mData = PINA; // 從CH375的并口PA輸入數(shù)據(jù) / PORTB |= 0x07; // 輸出無(wú)效的控制信號(hào), 完成操作CH375芯片, A0=0; CS=1; WR=1; RD=1; / */ SET_CH375_WR;// CLR_CH375_CS; CLR_CH375_RD; DDRC = 0x00; // 該操作無(wú)意義,僅作延時(shí),CH375要求讀寫(xiě)脈沖寬度大于100nS / mData = PINC; // 從CH375的并口PA輸入數(shù)據(jù) / //NOP();//延時(shí) mDelay1uS( ); CLR_CH375_WR;// SET_CH375_CS; SET_CH375_RD; DDRC = 0x00; return( mData ); } 中間的延時(shí)是后來(lái)加上的,加之前之后都不對(duì),寫(xiě)不進(jìn)去
主程序如下 void main( ) { UINT8 i, c; UINT16 TotalCount; UINT8 *pCodeStr; //CH375_PORT_INIT( ); mDelaymS( 100 ); /* 延時(shí)100毫秒 */ init_devices();//2010-1-19 8:51:18 OPEN_BUZZER; mDelaymS( 100 ); /* 延時(shí)100毫秒 */ STOP_BUZZER;//2010-1-18 16:12:33 //LED_OUT_INACT( ); //mInitSTDIO( ); /* 為了讓計(jì)算機(jī)通過(guò)串口監(jiān)控演示過(guò)程 */ //printf( "Start\n" );
#if DISK_BASE_BUF_LEN == 0 pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定義CH375的專(zhuān)用緩沖區(qū),而是用緩沖區(qū)指針指向其它應(yīng)用程序的緩沖區(qū)便于合用以節(jié)約RAM */ #endif
i = CH375LibInit( ); /* 初始化CH375程序庫(kù)和CH375芯片,操作成功返回0 */ mStopIfError( i ); /* 其它電路初始化 */
while ( 1 ) { while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 查詢(xún)CH375中斷并更新中斷狀態(tài),等待U盤(pán)插入 */ //LED_OUT_ACT( ); /* LED亮 */ mDelaymS( 200 ); /* 延時(shí),可選操作,有的USB存儲(chǔ)器需要幾十毫秒的延時(shí) */
/* 檢查U盤(pán)是否準(zhǔn)備好,有些U盤(pán)不需要這一步,但是某些U盤(pán)必須要執(zhí)行這一步才能工作 */ for ( i = 0; i < 10; i ++ ) { /* 有的U盤(pán)總是返回未準(zhǔn)備好,不過(guò)可以被忽略 */ mDelaymS( 100 ); //printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢(xún)磁盤(pán)是否準(zhǔn)備好 */ } #if DISK_BASE_BUF_LEN if ( DISK_BASE_BUF_LEN < CH375vSectorSize ) { /* 檢查磁盤(pán)數(shù)據(jù)緩沖區(qū)是否足夠大,CH375vSectorSize是U盤(pán)的實(shí)際扇區(qū)大小 */ //printf( "Too large sector size\n" ); while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelaymS( 100 ); continue; } #endif /* 查詢(xún)磁盤(pán)物理容量 */ /* printf( "DiskSize\n" ); i = CH375DiskSize( ); mStopIfError( i ); printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * (CH375vSectorSize/512) / 2048 ) ); // 顯示為以MB為單位的容量 // 原計(jì)算方法 (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * CH375vSectorSize / 1000000 ) 有可能前兩個(gè)數(shù)據(jù)相乘后導(dǎo)致溢出, 所以修改成上式 */
/* 讀取原文件 */ //printf( "Open\n" ); strcpy( (char *)mCmdParam.Open.mPathName, (char *)"/345.txt" ); /* 文件名,該文件在C51子目錄下 */ i = CH375FileOpen( ); /* 打開(kāi)文件 */ if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { // 沒(méi)有找到文件 strcpy( mCmdParam.Create.mPathName, mCmdParam.Open.mPathName ); i = CH375FileCreate( ); /* 新建文件并打開(kāi),如果文件已經(jīng)存在則先刪除后再新建 */ mStopIfError( i ); } else { /* 找到文件,說(shuō)明文件已存在,因?yàn)椴淮蛩愀采w原數(shù)據(jù),所以移動(dòng)文件指針到末尾,以便追加數(shù)據(jù) */ mStopIfError( i ); mCmdParam.ByteLocate.mByteOffset = 0xFFFFFFFF; /* 移動(dòng)到文件尾,用于在CMD_FileOpen打開(kāi)文件后,繼續(xù)追加數(shù)據(jù)到已打開(kāi)文件的末尾 */ CH375ByteLocate( ); //i = ExecCommand( CMD_ByteLocate, 4 ); /* 以字節(jié)為單位移動(dòng)文件指針 */ mStopIfError( i ); }
//#ifdef EN_DISK_WRITE /* 子程序庫(kù)支持寫(xiě)操作 */ /* 產(chǎn)生新文件 */ //pCodeStr = (UINT8 *)"Note: \xd\xa這個(gè)程序是以字節(jié)為單位進(jìn)行U盤(pán)文件讀寫(xiě),單片機(jī)只需要有600字節(jié)的RAM\xd\xa"; pCodeStr = (UINT8 *)"1234567iytr7ihff"; //while( 1 ) { /* 分多次寫(xiě)入文件數(shù)據(jù) */ //for ( i=0; i for ( i=0; i<18; i++ ) { c = *pCodeStr; mCmdParam.ByteWrite.mByteBuffer[i] = c; if ( c == 0 ) break; /* 源字符串結(jié)束 */ pCodeStr++; } //if ( i == 0 ) break; /* 源字符串結(jié)束,完成寫(xiě)文件 */ mCmdParam.ByteWrite.mByteCount = i; /* 寫(xiě)入數(shù)據(jù)的字符數(shù),單次讀寫(xiě)的長(zhǎng)度不能超過(guò)MAX_BYTE_IO,第二次調(diào)用時(shí)接著剛才的向后寫(xiě) */ i = CH375ByteWrite( ); /* 向文件寫(xiě)入數(shù)據(jù) */ mStopIfError( i ); } /* printf( "Modify\n" ); mCmdParam.Modify.mFileAttr = 0xff; 輸入?yún)?shù): 新的文件屬性,為0FFH則不修改 mCmdParam.Modify.mFileTime = 0xffff; 輸入?yún)?shù): 新的文件時(shí)間,為0FFFFH則不修改,使用新建文件產(chǎn)生的默認(rèn)時(shí)間 mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2004, 5, 18 ); 輸入?yún)?shù): 新的文件日期: 2004.05.18 mCmdParam.Modify.mFileSize = 0xffffffff; 輸入?yún)?shù): 新的文件長(zhǎng)度,以字節(jié)為單位寫(xiě)文件應(yīng)該由程序庫(kù)關(guān)閉文件時(shí)自動(dòng)更新長(zhǎng)度,所以此處不修改 i = CH375FileModify( ); 修改當(dāng)前文件的信息,修改日期 mStopIfError( i ); */ //printf( "Close\n" ); mCmdParam.Close.mUpdateLen = 1; /* 自動(dòng)計(jì)算文件長(zhǎng)度,以字節(jié)為單位寫(xiě)文件,建議讓程序庫(kù)關(guān)閉文件以便自動(dòng)更新文件長(zhǎng)度 */ i = CH375FileClose( ); mStopIfError( i );
/* 刪除某文件 */ /* printf( "Erase\n" ); strcpy( (char *)mCmdParam.Create.mPathName, "/OLD" ); 將被刪除的文件名,在根目錄下 i = CH375FileErase( ); 刪除文件并關(guān)閉 if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (UINT16)i ); 顯示錯(cuò)誤 */
/* 查詢(xún)磁盤(pán)信息 */ /* printf( "Disk\n" ); i = CH375DiskQuery( ); mStopIfError( i ); printf( "Fat=%d, Total=%ld, Free=%ld\n", (UINT16)mCmdParam.Query.mDiskFat, mCmdParam.Query.mTotalSector, mCmdParam.Query.mFreeSector ); */
//printf( "Take out\n" ); //while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); /* 查詢(xún)CH375中斷并更新中斷狀態(tài),等待U盤(pán)拔出 */ //LED_OUT_INACT( ); /* LED滅 */ OPEN_BUZZER; mDelaymS( 100 ); /* 延時(shí)100毫秒 */ STOP_BUZZER;//2010-1-18 16:12:33 mDelaymS( 200 ); while(1); /* i = FILE_DATA_BUF[0]; 因?yàn)槭且宰止?jié)為單位讀寫(xiě)文件,未用到文件數(shù)據(jù)緩沖區(qū),為了防止編譯器優(yōu)化掉該緩沖區(qū)而用一下緩沖區(qū) */ } }
寫(xiě)完文件后要更新相應(yīng)的文件長(zhǎng)度才可以,目前你發(fā)現(xiàn)文件好像寫(xiě)不進(jìn)去,看下文件大小是多少?是不是你實(shí)際的文件長(zhǎng)度? 關(guān)于如果更新文件長(zhǎng)度,請(qǐng)下載CH375EVT.ZIP,里面有CH375HF.PDF,按照上面的方法去更新就可以了。
研究貴公司燃CH374s一個(gè)星期了,一點(diǎn)頭緒都沒(méi)有。我用的是軟件模擬SPI方式。發(fā)送測(cè)試字后(發(fā)送測(cè)試字之前需要發(fā)送其他的什么數(shù)據(jù)或者命令嗎?),接收到的數(shù)據(jù)是0Xff。測(cè)試晶振兩管腳的電壓都是2點(diǎn)多伏。請(qǐng)問(wèn)我的問(wèn)題怎么解決?還有怎么區(qū)分發(fā)送的命令還是數(shù)據(jù)?
要放假了,祝大家春節(jié)快樂(lè),來(lái)年工作順利!
新手學(xué)習(xí)中
我這個(gè)程序?qū)崿F(xiàn)枚舉"\\IMPORT"文件中的"SJ*"文件列表,但不知為什么,只能找到第一個(gè)文件,然后就"i==ERR_MISS_FILE"就跳出了,我的文件夾里有好多個(gè)文件,如SJ1,SJ23,SJA等,請(qǐng)問(wèn),是什么原因? 求助。。。。。
strcpy( mCmdParam.Open.mPathName, "\\IMPORT" ); i = CH375FileOpen(); if(i != ERR_OPEN_DIR) //指定路徑未被打開(kāi) return(i);
for ( c = 0; c < 254; c ++ ) { /* 最多搜索前254個(gè)文件 */ mCmdParam.Open.mPathName[0]='S'; mCmdParam.Open.mPathName[1]='J'; mCmdParam.Open.mPathName[2]='*'; mCmdParam.Open.mPathName[3]=0; i = strlen( (char *)mCmdParam.Open.mPathName ); mCmdParam.Open.mPathName[ i ] = 0; i = CH375FileOpen( ); if ( i == ERR_MISS_FILE ) break; if ( i != ERR_FOUND_NAME ) break; //**顯示搜索到的文件名 }
你的這種應(yīng)用,下載CH375EVT.ZIP,參考CH375HF.PDF中的CH375FileEnumer( ); /* 枚舉文件 */
我現(xiàn)在這個(gè)程序跟例子一樣的,但不知為什么,就是枚舉不出其它的文件,麻煩你幫我看一下?
是一樣么?你的程序中有枚舉序號(hào)么,再好好比較一下吧: for ( c=0; c<255; c++ ) { /* 最多搜索前255 個(gè)文件 */ strcpy( mCmdParam.Enumer.mPathName, "\\C51\\CH375*" ); /* 在C51 子目錄下搜索以CH375 開(kāi)頭的文件名,*為通配符 */ i = strlen( mCmdParam.Enumer.mPathName ); /* 計(jì)算文件名長(zhǎng)度,指向結(jié)束符 */ mCmdParam.Enumer.mPathName[i] = c; /* 將結(jié)束符替換為搜索的序號(hào),從0 到254 */ i=CH375FileEnumer( ); /* 文件名中含有通配符*,枚舉/搜索文件而不打開(kāi) */ if ( i==ERR_MISS_FILE ) break; /* 再也搜索不到匹配文件,已經(jīng)沒(méi)有匹配的文件名 */ if ( i!=ERR_SUCCESS ) break; /* 出錯(cuò) */ printf( "found name %d#: %s\n", (unsigned int)c, mCmdParam.Enumer.mPathName ); /* 搜索到相匹配的文件名,顯示序號(hào)和搜索到的匹配文件名或者子目錄名 */ }
謝謝,搞定了,一直沒(méi)搞懂 mCmdParam.Enumer.mPathName與 mCmdParam.Open.mPathName的區(qū)別,現(xiàn)在明白了,還有那個(gè)序號(hào)
status = mRecvByte( ); /* 等待模塊完成操作并返回操作狀態(tài) */ if ( status == ERR_SUCCESS ) { /* 操作成功 */ i = mRecvByte( ); /* 返回結(jié)果數(shù)據(jù)的長(zhǎng)度 */ if ( i ) { /* 有結(jié)果數(shù)據(jù) */ CH375HMS.C中i = mRecvByte( ); /* 返回結(jié)果數(shù)據(jù)的長(zhǎng)度 */返回結(jié)果數(shù)據(jù)長(zhǎng)度是什么意思?每次發(fā)送完模塊操作命令,如果成功到底返回什么?例如ExecCommand( CMD_QueryStatus, 0 )之后如果成功返回到串口的數(shù)據(jù)依次是ERR_SUCCESS+返回結(jié)果數(shù)據(jù)的長(zhǎng)度+12個(gè)字節(jié)的struct Status嗎? 還是如CH375HM中說(shuō)的12個(gè)字節(jié)的struct Status
1、返回結(jié)果數(shù)據(jù)長(zhǎng)度,就是模塊應(yīng)答的數(shù)據(jù)長(zhǎng)度 2、數(shù)據(jù)組成就是頭文件中的結(jié)構(gòu)體所描述的