标签:
将UtoG,GtoU双向码表放到存储卡里面实现长文件名,因为FATFS长文件名需要unicode支持,
首先将UtoG.sys,GtoU.sys两个文件放到SD卡根目录,注意,一定要在根目录,并且是短文件名,因为长文件名需要UNICODE支持,此时的FATFS还是不支持长文件名的,但是当初始化UNICODE码表后就可以支持长文件名了.
两个码表下载地址:http://download.csdn.net/detail/cp1300/5526739
附上C代码
/************************************************************************************************************* * 文件名: unicode_gbk.c * 功能: 汉字编码转换 * 作者: cp1300@139.com * 创建时间: 2013-04-03 * 最后修改时间:2013-04-03 * 详细: 需要码表支持 *************************************************************************************************************/ #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 转 UCICODE 编码表位置 #define UtoG "0:/UtoG.sys" //UCICODE 转 GBK 编码表位置 static FIL GtoU_File; //GtoU 文件工作区 static FIL UtoG_File; //UtoG 文件工作区 /************************************************************************************************************************* * 函数 : u8 GBK_UNICODE_Init(void) * 功能 : 初始化GBK,UNICODE编码表 * 参数 : 无 * 返回 : 0:初始化成功;其它:初始化失败 * 依赖 : 底层读写函数 * 作者 : 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)!\r\n",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)!\r\n",GtoU, status); return 1; } return 0; } /************************************************************************************************************************* * 函数 : u16 OneGBKtoUNICODE(u16 GBKCode) * 功能 : 将GBK编码转换为unicode编码 * 参数 : GBK * 返回 : unicode * 依赖 : 底层读写函数 * 作者 : 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); //文件指针调到偏移位置 if(f_read(&GtoU_File, (u8 *)&data, 2, &bw) != FR_OK) //读取2字节 { 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; */ } /************************************************************************************************************************* * 函数 : u16 OneUNICODEtoGBK(u16 unicode) * 功能 : 将unicode编码转换为GBK编码 * 参数 : unicode * 返回 : GBK * 依赖 : 底层读写函数 * 作者 : 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)//是标点符号 { if(unicode<0XFF01||unicode>0XFF61) return 0x2020;//没有对应编码 //不能显示的字符就给两个空格填充,否则乱码 offset=unicode-0XFF01+0X9FA6-0X4E00; } offset *= 2; f_lseek(&UtoG_File, offset); //文件指针调到偏移位置 if(f_read(&UtoG_File, buff, 2, &bw) != FR_OK) //读取2字节 { return 0x2020; } temp = buff[0]; temp <<= 8; temp += buff[1]; return temp; //返回找到的编码 } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #else //码表直接在代码中 #include "unicode_gbk_code.h" /************************************************************************************************************************* * 函数 : u8 GBK_UNICODE_Init(void) * 功能 : 初始化GBK,UNICODE编码表 * 参数 : 无 * 返回 : 0:初始化成功;其它:初始化失败 * 依赖 : 底层读写函数 * 作者 : cp1300@139.com * 时间 : 2013-04-18 * 最后修改时间 : 2013-04-18 * 说明 : 无 *************************************************************************************************************************/ u8 GBK_UNICODE_Init(void) { return 0; } /************************************************************************************************************************* * 函数 : u16 OneGBKtoUNICODE(u16 GBKCode) * 功能 : 将GBK编码转换为unicode编码 * 参数 : GBK * 返回 : unicode * 依赖 : 底层读写函数 * 作者 : 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; } /************************************************************************************************************************* * 函数 : u16 OneUNICODEtoGBK(u16 unicode) * 功能 : 将unicode编码转换为GBK编码 * 参数 : unicode * 返回 : GBK * 依赖 : 底层读写函数 * 作者 : 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)//是标点符号 { if(unicode<0XFF01||unicode>0XFF61) return 0x2020;//没有对应编码 //不能显示的字符就给两个空格填充,否则乱码 offset=unicode-0XFF01+0X9FA6-0X4E00; } offset *= 2; temp = wGBKs[offset]; temp <<= 8; temp += wGBKs[offset+1]; return temp; //返回找到的编码 } #endif //GBK_UNICODE_IS_SDCARD /************************************************************************************************************************* * 函数 : void GBKToUnicode(u16 *pGBK, u16 *pUnicode, u32 cnt) * 功能 : 将多个GBK编码转换为UNICODE * 参数 : pGBK:GBK编码缓冲区 * pUnicode:UNCODE编码缓冲区 * cnt:转换编码个数 * 返回 : 无 * 依赖 : 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 ++; } } /************************************************************************************************************************* * 函数 : void UnicodeToGBK(u16 *pUnicode, u16 *pGBK, u32 cnt) * 功能 : 将多个UNICODE编码转换为GBK * 参数 : pUnicode:UNCODE编码缓冲区 * pGBK:GBK编码缓冲区 * cnt:转换编码个数 * 返回 : 无 * 依赖 : 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 ++; } }
修改cc963.c,FATFS的unicode编码支持文件
修改以下这个函数,主要讲这个文件里面的两个编码表注释掉,以实现节省单片机FLASH的目的。
#include "unicode_gbk.h" //编码转换 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之后马上初始化码表就可以实现用占用FLASH实现长文件名的支持,我的这个不光用在FATFS里面,还用在GSM模块的短信编码,解码上面。
标签:
原文地址:http://www.cnblogs.com/LittleTiger/p/4681936.html