我的CH375在初始化U盤時總是不能Ready,返回錯誤號總是0x1F,我測了一下USB口電源電壓,4.9伏,請問正常嗎?如果不Ready,下一步打開文件總是出錯,錯誤號是0x82……
測試一下你的磁盤數(shù)據(jù)緩沖區(qū)是否可以正常的讀寫,還有USB信號線上不需要串電阻.
另:(1)接口子程序問題。需要查WriteData/ReadData接口子程序是否太慢,導(dǎo)致U盤睡眠。 (2)CH375的晶振誤差不能過大 (3)檢查USB口與芯片供地好不好,多連接幾根地線,若通過延長線連接,那么需要屏蔽線,且屏蔽層要接地
USB信號線沒串電阻。請問什么是磁盤緩沖區(qū),怎樣測試磁盤緩沖區(qū)是否可以讀寫?謝謝! 整個板子敷了銅,應(yīng)該不是共地問題…… 現(xiàn)在可以通過Ready了,但是在執(zhí)行CH375FileOpen()時,怎么也不返回,就好像在這個函數(shù)里死循環(huán)了一樣,很著急…… 對了,晶振誤差一般允許多少? 我的CH375B使用3.3伏供電,5伏供電是不是會好些? 謝謝了!
你使用的是什么單片機(jī)?主頻是多少?可以嘗試把主頻降一點(diǎn)試試
用的是MSP430F247,主頻8MHz……這個與主頻有關(guān)系嗎?
測試一下你的磁盤數(shù)據(jù)緩沖區(qū)DISK_BASE_BUF是否可以正常讀寫,ch375的晶振用12M的,誤差在±0.4‰.
下面是我用的程序,Ready能過,但是到CH375FileOpen()那就死循環(huán)出不來了, /* 2004.06.05 **************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB Host File Interface for CH375 ** ** TC2.0@PC, IAR_C/EC++_2.10A@MSP430 ** **************************************** */ /* CH375 主機(jī)文件系統(tǒng)接口 */ /* 支持: FAT12/FAT16/FAT32 */
/* MSP430單片機(jī)C語言的U盤文件讀寫示例程序, 適用于具有不少于1KB容量RAM的單片機(jī), 如果RAM容量少于1100字節(jié), 那么需要合用磁盤緩沖區(qū)與文件緩沖區(qū) */ /* 該程序?qū)盤中的/C51/CH375HFT.C文件中的小寫字母轉(zhuǎn)成大寫字母后, 寫到新建的文件NEWFILE.TXT中, 如果找不到原文件CH375HFT.C, 那么該程序?qū)@示C51子目錄下所有以CH375開頭的文件名, 并新建NEWFILE.TXT文件并寫入提示信息, 如果找不到C51子目錄, 那么該程序?qū)@示根目錄下的所有文件名, 并新建NEWFILE.TXT文件并寫入提示信息 */ /* CH375的INT#引腳采用查詢方式處理, 數(shù)據(jù)復(fù)制方式為"內(nèi)部復(fù)制", 本程序適用于MSP430F449單片機(jī), 串口0輸出監(jiān)控信息,9600bps */
/* ICC430 CH375HFT.C -l CH375HFT.LST -o CH375HFT.R43 */ /* XLINK CH375HFT.R43 -o CH375HFT.TXT -Fmsp430_txt ..\430\lib\cl430f.r43 CH375HF8.R43 -f ..\430\config\lnk430F449.xcl */
#include #include #include #include "LCD.h" #include "CH375_COMM.h"
/* 以下定義的詳細(xì)說明請看CH375HF8.H文件 */ #define LIB_CFG_FILE_IO 1 /* 文件讀寫的數(shù)據(jù)的復(fù)制方式,0為"外部子程序",1為"內(nèi)部復(fù)制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引腳連接方式,0為"查詢方式",1為"中斷方式" */
#define CH375_CMD_PORT_ADDR 0xBDF1 /* CH375命令端口的I/O地址 */ #define CH375_DAT_PORT_ADDR 0xBCF0 /* CH375數(shù)據(jù)端口的I/O地址 */ /* 單片機(jī)的1KB的RAM分為兩部分: 0200H-03FFH為磁盤讀寫緩沖區(qū), 0400H-05FFH為文件數(shù)據(jù)緩沖區(qū) */ #define DISK_BASE_BUF_ADDR 0x0200 /* 外部RAM的磁盤數(shù)據(jù)緩沖區(qū)的起始地址,從該單元開始的緩沖區(qū)長度為SECTOR_SIZE */ #define DISK_BASE_BUF_LEN 512 /* 默認(rèn)的磁盤數(shù)據(jù)緩沖區(qū)大小為512字節(jié),建議選擇為2048甚至4096以支持某些大扇區(qū)的U盤,為0則禁止在.H文件中定義緩沖區(qū)并由應(yīng)用程序在pDISK_BASE_BUF中指定 */ #define FILE_DATA_BUF_ADDR 0x0400 /* 外部RAM的文件數(shù)據(jù)緩沖區(qū)的起始地址,緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度 */ /* 單片機(jī)的RAM有限,其中CH375子程序用512字節(jié),所以外部RAM剩余長度為512字節(jié),即使是具有2K容量RAM的單片機(jī),減去堆棧和變量的占用,緩沖區(qū)最多為1K字節(jié) */ #define FILE_DATA_BUF_LEN 0x0200 /* 外部RAM的文件數(shù)據(jù)緩沖區(qū),緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度 */ /* 如果準(zhǔn)備使用雙緩沖區(qū)交替讀寫,那么不要定義FILE_DATA_BUF_LEN,而是在參數(shù)中指定緩沖區(qū)起址,用CH375FileReadX代替CH375FileRead,用CH375FileWriteX代替CH375FileWrite */
#define CH375_INT_WIRE ( P1IN & 0x02 ) /* P1.1, CH375的中斷線INT#引腳,連接CH375的INT#引腳,用于查詢中斷狀態(tài) */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未調(diào)用CH375FileEnumer程序故禁止以節(jié)約代碼 */ #define NO_DEFAULT_CH375_F_QUERY 1 /* 未調(diào)用CH375FileQuery程序故禁止以節(jié)約代碼 */
#pragma language=extended #include "CH375HFF.H" #pragma language=default
/* 由于MSP430不開放系統(tǒng)總線,所以用I/O引腳模擬產(chǎn)生CH375的并口讀寫時序 */ /* 本例中的硬件連接方式如下(實(shí)際應(yīng)用電路可以參照修改下述3個并口讀寫子程序) */ /* MSP430單片機(jī)的引腳 CH375芯片的引腳 P1.1 INT# P3.3 A0 P3.0 CS# P3.2 WR# P3.1 RD# P2 D7-D0 */
void CH375_PORT_INIT(){ /* 由于使用通用I/O模塊并口讀寫時序,所以進(jìn)行初始化 */
P1OUT &=~BIT1; //設(shè)置A0為低電平 P3OUT |=BIT0; //設(shè)置CS為高電平 P3OUT |=BIT2; //設(shè)置WR為高電平 P3OUT |=BIT1; //設(shè)置RD為高電平 P1DIR &= ~BIT1;//INT#輸入 P3DIR |=BIT0 + BIT2 + BIT1 + BIT3;//設(shè)置CS,WR,RD,A0為輸出 P2DIR = 0; /* 設(shè)置8位并口輸入 */ }
void xWriteCH375Cmd( UINT8 mCmd ){ _NOP( ); _NOP( ); _NOP( ); /* 至少延時2uS,實(shí)際由于模擬I/O較慢而只需少量延時 */ P3DIR |= BIT1+BIT2+BIT3+BIT0; /* 設(shè)置P3口A0,CS,WR,RD為輸出控制信號 */ P2DIR = 0xFF; /* 寫操作所以數(shù)據(jù)輸出 */ P2OUT = mCmd; /* 向CH375的并口輸出數(shù)據(jù) */ P3OUT |= BIT3; /* 指向CH375芯片的命令端口, A0(P3.3)=1; */ P3OUT |= BIT1; //RD(P3.1)=1; P3OUT &=~BIT0;//CS(P3.0)=0; P3OUT &=~BIT2;//WR=(P3.2)=0; _NOP( ); /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度為100nS */ P3OUT |= BIT1+BIT2+BIT3+BIT0; /* 輸出無效的控制信號, 完成操作CH375芯片, A0(P3.3)=1; CS(P3.7)=1; WR=(P3.2)=1; RD(P3.1)=1; */ P3OUT &=~BIT3; /* 輸出A0(P3.3)=0; 可選操作 */ P2DIR = 0; /* 禁止數(shù)據(jù)輸出 */ _NOP( ); _NOP( ); _NOP( ); _NOP( ); _NOP( ); /* 至少延時2uS,實(shí)際由于模擬I/O較慢而只需少量延時 */ }
void xWriteCH375Data( UINT8 mData ){ P2DIR = 0xFF; /* 寫操作所以數(shù)據(jù)輸出 */ P2OUT = mData; /* 向CH375的并口輸出數(shù)據(jù) */ P3OUT &=~BIT3;//輸出有效寫控制信號, 寫CH375芯片的數(shù)據(jù)端口, A0(P3.3)=0; P3OUT &=~BIT0;//CS(P3.0)=0; P3OUT &=~BIT2;//WR=(P3.2)=0; P3OUT |=BIT1;//RD(P3.1)=1;
_NOP( ); /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度為100nS */
P3OUT &=~BIT3;//輸出無效的控制信號, 完成操作CH375芯片, A0(P3.3)=0; P3OUT |=BIT0;//CS(P3.0)=1; P3OUT |=BIT2;//WR=(P3.2)=1; P3OUT |=BIT1;//RD(P3.1)=1; P2DIR = 0; /* 禁止數(shù)據(jù)輸出 */ _NOP( ); /* 至少延時1uS,實(shí)際由于模擬I/O較慢而不一定有必要 */ }
UINT8 xReadCH375Data( void ){ UINT8 mData; _NOP( ); /* 至少延時1uS,實(shí)際由于模擬I/O較慢而不一定有必要 */ P2DIR = 0; /* 讀操作所以數(shù)據(jù)輸入 */ P3OUT &=~BIT3;//輸出有效讀控制信號, 讀CH375芯片的數(shù)據(jù)端口, A0(P3.3)=0; P3OUT &=~BIT0;//CS(P3.0)=0; P3OUT |= BIT2;// WR=(P3.2)=1; P3OUT &=~BIT1;//RD(P3.1)=0; _NOP( ); /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度為100nS */ mData = P2IN; /* 從CH375的并口輸入數(shù)據(jù) */ P3OUT &=~BIT3;//輸出無效的控制信號, 完成操作CH375芯片, A0(P3.3)=0; P3OUT |=BIT0;//CS(P3.0)=1; P3OUT |=BIT2;//WR=(P3.2)=1; P3OUT |=BIT1;//RD(P3.1)=1; return mData; }
/* 延時指定毫秒時間,適用于8MHz時鐘,不精確 */ void mDelaymS( UINT16 ms ){ UINT16 k; while ( ms -- ) for ( k = 2000; k != 0; k -- ); }
/* 檢查操作狀態(tài),如果錯誤則顯示錯誤代碼并停機(jī) */ void mStopIfError( UINT8 iError ){ if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ else{ printf( "Error: %02X\n", (UINT16)iError ); /* 顯示錯誤 */ while (1){ //printf("OUT!"); //mDelaymS(1); } } }
/* 為printf輸出初始化液晶 */ void mInitSTDIO(){ LCD_Init(); }
/* 選擇8MHz時鐘 */ void init_clk(){ int i; BCSCTL1 &= ~XT2OFF; // XT2on do{ IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0xFF; i > 0; i--); // Time for flag to set }while ((IFG1 & OFIFG)); // OSCFault flag still set? BCSCTL2 |= SELM_2 + SELS; // MCLK = SMCLK = XT2 (safe) }
void main() { WDTCTL = WDTPW + WDTHOLD; UINT8 i, c, SecCount; UINT16 NewSize, count; /* 因為RAM容量有限,所以NewSize限制為16位,實(shí)際上如果文件較大,應(yīng)該分幾次讀寫并且將NewSize改為UINT32以便累計 */ UINT8 *pCodeStr; init_clk(); CH375_PORT_INIT(); mDelaymS( 100 ); /* 延時100毫秒 */ mInitSTDIO(); /* 為了讓計算機(jī)通過串口監(jiān)控演示過程 */ xWriteCH375Cmd(RESET_ALL);//復(fù)位CH375 mDelaymS( 500 ); xWriteCH375Cmd(SET_USB_MODE);//設(shè)置USB模式 xWriteCH375Data(0x06); mDelaymS( 500 ); printf( "Start\n" );
#if DISK_BASE_BUF_LEN == 0 pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定義CH375的專用緩沖區(qū),而是用緩沖區(qū)指針指向其它應(yīng)用程序的緩沖區(qū)便于合用以節(jié)約RAM */ #endif
i = CH375LibInit(); /* 初始化CH375程序庫和CH375芯片,操作成功返回0 */ mStopIfError( i ); /* 其它電路初始化 */
while ( 1 ) { printf( "Wait Udisk\n" ); while ( CH375DiskStatus < DISK_CONNECT ) { /* 查詢CH375中斷并更新中斷狀態(tài),等待U盤插入 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有設(shè)備連接則返回成功,CH375DiskConnect同時會更新全局變量CH375DiskStatus */
我用的晶振是普通的那種扁長的晶振,上面標(biāo)注是12.000H9A,滿足要求嗎?
我用這段程序測試的緩沖區(qū): UINT8 m=10; UINT8 n; DISK_BASE_BUF[0]=m; n=DISK_BASE_BUF[0]; printf("n=%d\n", n); 輸出結(jié)果確實(shí)是n=10;
最好是把整個RAM都測試一下,測試數(shù)據(jù)最好寫入一些特殊的數(shù)據(jù)比如:(0x55,0xaa).
我覺得不是硬件的問題,我自己重新寫了一個可以訪問扇區(qū)的程序,已經(jīng)可以正確的返回U盤中每一個扇區(qū)的值,并且可以任意寫,只是還不會操作文件系統(tǒng)。貴公司提供的子程序庫還是沒法用……
樓上加我QQ交流一下,同樣問題!804847186,謝謝。
編譯時有warning,我貼出來,看是否有關(guān)系: 現(xiàn)在是FileOpen返回0x1F Building configuration: CH375 - Debug Updating build tree... 6 file(s) deleted. Updating build tree... LCD.c main.c Linking Warning[w6]: Type conflict for external/entry "mCmdParam", in module CH375MAI against external/entry in module main; class/struct/union field names do not match: Other16 vs Query /* In module CH375MAI: */ CMD_PARAM_I mCmdParam; typedef CMD_PARAM CMD_PARAM_I; typedef union _CMD_PARAM CMD_PARAM; /* In module main: */ CMD_PARAM_I mCmdParam; typedef CMD_PARAM CMD_PARAM_I; typedef union _CMD_PARAM CMD_PARAM; Warning[w35]: There is more than one definition for the struct/union type with tag '_CMD_PARAM'; class/struct/union field names do not match: Query vs Other16 union _CMD_PARAM /* Elements: 19, Bytes: 30 */ { struct /* Elements: 1, Bytes: 30 */ { UINT8 mBuffer[30]; } Other; struct /* Elements: 4, Bytes: 14 */ { UINT32 mReserved; UINT32 mTotalSector; UINT32 mFreeSector; UINT8 mDiskFat; } Query; struct /* Elements: 1, Bytes: 30 */ { UINT8 mPathName[30]; } Open; struct Enumer; struct /* Elements: 1, Bytes: 1 */ { UINT8 mUpdateLen; } Close; struct Create; struct Erase; struct /* Elements: 4, Bytes: 10 */ { UINT32 mFileSize; UINT16 mFileDate; UINT16 mFileTime; UINT8 mFileAttr; } Modify; struct /* Elements: 1, Bytes: 4 */ { UINT32 mSectorOffset; } Locate; struct /* Elements: 1, Bytes: 1 */ { UINT8 mSectorCount; } Read; struct Write; struct /* Elements: 3, Bytes: 10 */ { UINT8 mSectorCount; UINT8 mReserved[7]; PUINT8 mDataBuffer; } ReadX; struct WriteX; struct /* Elements: 1, Bytes: 4 */ { UINT32 mDiskSizeSec; } DiskSize; struct /* Elements: 1, Bytes: 4 */ { UINT32 mByteOffset; } ByteLocate; struct /* Elements: 2, Bytes: 30 */ { UINT8 mByteCount; UINT8 mByteBuffer[29]; } ByteRead; struct ByteWrite; struct /* Elements: 3, Bytes: 6 */ { UINT8 mSaveVariable; UINT8 mReserved[3]; PUINT8 mBuffer; } SaveVariable; union /* Elements: 2, Bytes: 22 */ { struct /* Elements: 10, Bytes: 22 */ { UINT32 mCBW_Sig; UINT32 mCBW_Tag; UINT8 mCBW_DataLen; UINT8 mCBW_DataLen1; UINT8 mCBW_DataLen2; UINT8 mCBW_DataLen3; UINT8 mCBW_Flag; UINT8 mCBW_LUN; UINT8 mCBW_CB_Len; UINT8 mCBW_CB_Buf[6]; } mCBW; struct /* Elements: 5, Bytes: 14 */ { UINT32 mCSW_Sig; UINT32 mCSW_Tag; UINT32 mCSW_Residue; UINT8 mCSW_Status; UINT8 mReserved; } mCSW; } BOC; }; typedef unsigned char UINT8; typedef unsigned long UINT32; typedef unsigned short UINT16; typedef unsigned char * PUINT8; union _CMD_PARAM /* Elements: 19, Bytes: 30 */ { struct /* Elements: 1, Bytes: 30 */ { UINT8 mBuffer[30]; } Other; struct /* Elements: 1, Bytes: 30 */ { UINT16 mBuffer16[15]; } Other16; struct /* Elements: 1, Bytes: 28 */ { UINT32 mBuffer32[7]; } Other32; struct /* Elements: 4, Bytes: 14 */ { UINT32 mReserved; UINT32 mTotalSector; UINT32 mFreeSector; UINT8 mDiskFat; } Query; struct /* Elements: 1, Bytes: 30 */ { UINT8 mPathName[30]; } Open; struct Enumer; struct /* Elements: 1, Bytes: 1 */ { UINT8 mUpdateLen; } Close; struct Create; struct Erase; struct /* Elements: 6, Bytes: 16 */ { UINT32 mFileSize; UINT16 mFileDate; UINT16 mFileTime; UINT8 mFileAttr; UINT8 mReserved[3]; UINT32 mOldSize; } Modify; struct /* Elements: 1, Bytes: 4 */ { UINT32 mSectorOffset; } Locate; struct /* Elements: 6, Bytes: 10 */ { UINT8 mSectorCount; UINT8 mActualCount; UINT8 mLbaCount; UINT8 mRemainCount; UINT32 mLbaStart; PUINT8X mDataBuffer; } Read; struct /* Elements: 7, Bytes: 14 */ { UINT8 mSectorCount; UINT8 mActualCount; UINT8 mLbaCount; UINT8 mAllocCount; UINT32 mLbaStart; PUINT8X mDataBuffer; UINT32 mSaveValue; } Write; struct /* Elements: 1, Bytes: 4 */ { UINT32 mDiskSizeSec; } DiskSize; struct /* Elements: 1, Bytes: 4 */ { UINT32 mByteOffset; } ByteLocate; struct /* Elements: 2, Bytes: 30 */ { UINT8 mByteCount; UINT8 mByteBuffer[29]; } ByteRead; struct ByteWrite; struct /* Elements: 3, Bytes: 6 */ { UINT8 mSaveVariable; UINT8 mReserved[3]; PUINT8X mBuffer; } SaveVariable; union /* Elements: 2, Bytes: 22 */ { struct /* Elements: 9, Bytes: 22 */ { UINT32 mCBW_Sig; UINT32 mCBW_Tag; UINT8 mCBW_DataLen; UINT8 mCBW_DataLen1; UINT16 mCBW_DataLen2; UINT8 mCBW_Flag; UINT8 mCBW_LUN; UINT8 mCBW_CB_Len; UINT8 mCBW_CB_Buf[6]; } mCBW; struct /* Elements: 5, Bytes: 14 */ { UINT32 mCSW_Sig; UINT32 mCSW_Tag; UINT32 mCSW_Residue; UINT8 mCSW_Status; UINT8 mReserved; } mCSW; } BOC; }; typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned long UINT32; typedef unsigned char * PUINT8X; Total number of errors: 0 Total number of warnings: 2
算了,不用貴公司子程序庫了,tiny-fatfs還不錯,就用它吧