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;急求大神們幫忙