FATFS外置UNICODE GBK雙向轉(zhuǎn)換碼表
將UtoG,GtoU雙向碼表放到存儲卡里面實現(xiàn)長文件名,因為FATFS長文件名需要unicode支持,
首先將UtoG.sys,GtoU.sys兩個文件放到SD卡根目錄,注意,一定要在根目錄,并且是短文件名,因為長文件名需要UNICODE支持,此時的FATFS還是不支持長文件名的,但是當(dāng)初始化UNICODE碼表后就可以支持長文件名了.
兩個碼表下載地址:http://download.csdn.net/detail/cp1300/5526739
附上C代碼
/*************************************************************************************************************
* 文件名: unicode_gbk.c
* 功能: 漢字編碼轉(zhuǎn)換
* 作者: cp1300@139.com
* 創(chuàng)建時間: 2013-04-03
* 最后修改時間:2013-04-03
* 詳細(xì): 需要碼表支持
*************************************************************************************************************/
#include "system.h"
#include "unicode_gbk.h"
#define GBK_UNICODE_IS_SDCARD 1 //GBK,UNICODE編碼表在SD卡或其它存儲器中
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//碼表在SD卡中
#if GBK_UNICODE_IS_SDCARD
#include "ff.h"
#define GtoU "0:/GtoU.sys" //GBK 轉(zhuǎn) UCICODE 編碼表位置
#define UtoG "0:/UtoG.sys" //UCICODE 轉(zhuǎn) GBK 編碼表位置
static FIL GtoU_File; //GtoU 文件工作區(qū)
static FIL UtoG_File; //UtoG 文件工作區(qū)
/*************************************************************************************************************************
* 函數(shù) : u8 GBK_UNICODE_Init(void)
* 功能 : 初始化GBK,UNICODE編碼表
* 參數(shù) : 無
* 返回 : 0:初始化成功;其它:初始化失敗
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 2013-04-18
* 最后修改時間 : 2013-04-18
* 說明 : 無
*************************************************************************************************************************/
u8 GBK_UNICODE_Init(void)
{
FRESULT status;
status = f_open(&UtoG_File, UtoG, FA_OPEN_EXISTING | FA_READ); //以只讀方式打開UNICODEtoGBK碼表,打開失敗返回錯誤
if(status != FR_OK) //打開失敗
{
uart_printf("open %s error (%d)!rn",UtoG, status);
return 1;
}
status = f_open(&GtoU_File, GtoU, FA_OPEN_EXISTING | FA_READ); //以只讀方式打開GBKtoUNICODE碼表,打開失敗返回錯誤
if(status != FR_OK) //打開失敗
{
uart_printf("open %s error (%d)!rn",GtoU, status);
return 1;
}
return 0;
}
/*************************************************************************************************************************
* 函數(shù) : u16 OneGBKtoUNICODE(u16 GBKCode)
* 功能 : 將GBK編碼轉(zhuǎn)換為unicode編碼
* 參數(shù) : GBK
* 返回 : unicode
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 20120602
* 最后修改時間 : 20120602
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
u16 OneGBKtoUNICODE(u16 GBKCode)
{
u8 ch,cl;
UINT bw;
u16 data;
ch = GBKCode >> 8;
cl = GBKCode & 0x00ff;
ch -= 0x81;
cl -= 0x40;
f_lseek(&GtoU_File, (ch*0xbf+cl)*2); //文件指針調(diào)到偏移位置
if(f_read(&GtoU_File, (u8 *)&data, 2, &bw) != FR_OK) //讀取2字節(jié)
{
return 0x1fff;
}
return (ch<=0x7d && cl<=0xbe) ? data : 0x1fff;
/* ch = GBKCode >> 8;
cl = GBKCode & 0x00ff;
ch -= 0x81;
cl -= 0x40;
return (ch<=0x7d && cl<=0xbe) ? wUnicodes[ch*0xbf+cl] : 0x1fff; */
}
/*************************************************************************************************************************
* 函數(shù) : u16 OneUNICODEtoGBK(u16 unicode)
* 功能 : 將unicode編碼轉(zhuǎn)換為GBK編碼
* 參數(shù) : unicode
* 返回 : GBK
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 20120602
* 最后修改時間 : 20120602
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
u16 OneUNICODEtoGBK(u16 unicode) //用二分查找算法
{
u32 offset;
u16 temp;
UINT bw;
u8 buff[2];
if(unicode<=0X9FA5)
{
if(unicode>=0X4E00)
offset=unicode-0X4E00;//0x1b87 //0X4E00,漢字偏移起點
else
return 0x2020; //不能顯示的字符就給兩個空格填充,否則亂碼
}
else if(unicode>0X9FA5)//是標(biāo)點符號
{
if(unicode<0XFF01||unicode>0XFF61)
return 0x2020;//沒有對應(yīng)編碼 //不能顯示的字符就給兩個空格填充,否則亂碼
offset=unicode-0XFF01+0X9FA6-0X4E00;
}
offset *= 2;
f_lseek(&UtoG_File, offset); //文件指針調(diào)到偏移位置
if(f_read(&UtoG_File, buff, 2, &bw) != FR_OK) //讀取2字節(jié)
{
return 0x2020;
}
temp = buff[0];
temp <<= 8;
temp += buff[1];
return temp; //返回找到的編碼
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#else //碼表直接在代碼中
#include "unicode_gbk_code.h"
/*************************************************************************************************************************
* 函數(shù) : u8 GBK_UNICODE_Init(void)
* 功能 : 初始化GBK,UNICODE編碼表
* 參數(shù) : 無
* 返回 : 0:初始化成功;其它:初始化失敗
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 2013-04-18
* 最后修改時間 : 2013-04-18
* 說明 : 無
*************************************************************************************************************************/
u8 GBK_UNICODE_Init(void)
{
return 0;
}
/*************************************************************************************************************************
* 函數(shù) : u16 OneGBKtoUNICODE(u16 GBKCode)
* 功能 : 將GBK編碼轉(zhuǎn)換為unicode編碼
* 參數(shù) : GBK
* 返回 : unicode
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 20120602
* 最后修改時間 : 20120602
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
u16 OneGBKtoUNICODE(u16 GBKCode)
{
u8 ch,cl;
ch = GBKCode >> 8;
cl = GBKCode & 0x00ff;
ch -= 0x81;
cl -= 0x40;
return (ch<=0x7d && cl<=0xbe) ? wUnicodes[ch*0xbf+cl] : 0x1fff;
}
/*************************************************************************************************************************
* 函數(shù) : u16 OneUNICODEtoGBK(u16 unicode)
* 功能 : 將unicode編碼轉(zhuǎn)換為GBK編碼
* 參數(shù) : unicode
* 返回 : GBK
* 依賴 : 底層讀寫函數(shù)
* 作者 : cp1300@139.com
* 時間 : 20120602
* 最后修改時間 : 20120602
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
u16 OneUNICODEtoGBK(u16 unicode) //用二分查找算法
{
u32 offset;
u16 temp;
if(unicode<=0X9FA5)
{
if(unicode>=0X4E00)
offset=unicode-0X4E00;//0x1b87 //0X4E00,漢字偏移起點
else
return 0x2020; //不能顯示的字符就給兩個空格填充,否則亂碼
}
else if(unicode>0X9FA5)//是標(biāo)點符號
{
if(unicode<0XFF01||unicode>0XFF61)
return 0x2020;//沒有對應(yīng)編碼 //不能顯示的字符就給兩個空格填充,否則亂碼
offset=unicode-0XFF01+0X9FA6-0X4E00;
}
offset *= 2;
temp = wGBKs[offset];
temp <<= 8;
temp += wGBKs[offset+1];
return temp; //返回找到的編碼
}
#endif //GBK_UNICODE_IS_SDCARD
/*************************************************************************************************************************
* 函數(shù) : void GBKToUnicode(u16 *pGBK, u16 *pUnicode, u32 cnt)
* 功能 : 將多個GBK編碼轉(zhuǎn)換為UNICODE
* 參數(shù) : pGBK:GBK編碼緩沖區(qū)
* pUnicode:UNCODE編碼緩沖區(qū)
* cnt:轉(zhuǎn)換編碼個數(shù)
* 返回 : 無
* 依賴 : OneGBKtoUNICODE
* 作者 : cp1300@139.com
* 時間 : 20130403
* 最后修改時間 : 20130403
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
void GBKToUnicode(u16 *pGBK, u16 *pUnicode, u32 cnt)
{
while(cnt --)
{
*pUnicode = OneGBKtoUNICODE(*pGBK ++);
pUnicode ++;
}
}
/*************************************************************************************************************************
* 函數(shù) : void UnicodeToGBK(u16 *pUnicode, u16 *pGBK, u32 cnt)
* 功能 : 將多個UNICODE編碼轉(zhuǎn)換為GBK
* 參數(shù) : pUnicode:UNCODE編碼緩沖區(qū)
* pGBK:GBK編碼緩沖區(qū)
* cnt:轉(zhuǎn)換編碼個數(shù)
* 返回 : 無
* 依賴 : OneUNICODEtoGBK
* 作者 : cp1300@139.com
* 時間 : 20130403
* 最后修改時間 : 20130403
* 說明 : 需要flash中的碼表支持
GBK碼范圍,高8位:0x81~0xfe;低8位:0x40~0xfe
*************************************************************************************************************************/
void UnicodeToGBK(u16 *pUnicode, u16 *pGBK, u32 cnt)
{
while(cnt --)
{
*pGBK = OneUNICODEtoGBK(*pUnicode ++);
pGBK ++;
}
}
/*************************************************************************************************************
* 文件名: unicode_gbk.h
* 功能: 漢字編碼轉(zhuǎn)換
* 作者: cp1300@139.com
* 創(chuàng)建時間: 2013-04-03
* 最后修改時間:2013-04-03
* 詳細(xì): 需要碼表支持
*************************************************************************************************************/
#ifndef UNICODE_GBK_H_
#define UNICODE_GBK_H_
#include "system.h"
u8 GBK_UNICODE_Init(void);
u16 OneGBKtoUNICODE(u16 GBKCode);
u16 OneUNICODEtoGBK(u16 unicode);
void GBKToUnicode(u16 *pGBK, u16 *pUnicode, u32 cnt); //將多個GBK編碼轉(zhuǎn)換為UNICODE
void UnicodeToGBK(u16 *pUnicode, u16 *pGBK, u32 cnt); //將多個UNICODE編碼轉(zhuǎn)換為GBK
#endif /*UNICODE_GBK_H_*/
修改cc963.c,FATFS的unicode編碼支持文件
修改以下這個函數(shù),主要講這個文件里面的兩個編碼表注釋掉,以實現(xiàn)節(jié)省單片機(jī)FLASH的目的.
#include "unicode_gbk.h" //編碼轉(zhuǎn)換
WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
)
{
WCHAR c;
if (src < 0x80) { /* ASCII */
c = src;
}
else
{
if (dir)
{ /* OEMCP to unicode */
c = OneGBKtoUNICODE(src);
}
else
{ /* Unicode to OEMCP */
c = OneUNICODEtoGBK(src);
}
}
return c;
}
#endif
這樣只要在初始化了FATFS之后馬上初始化碼表就可以實現(xiàn)用占用FLASH實現(xiàn)長文件名的支持,我的這個不光用在FATFS里面,還用在GSM模塊的短信編碼,解碼上面.