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