求助CH376 由短文件名創(chuàng)建長(zhǎng)文件名出錯(cuò)

unsigned char?file_Shortname = "TEST-1~2.FAP";

unsigned char?FileName_Now = "TEST-12345-0200P";


unsigned int Creat_LongFile_Name(unsigned char *file_Shortname,unsigned char *ModelName)?

{

? ? unsigned int j; ? ??

? ? unsigned int s;?

? ? for ( j = 0; ModelName[j] != 0; j++ )?

? ? { ?// 復(fù)制并轉(zhuǎn)換長(zhǎng)文件名到LongNameBuf長(zhǎng)文件名緩沖區(qū)?

? ? ? LongNameBuf[j*2] = ModelName[j]; // 將英文字符轉(zhuǎn)換為兩字節(jié)的小端UNICODE編碼?

? ? ? LongNameBuf[j*2 + 1] = 0x00;

? ? } ??

? ? LongNameBuf[j*2] = 0x00; ? // 末尾用兩個(gè)0表示結(jié)束

? ? LongNameBuf[j*2 + 1] = 0x00; // 復(fù)制該長(zhǎng)文件名的ANSI編碼的全路徑的短文件名(8+3格式),短文件名由長(zhǎng)文件名生成(只要不沖突,其實(shí)隨便定)

? ?s = CH376CreateLongName( file_Shortname,LongNameBuf ); // 新建具有長(zhǎng)文件名的文件 L_NAME

? ?return (s); ? ? ?

}


unsigned int ? CH376CreateLongName( unsigned char * PathName, unsigned char * LongName )

{

? ?unsigned int i,s;

? ?unsigned char ? DirBlockCnt; ?/* 長(zhǎng)文件名占用文件目錄結(jié)構(gòu)的個(gè)數(shù) */

? ?unsigned int16 ?count; ? ? ?/* 臨時(shí)變量,用于計(jì)數(shù),用于字節(jié)讀文件方式下實(shí)際讀取的字節(jié)數(shù) */

? ?unsigned int16 ?NameCount; ? ?/* 長(zhǎng)文件名字節(jié)計(jì)數(shù) */

? ?unsigned int32 ?NewFileLoc; ? /* 當(dāng)前文件目錄信息在上級(jí)目錄中的起始位置,偏移地址 */?

? ?for ( count = 0; count < LONG_NAME_BUF_LEN; count += 2 )

? ?{

? ? ? if ( *(unsigned int16 *)(&LongName[count]) == 0 ) ?break; ?/* 到結(jié)束位置 */

? ?} ?

? ?if ( count == 0 || count >= LONG_NAME_BUF_LEN || count > LONE_NAME_MAX_CHAR )?

? ?{

? ? ? return( ERR_LONG_NAME_ERR ); ? /* 長(zhǎng)文件名無(wú)效 */

? ?}?

? ?DirBlockCnt = count / LONG_NAME_PER_DIR; ? /* 長(zhǎng)文件名占用文件目錄結(jié)構(gòu)的個(gè)數(shù) */?

? ?i = count - DirBlockCnt * LONG_NAME_PER_DIR;

? ?if ( i ) ? ? ? ? ? /* 有零頭 */

? ?{

? ? ? if ( ++ DirBlockCnt * LONG_NAME_PER_DIR > LONG_NAME_BUF_LEN )?

? ? ? {

? ? ? ? return( ERR_LONG_BUF_OVER ); ? ? /* 緩沖區(qū)溢出 */

? ? ? }

? ? ? count += 2; ? ? ? ? ? ? ? ? ?/* 加上0結(jié)束符后的長(zhǎng)度 */

? ? ? i += 2; ? ??

? ? ? if ( i < LONG_NAME_PER_DIR ) /* 最末的文件目錄結(jié)構(gòu)不滿 */

? ? ? { ?

? ? ? ? while ( i++ < LONG_NAME_PER_DIR )?

? ? ? ? {

? ? ? ? ? LongName[count++] = 0xFF; ?/* 把剩余數(shù)據(jù)填為0xFF */

? ? ? ? }

? ? ? }

? ?} ?

? ?// s = CH376FileOpenPath( PathName ); /* 打開(kāi)多級(jí)目錄下的文件 */?

?

? ?CH376FileOpen( C_connect ); ? // unsigned?C_connect[2]="/";?

? ?s = CH376FileOpen(PathName ); /* 打開(kāi)多級(jí)目錄下的文件 */

?

? ?if ( s != USB_INT_SUCCESS ) ?return( s ); ? ?

? ?i = CH376ReadVar8( VAR_FILE_DIR_INDEX ); /* 臨時(shí)用于保存當(dāng)前文件目錄信息在扇區(qū)內(nèi)的索引號(hào) */

? ?s = CH376LocateInUpDir( PathName ); /* 在上級(jí)目錄中移動(dòng)文件指針到當(dāng)前文件目錄信息所在的扇區(qū) */

? ?if ( s != USB_INT_SUCCESS ) ? ? ? ? ? ? ? ? ? ? ??

? ?{

? ? ? goto CH376CreateLongNameE;/* 沒(méi)有直接返回是因?yàn)槿绻蜷_(kāi)了根目錄那么必須要關(guān)閉后才能返回 */

? ?} ?

? ?NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ) + i * sizeof(FAT_DIR_INFO);/* 計(jì)算當(dāng)前文件目錄信息在上級(jí)目錄中的起始位置,偏移地址 */

? ?s = CH376ByteLocate( NewFileLoc ); ?/* 在上級(jí)目錄中移動(dòng)文件指針到當(dāng)前文件目錄信息的位置 */

? ?if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;

? ?s = CH376ByteRead( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO),0 );/* 以字節(jié)為單位讀取數(shù)據(jù),獲得當(dāng)前文件的目錄信息FAT_DIR_INFO */

? ?if ( s != USB_INT_SUCCESS ) ?goto CH376CreateLongNameE;

? ?for ( i = DirBlockCnt; i != 0; -- i ) /* 搜索空閑的文件目錄結(jié)構(gòu)用于存放長(zhǎng)文件名 */

? ?{ ?

? ? ? s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count );/* 以字節(jié)為單位讀取數(shù)據(jù),獲得下一個(gè)文件目錄信息FAT_DIR_INFO */

? ? ? if ( s != USB_INT_SUCCESS ) ? ?goto CH376CreateLongNameE;

? ? ? if ( count == 0 ) {break; } ? ?

? ? ? if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) ?/* 后面有正在使用的文件目錄結(jié)構(gòu),由于長(zhǎng)文件名必須連接存放,所以空間不夠,必須放棄當(dāng)前位置并向后轉(zhuǎn)移 */

? ? ? { ?

? ? ? ? s = CH376ByteLocate(NewFileLoc);/* 在上級(jí)目錄中移動(dòng)文件指針到當(dāng)前文件目錄信息的位置 */

? ? ? ? ?if ( s != USB_INT_SUCCESS ) ? ? goto CH376CreateLongNameE;

? ? ? ? ?GlobalBuf[ 0 ] = 0xE5; ? ? ? ? ? ? ?/* 文件刪除標(biāo)志 */

? ? ? ? ?for ( s = 1; s != sizeof(FAT_DIR_INFO); s ++ )?

? ? ? ? ?{

? ? ? ? ? ? ?GlobalBuf[ s ] = GlobalBuf[ sizeof(FAT_DIR_INFO) + s ];

? ? ? ? ?}

? ? ? ? ?s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) );?

? ? ? ? /* 寫(xiě)入一個(gè)文件目錄結(jié)構(gòu),用于刪除之前新建的文件,實(shí)際上稍后會(huì)將之轉(zhuǎn)移到目錄的最末位置 */

? ? ? ? ?if ( s != USB_INT_SUCCESS ) ? ?goto CH376CreateLongNameE;

? ? ? ? ?while ( count && GlobalBuf[0] )?

/* 如果仍然是正在使用的文件目錄結(jié)構(gòu)則繼續(xù)向后搜索,直到上級(jí)目錄結(jié)束或者有尚未使用過(guò)的文件目錄結(jié)構(gòu) */

? ? ? ? { ?

? ? ? ? ? ?s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); ?

? ? ? ? ? ?/* 以字節(jié)為單位讀取數(shù)據(jù),獲得下一個(gè)文件目錄信息FAT_DIR_INFO */ ? ? ? ? ??

? ? ? ? ? ?if ( s != USB_INT_SUCCESS ) ?goto CH376CreateLongNameE;

? ? ? ? } ? ? ? ??

? ? ? ? NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET );

? ? ? ? /* 用上級(jí)目錄的當(dāng)前文件指針作為當(dāng)前文件目錄信息在上級(jí)目錄中的起始位置 */

? ? ? ? i =DirBlockCnt+1;/* 需要的空閑的文件目錄結(jié)構(gòu)的個(gè)數(shù),包括短文件名本身一個(gè)和長(zhǎng)文件名 */

? ? ? ? if ( count == 0 ) ?break; ? ? ?/* 無(wú)法讀出數(shù)據(jù),上級(jí)目錄結(jié)束了 */

? ? ? ? NewFileLoc -= sizeof(FAT_DIR_INFO);/* 倒回到剛才搜索到的空閑的文件目錄結(jié)構(gòu)的起始位置 */

? ? ? }

? ?}

? ?if (i) /* 空閑的文件目錄結(jié)構(gòu)不足以存放長(zhǎng)文件名,原因是上級(jí)目錄結(jié)束了,下面增加上級(jí)目錄的長(zhǎng)度 */

? ?{ ?

? ? ? s = CH376ReadVar8( VAR_SEC_PER_CLUS ); ?/* 每簇扇區(qū)數(shù) */ ? ? ?

? ? ? if ( s == 128 ) ?/* FAT12/FAT16的根目錄,容量是固定的,無(wú)法增加文件目錄結(jié)構(gòu) */ ? ?

? ? ? ?{ ?

? ? ? ? ?s = ERR_FDT_OVER; ? ?/* FAT12/FAT16根目錄下的文件數(shù)應(yīng)該少于512個(gè),需要磁盤(pán)整理 */

? ? ? ? ?goto CH376CreateLongNameE;

? ? ? } ? ?

? ? ? count = s * DEF_SECTOR_SIZE; ? ? /* 每簇字節(jié)數(shù) */

? ? ? if ( count < i * sizeof(FAT_DIR_INFO) )?

? ? ? {

? ? ? ? count <<= 1; ? ? /* 一簇不夠則增加一簇,這種情況只會(huì)發(fā)生于每簇為512字節(jié)的情況下 */

? ? ? }

? ? ? s=CH376LongNameWrite(NULL,count);/*以字節(jié)為單位向當(dāng)前位置寫(xiě)入全0數(shù)據(jù)塊,清空新增加的文件目錄簇 */ ??

? ? ? if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;

? ?} ?

? ?s = CH376ByteLocate( NewFileLoc ); /* 在上級(jí)目錄中移動(dòng)文件指針到當(dāng)前文件目錄信息的位置 */

? ?if ( s != USB_INT_SUCCESS ) ? ?goto CH376CreateLongNameE; ?

? ?GlobalBuf[11] = ATTR_LONG_NAME;

? ?GlobalBuf[12] = 0x00;

? ?GlobalBuf[13]=CH376CheckNameSum(&GlobalBuf[sizeof(FAT_DIR_INFO)]);/*計(jì)算長(zhǎng)文件名的短文件名檢驗(yàn)和 */

? ?GlobalBuf[26] = 0x00;

? ?GlobalBuf[27] = 0x00;

? ?for ( s = 0; DirBlockCnt != 0; ) ? ? /* 長(zhǎng)文件名占用的文件目錄結(jié)構(gòu)計(jì)數(shù) */

? ?{ ?

? ? ? GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40; ?/* 首次要置長(zhǎng)文件名入口標(biāo)志 */

? ? ? DirBlockCnt --;

? ? ? NameCount = DirBlockCnt * LONG_NAME_PER_DIR;?

? ? ? for(s =1;s

? ? ? { ?

? ? ? ? ?if ( s == 1 + 5 * 2 )?

? ? ? ? ?{

? ? ? ? ? ? s = 14; ? ? ? ?/* 從長(zhǎng)文件名的第一組1-5個(gè)字符跳到第二組6-11個(gè)字符 */

? ? ? ? ?}

? ? ? ? ?else if ( s == 14 + 6 * 2 )?

? ? ? ? ?{

? ? ? ? ? ?s = 28; ? ? ?/* 從長(zhǎng)文件名的第二組6-11個(gè)字符跳到第三組12-13個(gè)字符 */

? ? ? ? ?}

? ? ? ? ?GlobalBuf[ s ] = LongName[ NameCount++ ];

? ? ? ? ?GlobalBuf[ s + 1 ] = LongName[ NameCount++ ];

? ? ? }

? ? ? s=CH376LongNameWrite(GlobalBuf,sizeof(FAT_DIR_INFO));

? ? ? /* 以字節(jié)為單位寫(xiě)入一個(gè)文件目錄結(jié)構(gòu),長(zhǎng)文件名 */ ? ? ? ?

? ? ? if ( s != USB_INT_SUCCESS ) ? ?goto CH376CreateLongNameE;

? ?}

? ?s = CH376LongNameWrite(&GlobalBuf[sizeof(FAT_DIR_INFO)],sizeof(FAT_DIR_INFO));?

? ? /* 以字節(jié)為單位寫(xiě)入一個(gè)文件目錄結(jié)構(gòu),這是轉(zhuǎn)移來(lái)的之前新建的文件的目錄信息 */


CH376CreateLongNameE:?

? ?CH376FileClose( FALSE ); ? ? /* 對(duì)于根目錄則必須要關(guān)閉 */

? ?return( s );

}



unsigned int CH376LocateInUpDir( unsigned char * PathName_s)?

{

? ?unsigned int ? s,c;

? ?unsigned char ?BufData1[64];

? ?xWriteCH376Cmd( CMD14_READ_VAR32 );

? ?xWriteCH376Data( VAR_FAT_DIR_LBA ); ? /* 當(dāng)前文件目錄信息所在的扇區(qū)LBA地址 */

? ?for ( s = 4; s != 8; s ++ )?

? ?{

? ? ?BufData1[s] = xReadCH376Data( ); /* 臨時(shí)保存于全局緩沖區(qū)中,節(jié)約RAM */

? ?} ?

? ?s = CH376SeparatePath(PathName_s);

? ?/*從路徑中分離出最后一級(jí)文件名或者目錄名,返回最后一級(jí)文件名或者目錄名的偏移 */

? ?if ( s )

? ?{

? ? ? s=CH376FileOpenDir(PathName_s,s);/*多級(jí)目錄,打開(kāi)多級(jí)目錄下最后一級(jí)目錄,即打開(kāi)文件的上級(jí)目錄*/

? ?}

? ?else?

? ?{

? ? ??s = CH376FileOpen("/");?? ? ?/* 根目錄下的文件,則打開(kāi)根目錄 */

? ?}

? ?if ( s != ERR_OPEN_DIR ) ?// ?ERR_OPEN_DIR = 0x41;

? ?{

? ? ? ?return( s );

? ?}

? ?*(unsigned int32 *)( &BufData1[0] )= 0; ?/*目錄扇區(qū)偏移扇區(qū)數(shù),保存在全局緩沖區(qū)中,節(jié)約RAM */

? ?while(1) ?/* 不斷移動(dòng)文件指針,直到與當(dāng)前文件目錄信息所在的扇區(qū)LBA地址匹配 */

? ?{ ?

? ? s=CH376SecLocate(*(unsigned int32*)(&BufData1[0]));/*以扇區(qū)為單位在上級(jí)目錄中移動(dòng)文件指針 */

? ? ? if ( s != USB_INT_SUCCESS ) ?return( s );

? ? ? CH376ReadBlock( &BufData1[8] ); /*從內(nèi)存緩沖區(qū)讀取CH376_CMD_DATA.SectorLocate.mSectorLba數(shù)據(jù)塊,返回長(zhǎng)度總是sizeof(CH376_CMD_DATA.SectorLocate) */?

? ? ? if ( *(unsigned int32 *)(&BufData1[8]) == *(unsigned int32 *)(&BufData1[4]) )?

? ? ? {

? ? ? ? return( USB_INT_SUCCESS ); ? ? /* 已到當(dāng)前文件目錄信息扇區(qū) */

? ? ? }

? ? ? xWriteCH376Cmd( CMD50_WRITE_VAR32 );

? ? ? xWriteCH376Data( VAR_FAT_DIR_LBA );/* 得到前一個(gè)扇區(qū),設(shè)置為新的文件目錄信息扇區(qū)LBA地址 */

? ? ? for ( s = 8; s != 12; s ++ )?

? ? ? {

? ? ? ? c = BufData1[s];

? ? ? ? xWriteCH376Data(c);

? ? ? }

? ? ? ++ *(unsigned int32 *)(&BufData1[0]);

? ?}

}


unsigned int ? CH376SeparatePath( unsigned char *path )

{

? unsigned char *pName;

? for ( pName = path; *pName != 0; ++pName ); ? ?/* 到文件名字符串結(jié)束位置 */

? while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path )?

? { ??

? ? pName --; ? ? ? ? /* ?搜索倒數(shù)第一個(gè)路徑分隔符 */ ??

? }

? if ( pName != path )?

? {

? ?pName++;/*找到路徑分隔符,則修改指向目標(biāo)文件的最后一級(jí)文件名,跳過(guò)前面的多級(jí)目錄名及路徑分隔符*/

? }

? return((unsigned int)(pName - path));

}


SPI方式?

PIC24EP256GU814 ? 16位單片機(jī)調(diào)用s=Creat_LongFile_Name(file_Shortname,FileName_Now);運(yùn)行到紅色字體處出錯(cuò),s = CH376FileOpen("/");?返回S = 0X42;急求大神們幫忙


你的短文件名不是全路徑的? 試試unsigned char?file_Shortname = "/TEST-1~2.FAP";


謝謝您的回復(fù),我程序中是有分兩步的,見(jiàn)程序中藍(lán)色字體部分

CH376FileOpen( C_connect ); ? ? ? ? ? // unsigned?C_connect[2]="/";?

s = CH376FileOpen(PathName ); ? ? ? /* 打開(kāi)多級(jí)目錄下的文件 */

之前在PIC 8位單片機(jī)中運(yùn)行是沒(méi)問(wèn)題的,現(xiàn)在用的是16位單片機(jī),分析了好久,不知道是什么原因,急求幫忙


你的TEST-1~2.FAP文件在執(zhí)行程序之前必須是已經(jīng)存在于根目錄的,比較有局限性。建議使用FILE_SYS.C提供的長(zhǎng)文件處理函數(shù)。如果程序里只執(zhí)行s = CH376FileOpen("/");?會(huì)報(bào)S = 0X42嗎?嘗試把CH376FileOpen("/")改成CH376FileOpen("/\0") 試一下。


收藏


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频