目次
前
次
キャラクタLCDの4ピン制御
キャラクタLCDは、14ピンをもち、4種類に分けられる。
- 電源ピン Vdd GND
- コントラスト調整 Vo
- 制御ピン E RS WR
- データ DB0 -> DB7
通常は、キャラクタLCDからデータを入力することは殆どないので
WRピンを、0Vに固定し、書き込みだけできるようにすればよい。
制御ピンがE RS の2本、データピンが8本の合計10ピンで、表示を
制御できる。
場合によっては、10ピンを利用できないこともある。シフトレジスタ
74HC164を利用し、データを2ビットで一度レジスタにラッチ後
LCDに転送すれば、4ピンで制御できる。
回路は、下図のようにする。
最下層処理
74HC164のデータ入力A、Bに同じデータを入力し、クロックを
与えれば8ビットのデータを転送できる。
LCDにデータを転送するシーケンスは、以下とする。
- シフトレジスタにデータを転送する
- EをLにする
- RSを、HかLのどちらかに設定
- データ8ビットを出力
- EをHにする
- EをLにする
シフトレジスタにデータを転送するシーケンスは、以下とする。
- シフトレジスタのCLKをLにする
- 2^7(MSB)ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^6ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^5ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^4ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^3ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^2ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^1ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
- 2^0ビットを出力
- シフトレジスタのCLKをHにする
- シフトレジスタのCLKをLにする
最下層処理関数
メモリマップドI/OとI/OマップドI/Oで、動作の違いがあるので
それぞれの関数を定義する。
メモリマップドI/Oの場合
typedef unsigned char UBYTE ;
#define OFF 0
#define ON OFF+1
void put_lcd_primitive(UBYTE which,UBYTE dat)
{
UBYTE i ;
/* send 8 bit data */
SHF_CLK = OFF ;
for ( i = 0 ; i < 8 ; i++ ) {
SHF_DAT = OFF ;
if ( dat & 0x80 ) { SHF_DAT = ON ; }
SHF_CLK = ON ;
dat <<= 1 ;
SHF_CLK = OFF ;
}
/* 0 -> E */
LCD_E = OFF ;
/* RS */
LCD_RS = which ;
/* 1 -> E */
LCD_E = ON ;
/* 0 -> E */
LCD_E = OFF ;
}
I/OマップドI/Oの場合
void put_lcd_primitive(UBYTE which,UBYTE dat)
{
UBYTE i ;
UBYTE ctmp;
/* send 8 bit data */
ctmp &= ~SHF_CLK ;
outp( LCD_CP , ctmp );
for ( i = 0 ; i < 8 ; i++ ) {
ctmp &= ~SHF_DAT ;
if ( dat & 0x80 ) { ctmp |= SHF_DAT ; }
outp( LCD_CP , ctmp );
ctmp |= SHF_CLK ;
outp( LCD_CP , ctmp );
dat <<= 1 ;
ctmp &= ~SHF_CLK ;
outp( LCD_CP , ctmp );
}
/* 0 -> E */
ctmp &= ~LCD_E ;
outp( LCD_CP , ctmp );
/* RS */
ctmp &= ~LCD_RS ;
if ( which ) { ctmp |= LCD_RS ; }
outp( LCD_CP , ctmp );
/* 1 -> E */
ctmp |= LCD_E ;
outp( LCD_CP , ctmp );
/* 0 -> E */
ctmp &= ~LCD_E ;
outp( LCD_CP , ctmp );
}
初期化処理
8ビットデータアクセスの場合は、以下のように初期化する。
- 最短15ms待ち
- RS=L状態で、0x30を転送
- 最短4.1ms待ち
- RS=L状態で、0x30を転送
- 最短100us待ち
- RS=L状態で、0x30を転送
- RS=L状態で、0x20を転送
- RS=L状態で、0x28を転送
- RS=L状態で、0x08を転送
- RS=L状態で、0x01を転送
- 最短2ms待ち
- RS=L状態で、0x06を転送
- 最短2ms待ち
- RS=L状態で、0x0cを転送
- RS=L状態で、0x02を転送
- RS=L状態で、0x80を転送
ms単位での時間待ちをすることができる関数があるとして
次のように、初期化コードを記述する。
void init_lcd(void)
{
/* initialize hardware */
mwait_by(15) ; /* 25ms */
put_lcd_primitive(OFF,0x30);
mwait_by(5) ; /* 5ms */
put_lcd_primitive(OFF,0x30);
mwait_by(1); /* 1ms */
put_lcd_primitive(OFF,0x30);
mwait_by(1); /* 1ms */
put_lcd_primitive(OFF,0x20);
mwait_by(1); /* 1ms */
/* set function */
put_lcd_primitive(OFF,0x28);
put_lcd_primitive(OFF,0x08);
put_lcd_primitive(OFF,0x01);
mwait_by(2); /* 2ms */
put_lcd_primitive(OFF,0x06);
mwait_by(2); /* 2ms */
put_lcd_primitive(OFF,0x0c);
put_lcd_primitive(OFF,0x02);
put_lcd_primitive(OFF,0x80);
}
8ビットのバスインタフェースの場合
初期化関数は、以下となります。
void init_lcd(void)
{
/* initialize hardware */
delay_ms(15) ; /* 15ms */
put_lcd_primitive(OFF,0x30);
delay_ms(5) ; /* 5ms */
put_lcd_primitive(OFF,0x30);
delay_ms(1); /* 1ms */
put_lcd_primitive(OFF,0x30);
delay_ms(1); /* 1ms */
/* set function */
put_lcd_primitive(OFF,0x38);
put_lcd_primitive(OFF,0x08);
put_lcd_primitive(OFF,0x01);
delay_ms(2); /* 2ms */
put_lcd_primitive(OFF,0x0c);
}
文字列表示
行と桁を指定し、文字列を表示するには、次のシーケンスを実行する。
- 桁と行から、LCD内部のメモリアドレスを求める
- メモリアドレスを転送
- 1文字ずつ転送
2行のLCDでは、次のようにアドレスがエントリーを指定されている
0行0桁 → 0x00
1行0桁 → 0x40
4行のLCDでは、次のようにアドレスがエントリーを指定されている
0行0桁 → 0x00
1行0桁 → 0x40
2行0桁 → 0x14
3行0桁 → 0x54
文字列表示の関数を定義すると、次のようになる。
#define MASK80 0x80
void put_lcd_str(UBYTE r,UBYTE c,UBYTE *ptr)
{
UBYTE adr ;
/* check range */
#ifdef LCD_4LINES
if ( r > 3 ) return ;
if ( c > 19 ) return ;
#else
if ( r > 1 ) return ;
if ( c > 15 ) return ;
#endif
/* set address */
switch ( r ) {
case 1 : adr = 0x40 ; break ;
case 2 : adr = 0x14 ; break ;
case 3 : adr = 0x54 ; break ;
default : adr = 0x00 ; break ;
}
adr += c ;
adr |= MASK80 ;
put_lcd_primitive(OFF,adr);
while ( *ptr != '\0' ) {
put_lcd_primitive(ON,*ptr);
ptr++ ;
}
}
目次
前
次