可以初始化
可以CH376DiskMount( ) == USB_INT_SUCCESS
然后新建文件之后看不到,寫了數(shù)據(jù)就更看不到了,不過下次執(zhí)行CH376FileOpenPath的時候,程序顯示找到了那個文件,但PC里看不到(有人說需要用XP系統(tǒng)?),SD卡已經(jīng)是FAT32格式。
或者根本就沒有新建成功。
總之我現(xiàn)在有點(diǎn)崩潰了,跪求大神救我,如果有技術(shù)人員愿意幫我就更好了,我可以把整個程序發(fā)過去。
下面附main函數(shù)和部分函數(shù)定義,求大神看一下。
void main(void)
{
? ?
// 步驟 1. 初始化系統(tǒng)控制:
// 設(shè)置PLL, WatchDog, 使能外設(shè)時鐘
// 下面這個函數(shù)可以從DSP280x_SysCtrl.c文件中找到.
? ?InitSysCtrl();
// 步驟 2. 初始化通用輸入輸出多路復(fù)用器GPIO:
// 這個函數(shù)在DSP280x_Gpio.c源文件中被定義了
// 這個函數(shù)使GPIO控制類寄存器初始化到默認(rèn)狀態(tài)
// InitGpio(); ?// Skipped for this example
// 次函數(shù)在DSP280x_Spi.c文件里面-----------------------------------------(1)
? ?InitSpiaGpio(); ?//開發(fā)板使用SPIA
//步驟 3. 清除所有中斷,初始化中斷向量表:
// 禁止CPU全局中斷
? ?DINT;
// 初始化PIE控制寄存器到他們的默認(rèn)狀態(tài).
// 這個默認(rèn)狀態(tài)就是禁止PIE中斷及清除所有PIE中斷標(biāo)志
// 這個函數(shù)放在DSP280x_PieCtrl.c源文件里
? ?InitPieCtrl();
// 禁止CPU中斷,清除CPU中斷標(biāo)志位
? ?IER = 0x0000;
? ?IFR = 0x0000;
? ?
// 初始化PIE中斷向量表,并使其指向中斷服務(wù)子程序(ISR)
// 這些中斷服務(wù)子程序被放在了DSP280x_DefaultIsr.c源文件中
// 這個函數(shù)放在了DSP280x_PieVect.c源文件里面.
? ?InitPieVectTable();
// 步驟 4.初始化片內(nèi)外設(shè):--------------------------------------------------(2)
? ?CH376_PORT_INIT( ?); ?/* 由于使用SPI讀寫時序,所以進(jìn)行初始化SPI,同時初始化GPIO74,初始化FIFO */
? ?GpioDataRegs.GPCSET.bit.GPIO74 = 1; ?/* 防止之前未通過xEndCH376Cmd禁止SPI片選 */
// 步驟 5. 以下是用戶編寫的指定代碼, 使能相關(guān)中斷:#####################################################
? ?GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共陰極LED14滅
? ?delay_loop_ms(50);
? ?statecheck = mInitCH376Host( ); ?/* 初始化CH376 */
? ?mStopIfError( statecheck );
? //xWriteCH376Cmd( CMD11_CHECK_EXIST ); ?/* 測試單片機(jī)與CH376之間的通訊接口 */
? ?GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共陰極LED14亮
? ?delay_loop_ms(500);
? ?for ( s = 0; s < 10; s ++ ) { ?/* 最長等待時間,10*50mS */
? delay_loop_ms(50);
? ?if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; ?/* 初始化磁盤并測試磁盤是否就緒 */
? ?}
? ?/* 如果.TXT文件已經(jīng)存在則添加數(shù)據(jù)到尾部,如果不存在則新建文件 */
? ?s = CH376FileOpenPath( "/161211.TXT" ); ?/* 打開文件,該文件在根目錄下 */
? ?if ( s == USB_INT_SUCCESS ) { ?/* 文件存在并且已經(jīng)被打開,移動文件指針到尾部以便添加數(shù)據(jù) */
? ? s = CH376ByteLocate( 0xFFFFFFFF ); ?/* 移到文件的尾部 */
? ?mStopIfError( s );
? ?}
? ?else if ( s == ERR_MISS_FILE ) { ?/* 沒有找到文件,必須新建文件 */
? ?s = CH376FileCreatePath( "/161211.TXT" ?); ?/* 新建文件并打開,如果文件已經(jīng)存在則先刪除后再新建,不必再提供文件名,剛才已經(jīng)提供給CH376FileOpen */
? ?mStopIfError( s );
? ?}
? ?else mStopIfError( s ); ?/* 打開文件時出錯 */
? ?strcpy( buf, "ADC" );
? ?s = CH376ByteWrite( buf, 3, NULL ); ?/* 以字節(jié)為單位向文件寫入數(shù)據(jù) */
? ?mStopIfError( s );
? ?//delay_loop_ms(50);
? ?s = CH376FileClose( 0x01 ); ?/* 關(guān)閉文件,自動計算文件長度,以字節(jié)為單位寫文件,建議讓程序庫關(guān)閉文件以便自動更新文件長度 */
? ?mStopIfError( s );
? ?LED14flash();
}
//end of main############################################################################
#definexEndCH376Cmd() ? GpioDataRegs.GPCSET.bit.GPIO74 = 1; /* SPI片選無效,結(jié)束CH376命令,僅用于SPI接口方式 */
//延遲函數(shù)
void delay_loop_100ms()//0.1s
{
? ? long ? ? ?i;
? ? for (i = 0; i < 15000000; i++) {} //1ms
}
void delay_loop_ms(int n)//0.001s
{
? ? long ? ? ?i;
? ? for (i = 0; i < 150000*n; i++) {} //1ms
}
void delay_loop_us(int n)//0.000001s
{
? ? long ? ? ?i;
? ? for (i = 0; i < 150*n; i++) {} //1us
}
voidCH376_PORT_INIT( ?) ?/* 由于使用SPI讀寫時序,所以進(jìn)行初始化SPI,同時初始化GPIO74,初始化FIFO */
{
/* 如果是硬件SPI接口,那么可使用mode3(CPOL=1&CPHA=1)或mode0(CPOL=0&CPHA=0),CH376在時鐘上升沿采樣輸入,下降沿輸出,數(shù)據(jù)位是高位在前 */
//CH376_SPI_SCS = 1; ?/* 禁止SPI片選 */
/* 對于雙向I/O引腳模擬SPI接口,那么必須在此設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */
//SPCR = 0x5C; ?/* 設(shè)置SPI模式3, DORD=0(MSB first), CPOL=1, CPHA=1, CH376也支持SPI模式0 */
SpiaRegs.SPICCR.all =0x0047;// SPI軟件復(fù)位, 極性位為1(下降沿發(fā)送數(shù)據(jù)), 每次移 ? ? ? ? 0100 0111
? ? ? ? ? ? ? ? ? ? ? ? ? ?//進(jìn)和移出8位字長度;禁止SPI內(nèi)部回送(LOOKBACK)功能;
SpiaRegs.SPICTL.all =0x0006; // 使能主機(jī)模式,正常相位(0),使能主機(jī)發(fā)送,禁止接收 ?0000 0110
? ? ? ? ? ? ? ? ? ? ? ? ? ?//溢出中斷,禁止SPI中斷;
SpiaRegs.SPIBRR =0x0011;//SPI波特率=150M/4/18=2MHZ
SpiaRegs.SPICCR.all =0x00C7;//停止SPI軟件復(fù)位準(zhǔn)備接收或發(fā)送;禁止SPI內(nèi)部回送; ?1100 0111
SpiaRegs.SPIPRI.bit.FREE = 1; ?// 自由運(yùn)行
//GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 0; ? ? ? ? ? ? ? //GPIO74作為普通IO
//GpioCtrlRegs.GPCDIR.bit.GPIO74 = 1; ? ? ? ? ? ? ? ? ? //GPIO74方向為輸出
//GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 0; ? ? ? ? ? ? ? //GPIO73作為普通IO
//GpioCtrlRegs.GPCDIR.bit.GPIO73 = 0; ? ? ? ? ? ? ? ? ? //GPIO73方向為輸入
//GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;//GPIO4---->LED作為DEGUG的標(biāo)志,之后要刪掉?。。?!**********************************
//GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
SpiaRegs.SPIFFTX.all=0xE040;//使能FIFO;清除發(fā)送中斷標(biāo)志位;禁止FIFO發(fā)送中斷;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送中斷級別定義為0;
SpiaRegs.SPIFFRX.all=0x204F;//清除FF溢出標(biāo)志位;清除溢出接受中斷標(biāo)志位;禁止
? ? ? ? ? ? ? ? ? ? ? ? ? ?//FF接受中斷;接受中斷級別為16;
SpiaRegs.SPIFFCT.all=0x0;//SPITXBUF到移位寄存器傳送不延遲;
}
UINT8Spi376Exchange( UINT8 d ) ?/* 硬件SPI輸出且輸入8個位數(shù)據(jù) */
{
Uint16 sdata;
Uint16 rdata;
UINT8 tempdata2;
sdata=(d<<8);
SpiaRegs.SPITXBUF=sdata;
while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }// wait for the transmission
rdata = SpiaRegs.SPIRXBUF; ? //每次都保證發(fā)送和接收都進(jìn)行一次,這樣FIFO中才不會滯留數(shù)據(jù)
tempdata2=(UINT8)rdata;
return( tempdata2 );
}
void ? LED14flash()
{
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共陰極LED14亮
delay_loop_100ms();
GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共陰極LED14滅
delay_loop_100ms();
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共陰極LED14亮
delay_loop_100ms();
GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共陰極LED14滅
}
voidmStopIfError( UINT8 iError )
{
if ( iError == USB_INT_SUCCESS ) ? /* 操作成功 */
{
//LED14flash();
}
}
voidxWriteCH376Cmd( UINT8 mCmd ) ?/* 向CH376寫命令 */
{
GpioDataRegs.GPCSET.bit.GPIO74 = 1; ?/* 防止之前未通過xEndCH376Cmd禁止SPI片選 */
delay_loop_us(2);
/* 對于雙向I/O引腳模擬SPI接口,那么必須確保已經(jīng)設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */
GpioDataRegs.GPCCLEAR.bit.GPIO74 = 1; ?/* SPI片選有效 */
delay_loop_us(2);
Spi376Exchange( mCmd ); ?/* 發(fā)出命令碼 */
delay_loop_us(2);
/* 延時1.5uS確保讀寫周期大于1.5uS,或者用上面一行的狀態(tài)查詢代替 */
}
voidxWriteCH376Data( UINT8 mData ) ?/* 向CH376寫數(shù)據(jù) */
{
Spi376Exchange( mData );
delay_loop_us(2);
}
UINT8xReadCH376Data( void ) ?/* 從CH376讀數(shù)據(jù) */
{
delay_loop_us(2);
return( Spi376Exchange( 0xFF ) );
}
UINT8mInitCH376Host( void ) ?/* 初始化CH376 */
{
UINT8res;
//CH376_PORT_INIT( ); ?/* 接口硬件初始化 *///接口可以在硬件初始化之前就完成初始化
xWriteCH376Cmd( CMD11_CHECK_EXIST ); ?/* 測試單片機(jī)與CH376之間的通訊接口 */
xWriteCH376Data( 0x56 );
res = xReadCH376Data( );
xEndCH376Cmd( );
if ( res != 0xA9 ) return( ERR_USB_UNKNOWN ); ?/* 通訊接口不正常,可能原因有:接口連接異常,其它設(shè)備影響(片選不唯一),串口波特率,一直在復(fù)位,晶振不工作 */
xWriteCH376Cmd( CMD11_SET_USB_MODE ); ?/* 設(shè)備USB工作模式 */
xWriteCH376Data( 0x03 );//USB 05
delay_loop_ms(20);
res = xReadCH376Data( );
xEndCH376Cmd( );
if ( res == CMD_RET_SUCCESS ) return( USB_INT_SUCCESS );
else return( ERR_USB_UNKNOWN ); ?/* 設(shè)置模式錯誤 */
}
UINT8Query376Interrupt( void )
{
return( GpioDataRegs.GPCDAT.bit.GPIO73 ? FALSE : TRUE ); ?/* 如果連接了CH376的中斷引腳則直接查詢中斷引腳 */
}
UINT8Wait376Interrupt( void ) ?/* 等待CH376中斷(INT#低電平),返回中斷狀態(tài)碼, 超時則返回ERR_USB_UNKNOWN */
{
UINT32i;
for ( i = 0; i < 30000000; i ++ ) { ?/* 計數(shù)防止超時,默認(rèn)的超時時間,與單片機(jī)主頻有關(guān) */
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); ?/* 檢測到中斷 */
/* 在等待CH376中斷的過程中,可以做些需要及時處理的其它事情 */
}
return( ERR_USB_UNKNOWN ); ?/* 不應(yīng)該發(fā)生的情況 */
}
UINT8CH376GetIntStatus( void ) ?/* 獲取中斷狀態(tài)并取消中斷請求 */
{
UINT8s;
xWriteCH376Cmd( CMD01_GET_STATUS );
s = xReadCH376Data( );
xEndCH376Cmd( );
return( s );
}
UINT8CH376SendCmdWaitInt( UINT8 mCmd ) ?/* 發(fā)出命令碼后,等待中斷 */
{
xWriteCH376Cmd( mCmd );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8CH376DiskMount( void ) ?/* 初始化磁盤并測試磁盤是否就緒 */
{
return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) );
}
UINT8CH376FileOpen( PUINT8 name ) ?/* 在根目錄或者當(dāng)前目錄下打開文件或者目錄(文件夾) */
{
CH376SetFileName( name ); ?/* 設(shè)置將要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) );
}
UINT8CH376FileOpenPath( PUINT8 PathName ) ?/* 打開多級目錄下的文件或者目錄(文件夾),支持多級目錄路徑,支持路徑分隔符,路徑長度不超過255個字符 */
{
return( CH376FileOpenDir( PathName, 0xFF ) );
}
UINT8CH376FileOpenDir( PUINT8 PathName, UINT8 StopName ) ?/* 打開多級目錄下的文件或者目錄的上級目錄,支持多級目錄路徑,支持路徑分隔符,路徑長度不超過255個字符 */
/* StopName 指向最后一級文件名或者目錄名 */
{
UINT8i, s;
s = 0;
i = 1; ?/* 跳過有可能的根目錄符 */
while ( 1 ) {
while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) ++ i; ?/* 搜索下一個路徑分隔符或者路徑結(jié)束符 */
if ( PathName[i] ) i ++; ?/* 找到了路徑分隔符,修改指向目標(biāo)文件的最后一級文件名 */
else i = 0; ?/* 路徑結(jié)束 */
s = CH376FileOpen( &PathName[s] ); ?/* 打開文件或者目錄 */
if ( i && i != StopName ) { ?/* 路徑尚未結(jié)束 */
if ( s != ERR_OPEN_DIR ) { ?/* 因為是逐級打開,尚未到路徑結(jié)束,所以,如果不是成功打開了目錄,那么說明有問題 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); ?/* 中間路徑必須是目錄名,如果是文件名則出錯 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); ?/* 中間路徑的某個子目錄沒有找到,可能是目錄名稱錯誤 */
else return( s ); ?/* 操作出錯 */
}
s = i; ?/* 從下一級目錄開始繼續(xù) */
}
else return( s ); ?/* 路徑結(jié)束,USB_INT_SUCCESS為成功打開文件,ERR_OPEN_DIR為成功打開目錄(文件夾),其它為操作出錯 */
}
}
UINT8CH376FileCreatePath( PUINT8 PathName ) ?/* 新建多級目錄下的文件,支持多級目錄路徑,支持路徑分隔符,路徑長度不超過255個字符 */
{
UINT8s;
UINT8Name;
Name = CH376SeparatePath( PathName ); ?/* 從路徑中分離出最后一級文件名,返回最后一級文件名的偏移 */
if ( Name ) { ?/* 是多級目錄 */
s = CH376FileOpenDir( PathName, Name ); ?/* 打開多級目錄下的最后一級目錄,即打開新建文件的上級目錄 */
if ( s != ERR_OPEN_DIR ) { ?/* 因為是打開上級目錄,所以,如果不是成功打開了目錄,那么說明有問題 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); ?/* 中間路徑必須是目錄名,如果是文件名則出錯 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); ?/* 中間路徑的某個子目錄沒有找到,可能是目錄名稱錯誤 */
else return( s ); ?/* 操作出錯 */
}
}
return( CH376FileCreate( &PathName[Name] ) ); ?/* 在根目錄或者當(dāng)前目錄下新建文件 */
}
UINT8CH376SeparatePath( PUINT8 path ) ?/* 從路徑中分離出最后一級文件名或者目錄(文件夾)名,返回最后一級文件名或者目錄名的字節(jié)偏移 */
{
PUINT8pName;
for ( pName = path; *pName != 0; ++ pName ); ?/* 到文件名字符串結(jié)束位置 */
while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) pName --; ?/* ?搜索倒數(shù)第一個路徑分隔符 */
if ( pName != path ) pName ++; ?/* 找到了路徑分隔符,則修改指向目標(biāo)文件的最后一級文件名,跳過前面的多級目錄名及路徑分隔符 */
return( pName - path );
}
UINT8CH376ByteLocate( UINT32 offset ) ?/* 以字節(jié)為單位移動當(dāng)前文件指針 */
{
xWriteCH376Cmd( CMD4H_BYTE_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( (UINT8)(offset>>24) );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8CH376FileCreate( PUINT8 name ) ?/* 在根目錄或者當(dāng)前目錄下新建文件,如果文件已經(jīng)存在那么先刪除 */
{
if ( name ) CH376SetFileName( name ); ?/* 設(shè)置將要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) );
}
UINT8CH376DirCreate( PUINT8 name ) ?/* 在根目錄下新建目錄(文件夾)并打開,如果目錄已經(jīng)存在那么直接打開 */
{
CH376SetFileName( name ); ?/* 設(shè)置將要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) );
}
voidCH376SetFileName( PUINT8 name ) ?/* 設(shè)置將要操作的文件的文件名 */
{
/*UINT8i;*/
UINT8c;
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
/*for ( i = MAX_FILE_NAME_LEN; i != 0; -- i ) {
c = *name;
xWriteCH376Data( c );
if ( c == 0 ) break;
name ++;
}*/
c = *name;
xWriteCH376Data( c );
while ( c ) {
name ++;
c = *name;
if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0; ?/* 強(qiáng)行將文件名截止 */
xWriteCH376Data( c );
}
xEndCH376Cmd( );
}
UINT8CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) ?/* 以字節(jié)為單位向當(dāng)前位置寫入數(shù)據(jù)塊 */
{
//UINT8s;
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
s = CH376WriteReqBlock( buf ); ?/* 向內(nèi)部指定緩沖區(qū)寫入請求的數(shù)據(jù)塊,返回長度 */
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
/*else if ( s == USB_INT_SUCCESS ) return( s );*/ ?/* 結(jié)束 */
else return( s ); ?/* 錯誤 */
}
}
UINT8CH376WriteReqBlock( PUINT8 buf ) ?/* 向內(nèi)部指定緩沖區(qū)寫入請求的數(shù)據(jù)塊,返回長度 */
{
UINT8s, l;
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
s = l = xReadCH376Data( ); ?/* 長度 */
if ( l ) {
do {
xWriteCH376Data( *buf );
buf ++;
} while ( -- l );
}
xEndCH376Cmd( );
return( s );
}
UINT8CH376FileClose( UINT8 UpdateSz ) ?/* 關(guān)閉當(dāng)前已經(jīng)打開的文件或者目錄(文件夾) */
{
return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) );
}
UINT8CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ) ?/* 發(fā)出命令碼和一字節(jié)數(shù)據(jù)后,等待中斷 */
{
xWriteCH376Cmd( mCmd );
xWriteCH376Data( mDat );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}