在卡西歐(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的字體文件不通用,后兩者的字庫文件通用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM