• FATFS外置UNICODE GBK双向转换码表(转)


    源:FATFS外置UNICODE GBK双向转换码表

    将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)!
    ",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)!
    ",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模块的短信编码,解码上面。

  • 相关阅读:
    bzoj4407 于神之怒加强版
    bzoj4600 [Sdoi2016]硬币游戏
    javascript 笔记(1)
    thinkphp 杂乱笔记(1)
    think ajax 应用
    jquery ajax post, get, javascript ajax post, get 处理
    文件操作 系统备份和还原,压缩,解压 tar dump/restore
    查看系统信息
    进程显示,删除,调度 ps, top kill
    相看系统中用户的信息 passwd, shadow
  • 原文地址:https://www.cnblogs.com/LittleTiger/p/4681936.html
Copyright © 2020-2023  润新知