目次

キャラクタ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フォントを格納するには
 次のシーケンスを使う。
  1. ファンクションで、格納するアドレスを指定
  2. データ転送で、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) ; } }

目次

inserted by FC2 system