在卡西欧(CASIO)DT930上显示中文的方法

当我刚接触卡西欧(CASIO)DT930开发的时候,遇到最难的问题之一,是如何显示中文。后来经过很多摸索,终于找到解决
的办法,现在总结出来,希望能帮助遇到同样困难的朋友。
一、显示中文的基本步骤
---程序中要做的事---
1、调用lcd_usrfont()注册字库。注意确保注册路径和字库文件实际路径一致。
2、调用dat_system()把屏幕的点阵模式设置成与字库一致。
3、调用cputstr()显示中文。
---编译时要做的事---
4、用开发包提供的kj.exe,将程序里的中文转换为ASCII码形式。因为DT930的C编译器只支持英文,所以当程序里含有中文的时候,
必须先用kj.exe将其转换为ASCII码形式,否则是不能通过编译这一关的。程序里含有日文时也是用kj.exe转换。
5、接下来与一般的编译步骤相同。
---要下载的文件---
6、编译好的程序文件(.LOD)。
7、启动引导文件(astart.hts)。
7、字库文件:font6sk.fon。注意确保存放路径与lcd_usrfont()的注册路径一致。
二、常见问题及解决方法
按照上面的步骤操作,应能正确显示中文,如果显示出奇怪的字或符号,或中文躺着而且不完整,参考以下几种原因:
1、没有字库文件。
解决方法:下载字库。
2、没有用lcd_usrfont()注册字库文件。
解决方法:用lcd_usrfont()注册字库,确保注册路径和字库文件实际路径一致。
3、字库文件不适用。
解决方法:检查字库文件名是不是“font6sk.fon”,如果不是,该字库很可能不适用于DT930,请重新下载。
我见过的字库文件有3个:font6sk.fon、font6sl.fon、hzk12s.fnt,第1个是DT930适用的;第2个适用于DT900,用在
DT930上显示出来的中文是躺下的,而且不完整;第3个不会用。
当然,字库文件的名字是可以改的,文件名只能作为判断的参考依据,但如果中文躺着而且不完整,基本上可以断定是
字库不适用。
4、屏幕点阵模式与字库不一致。
如上述,我见过的字库文件中,适用于DT930的只有font6sk.fon,它是一个6点阵的字库,因此要用它显示中文,须将
屏幕点阵模式设置为6点阵。但字库肯定不是只有6点阵的,如果您使用其他点阵规格的字库,请设置相应的点阵模式。
三、屏幕容量和坐标
由于我只用过6点阵的字库,下面只针对6点阵的情况予以说明。对于其它模式的情况,可参考
《DT-930 Series C Library Manual (Version 1.00)》第70页。
单屏能显示的行、列数受字型(ANK)和属性(ATTR)两个参数同时影响,下表列出各种组合的情况:
ANK ATTR 屏幕容量 行坐标 列坐标
-------------------------------------------------------------------------------------------------------------------------------------
中文 LCD_ANK_STANDARD       LCD_ATTR_NORMAL          5行×10列 1,3,5,7,9        0,2,4,..18
LCD_ANK_STANDARD       LCD_ATTR_DOUBLE           5行×5列 1,3,5,7,9       0,4,8,12,16
LCD_ANK_LIGHT 任意 中文不支持LCD_ANK_LIGHT
------------------------------------------------------------------------------------------------------------------------------------
英文    LCD_ANK_STANDARD LCD_ATTR_NORMAL          5行×21列      1,3,5,7,9        0,1,2,..20
LCD_ANK_STANDARD LCD_ATTR_DOUBLE           5行×10列      1,3,5,7,9        0,2,4,..18
LCD_ANK_LIGHT LCD_ATTR_NORMAL         10行×21列     0~9                0~20
LCD_ANK_LIGHT LCD_ATTR_DOUBLE         10行×10列     0~9                0,2,4,..18
四、小技巧
1、快速显示中文。
有两个关键:一是把A盘格式化为DT700格式;二是把字库文件放在A盘下。这样处理时中文的显示速度最快。
2、让字库不会断电丢失。
《使卡西欧(CASIO)DT930程序不会断电丢失的方法》一文中,我们知道当DT930的电池被耗尽后,A盘的所有数据
都会丢失,但如上述,要快速显示中文,字库文件必须放在A盘。如何做到既快速显示,又不怕字体丢失呢?
方法很简单,就是把字库文件下载到B盘,然后让程序在启动时检查A盘有没有字库文件,没有就从B盘复制过来。程序
总是使用A盘的字库。
五、一个综合运用的小程序
上面介绍了这么多内容,最后让我用一个小程序,把所有的知识都串联起来,如果您有DT930和开发环境,按下面的方
法编译源程序,运行后会看到各种字体的显示效果。^_^
1、源程序
(1)程序代码。存为“chinese.c”。
#include    <stdio.h>
#include    <stdlib.h>
#include    "itron.h"
#include    "cmndef.h"
#include    "bios1mac.h"
#define     WAIT            {while ((key_check()) == 0xFFFFFFFF); key_clear();}
#define     DT930 /*如要在DT900上运行,请注释本行*/
#ifdef        DT930
#define     FONT_FILE       "a:\\font6sk.fon"
#define     FONT_BAK       "b:\\font6sk.fon"
#else
#define     FONT_FILE       "a:\\font6sl.fon"
#define     FONT_BAK       "b:\\font6sl.fon"
#endif
/*
显示中英文字串。先要用kj.exe转换。
这是在网上找到的一段代码,感谢网友们的分享精神。
*/
int cputstr(int attrib , unsigned char *string)
{
    int i;
    unsigned char strtemp[67],ss0,ss1;
    for(i=0;i<66;i+=2)
    {
        if(string[i]==0)
        {
            break;
        }
        else if(string[i+1]==0)
        {  
            strtemp[i]=string[i];
            i++;
            break;
        }
        if(string[i]<0x80)
        {
            strtemp[i]=string[i];
            if(string[i+1]<0x80)
            {
                strtemp[i+1]=string[i+1];
                continue;
            }
            else
                i++;
        }
        if(string[i]==0xa3)
        {
            strtemp[i]=0xe8;
            strtemp[i+1]=string[i+1]-0xa1+0x40+95;
        }
        else
        {
            ss0=string[i]-0xb0;
            ss1=string[i+1]-0xa1+0x40;
            if (ss0<8)
            {
                strtemp[i]=(ss0/2)+0x81;
                if(ss0%2)
                {
                    strtemp[i+1]=ss1+95;
                }
                else
                {
                    if(ss1>0x7e)
                        ss1++;
                    strtemp[i+1]=ss1;
                }
            }
            else if(ss0<0x37)
            {
                strtemp[i]=((ss0+1)/2)+0x84;
                if((ss0+1)%2)
                {
                    strtemp[i+1]=ss1+95;
                }
                else
                {
                    if(ss1>0x7e)
                        ss1++;
                    strtemp[i+1]=ss1;
                }
            }
            else
            {
                ss0=ss0-0x37;
                strtemp[i]=(ss0/2)+0xe0;
                if(ss0%2)
                {
                    strtemp[i+1]=ss1+95;
                }
                else
                {
                    if(ss1>0x7e)
                        ss1++;
                    strtemp[i+1]=ss1;
                }
            }
        }
    }
    strtemp[i]=0;
    lcd_csr_set( LCD_CSR_OFF );
    lcd_string(LCD_ANK_STANDARD,attrib,(UB*)strtemp,LCD_LF_OFF);
    return(0); 
}
/*判断文件是否存在*/
int FileExists(const char *File)
{
    FILE *fp;
    fp = fopen(File , "r");
    if (fp)
    {
        fclose(fp);
        return 1;
    }
    else
    {
        return 0;
    }
}
/*用Sour指定的文件覆盖Dest指定的文件*/
int CoverFile(const char *Dest , const char *Sour)
{
    FILE *fpSour , *fpDest;
    char buf[1000];
    int n;
    fpSour = fopen(Sour , "rb");
    fpDest = fopen(Dest , "wb");
    if (fpSour && fpDest)
    {
        n = fread(buf , sizeof(buf[0]) , sizeof(buf) , fpSour);
        while (n > 0)
        {
            fwrite(buf , sizeof(buf[0]) , n , fpDest);
            n = fread(buf , sizeof(buf[0]) , sizeof(buf) , fpSour);
        }
        fclose(fpSour);
        fclose(fpDest);
        return 1;
    }
    else
    {
        fclose(fpSour);
        fclose(fpDest);
        return 0;
    }
}
/*程序从这里开始执行,相当于命令行程序的main()或Windows程序的WinMain()*/
void ap_start( void )
{   
    ER Ercd;
    DAT_DSP_STR InitSettings, DisplaySettings;
    Ercd = dat_system(SYSD_FNC_READ, SYSD_DSP, &InitSettings);
    DisplaySettings = InitSettings;
    DisplaySettings.font_md = FONT6_SET;
    Ercd = dat_system(SYSD_FNC_WRITE, SYSD_DSP, &DisplaySettings);
    lcd_csr_put(3 , 0);
    lcd_string(LCD_ANK_STANDARD , LCD_ATTR_NORMAL , (UB*)"Preparing Font..." , LCD_LF_OFF);
    if (FileExists(FONT_FILE) || CoverFile(FONT_FILE,FONT_BAK)) /*检查A盘的字体文件,如果丢失从B盘复制过来*/
    {
        lcd_usrfont(LCD_K6_FILE , FONT_FILE); /*使用A盘的字体文件,加快显示速度。记得格式化为DT700格式*/
    }
    else
    {
        lcd_csr_put(5 , 0);
        lcd_string(LCD_ANK_STANDARD , LCD_ATTR_NORMAL , (UB*)"Font File Missing!!!" , LCD_LF_OFF);
        WAIT; /*等待按任意键*/
        exit(0);
    }
    lcd_csr_put(1 , 0);
    cputstr(LCD_ATTR_NORMAL , (UB*)"壹贰叁肆伍陆柒捌玖拾"); /*标准中文*/
    lcd_csr_put(3 , 0);
    cputstr(LCD_ATTR_WIDTH , (UB*)"壹贰叁肆伍陆柒捌玖拾"); /*加粗中文*/
    lcd_csr_put(5 , 0);
    cputstr(LCD_ATTR_REVERS , (UB*)"壹贰叁肆伍陆柒捌玖拾"); /*反显中文*/
    lcd_csr_put(7 , 0);
    cputstr(LCD_ATTR_DOUBLE , (UB*)"壹贰叁肆伍"); /*加宽中文*/
    lcd_csr_put(8 , 0);
    lcd_string(LCD_ANK_LIGHT , LCD_ATTR_NORMAL  , (UB*)"12345678901234567890" , LCD_LF_OFF); /*半高英文*/
    lcd_csr_put(9 , 0);
    lcd_string(LCD_ANK_LIGHT , LCD_ATTR_DOUBLE  , (UB*)"1234567890" , LCD_LF_OFF); /*半高加宽英文*/
    /*lcd_string(LCD_ANK_LIGHT , LCD_ATTR_DOUBLE | LCD_ATTR_REVERS , (UB*)"1234567890" , LCD_LF_OFF);*/ /*叠加两种属性,半高反显加宽英文*/
    WAIT; /*等待按任意键*/
}
(2)连接命令文件。存为“chinese.org”,与上述文件同路径。
INPUT AP_START.OBJ,&
AP_INIT.OBJ,& 
CHINESE.OBJ
LIBRARY ..\LIB\SHCLIB.LIB ;路径应与您的开发环境一致
LIBRARY ..\LIB\HICIF.LIB ;路径应与您的开发环境一致
ROM (D,R) 
START P,C,D,hicif(09048030) 
OUTPUT .\CHINESE
PRINT .\CHINESE
FORM A 
EXIT  
(3)编译批处理文件。存为“chinese.bat”,与上述文件同路径。
del chinese.abs
del chinese.map
del chinese.mot
del chinese.obj
del chinese.lod
copy chinese.org chinese.sub
rem 下面的路径应与您的开发环境相符
SET DRV=C:\DT930NEW
SET DOS16M=0@1M;2M
SET SHC_LIB=C:\DT930NEW\BIN
SET SHC_TMP=C:\
SET SHC_INC=C:\DT930NEW\INCLUDE
kj chinese.c chinese.cnv
rem 这里 shc /i 的路径应与您的开发环境相符
shc /i=c:\DT930new\include /OB=chinese.obj chinese.cnv 
lnk -subcommand=chinese.sub
submk chinese.sub
lnk -subcommand=chinese.sub
cnvs chinese
apcnvy chinese.mot chinese.lod
(4)启动引导文件。存为“astart.hts”,与上述文件同路径。
b:\chinese.lod
2、编译方法
(1)用文本编辑器编辑上述4个文件,分别用指定的名字,保存到同一路径下。
(2)运行chinese.bat进行编译。
(3)编译完成后,将 chinese.lod、font6sk.fon、astart.hts、patch001.lod、patch002.lod 下载到DT930的B盘即可。
3、还有几点要说明
(1)用cputstr()和lcd_string()都能正确显示英文和数字,但cputstr()固定显示标准字体(LCD_ANK_STANDARD),而
lcd_string()还能显示半高字体(LCD_ANK_LIGHT)。当然,只要为cputstr()增加一个参数,允许字体规格传进去,则
显示半高字体不是问题,只不过中文没有半高字体,而cputstr()通常用于显示中文,所以简化了参数。
(2)要显示中文,必须使用cputstr(),用lcd_string()显示中文是乱码。
(3)可以用或运算叠加多种属性(ATTR),例如要显示“反显加宽英文”,可将属性设置为:LCD_ATTR_REVERS | LCD_ATTR_DOUBLE。
(4)DT900、DT930、DT940的执行文件(.LOD)是通用的,但DT900与DT930、DT940的字体文件不通用,后两者的字库文件通用。

posted @ 2012-02-16 09:27  小冰岛  阅读(6104)  评论(0编辑  收藏  举报
        联系人 :梁小姐
       联系方式:18665009335
        邮箱 :busi@gzgolem.com