目次
前
次
キャラクタLCD独自フォント作成
多くのキャラクタLCDには、独自フォントを定義し保存できる。
フォントサイズは、横5ビットx縦8ラインで、1フォントは
8バイト構成。
独自フォント利用は、LCDにヒストグラムを表示したい
場面に出くわしたから。
趣味のアマチュア無線では、バンドスコープと呼ぶ測定機器
の表示がある。指定周波数範囲の中に、突出して振幅の大きな
信号があるかを確認できる。
ヒストグラムをキャラクタLCDで表示するには
フォントジェネレータと転送機構が必要。
フォントジェネレータと転送機構を作成し
実用できるようにする。
フォントジェネレータは、テキストファイルにビット
パターンを入れ、AWKスクリプトでフォントを16進に
変換することで実現。
使い方は、CUIで次のようにする。
c:>gawk -f tt.awk tt.txt > pat.txt{enter}
スクリプトは、次のように記述。
{
result = 0
for ( i = 1 ; i < 6 ; i++ ) {
result = result * 2 + $i
}
printf("0x%02X,\n",result)
}
フォント定義のテキストファイル内容は以下。
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 1 1
生成テキストファイル内容は、次のようになった。
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x1F,
フォントを、Cの配列に入れて転送できるように成形。
char xpat0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F} ;
ヒストグラムは8パターンあるとして、柱の高さを
変えて定義しておく。
char xpat0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F} ;
char xpat1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F} ;
char xpat2[] = {0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F} ;
char xpat3[] = {0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F} ;
char xpat4[] = {0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F} ;
char xpat5[] = {0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F} ;
char xpat6[] = {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F} ;
char xpat7[] = {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F} ;
パターンが定義できたなら、LCDへの転送を考える。
データシートを読むと、1フォントを格納するには
次のシーケンスを使う。
- ファンクションで、格納するアドレスを指定
- データ転送で、8バイトの情報を8回転送
LCDに転送するには、CGRAMの6ビット構成アドレスの
割当てがどうなっているのか調べる。
上位3ビットがフォント全体のアドレス、下位3ビットが
そのフォントのビットごとのアドレスになっている。
ファンクション設定、データ転送を担当する関数が
put_lcd_function、put_lcd_dataだとし、フォント
をひとつだけ格納する関数を定義。
void set_cg(char xadr,char *ptr)
{
char loop ;
/* set address */
xadr <<= 3 ; /* shift font address */
xadr |= 0x40 ; /* add function command */
/* store bit pattern */
for ( loop = 0 ; loop < 8 ; loop++ ) {
/* set address */
put_lcd_function(xadr);
/* set data */
put_lcd_data( *ptr );
/* increment address */
xadr++ ;
/* next bit pattern */
ptr++ ;
}
}
コーリングシーケンスは、次のようにCGRAM
アドレス、配列開始アドレスを指定。
set_cg(0,(char *)(xpat0+0)) ;
set_cg(1,(char *)(xpat1+0)) ;
set_cg(2,(char *)(xpat2+0)) ;
set_cg(3,(char *)(xpat3+0)) ;
set_cg(4,(char *)(xpat4+0)) ;
set_cg(5,(char *)(xpat5+0)) ;
set_cg(6,(char *)(xpat6+0)) ;
set_cg(7,(char *)(xpat7+0)) ;
LCDの初期化の最後に、このフォント定義処理を
含めれば、呼び出して使える。
フォント表示には、'A'(=0x41)のように文字定数を
利用するが、定義したフォントは、定数0x00〜0x07
を与える。
2行x16桁のLCDの下段に、ヒストグラムを
表示するには、次のように指定する。
char loop ;
char msg[9] ;
/* set font access pointer */
*(msg+8) = '\0' ;
for ( loop = 0 ; loop < 8 ; loop++ ) {
*(msg+loop) = loop ;
}
/* show */
put_lcd_str(1,0,(char *)(msg+0)) ;
動作確認すると、次のように。
利用関数
フォント処理で利用した関数を示す。
初期化処理
void init_lcd(void)
{
/* initialize hardware */
delay_ms(45) ;
put_lcd_p4(OFF,0x30); /* select 8 bits */
delay_ms(5) ;
put_lcd_p4(OFF,0x30); /* select 8 bits */
delay_ms(1);
put_lcd_p4(OFF,0x30); /* select 8 bits */
delay_ms(1);
/* set function */
put_lcd_p4(OFF,0x20); /* select 4 bits */
delay_ms(1);
/* select 2 line display */
put_lcd_function(0x28);
delay_ms(1);
/* display off */
put_lcd_function(0x08);
delay_ms(1);
/* display on , cursor appear */
put_lcd_function(0x0e);
delay_ms(1);
/* entry mode*/
put_lcd_function(0x06);
delay_ms(1);
/* clear */
put_lcd_function(0x01);
delay_ms(1);
/* define font */
set_cg(0,(char *)(xpat0+0)) ;
set_cg(1,(char *)(xpat1+0)) ;
set_cg(2,(char *)(xpat2+0)) ;
set_cg(3,(char *)(xpat3+0)) ;
set_cg(4,(char *)(xpat4+0)) ;
set_cg(5,(char *)(xpat5+0)) ;
set_cg(6,(char *)(xpat6+0)) ;
set_cg(7,(char *)(xpat7+0)) ;
}
文字列表示
typedef unsigned char UBYTE ;
#define MASK80 0x80
void put_lcd_str(UBYTE r,UBYTE c,UBYTE *ptr)
{
UBYTE adr ;
/* check range */
if ( r > 1 ) return ;
if ( c > 7 ) return ;
/* set address */
adr = 0x00 ;
if ( r ) { adr += 0x40 ; }
adr += c ;
adr |= MASK80 ;
put_lcd_function(adr);
/* send character */
for ( adr = c ; adr < 16 ; adr++ ) {
put_lcd_data(*ptr);
ptr++ ;
}
}
ファンクション設定
void put_lcd_function(UBYTE xdat)
{
put_lcd_primitive(OFF,xdat);
}
データ設定
void put_lcd_data(UBYTE xdat)
{
put_lcd_primitive(ON,xdat);
}
8ビット転送
void put_lcd_primitive(UBYTE which,UBYTE dat)
{
put_lcd_p4(which,dat & MASKF0);
put_lcd_p4(which,(dat << 4) & MASKF0);
}
4ビット転送
void put_lcd_p4(UBYTE which,UBYTE dat)
{
/* LCD_E : OFF */
PORTD &= ~(1 << LCD_E) ;
/* LCD_RS : ON or OFF */
PORTD &= ~(1 << LCD_RS) ;
if ( which ) { PORTD |= (1 << LCD_RS) ;}
/* nibble */
{
/* clear upper nibble */
PORTD &= MASK0F ;
/* impress upper nibble */
PORTD |= (dat & MASKF0) ;
/* trigger H */
PORTD |= (1 << LCD_E) ;
/* delay */
delay_ms(1);
/* trigger L */
PORTD &= ~(1 << LCD_E) ;
}
}
目次
前
次