V850付録基板に
すんさんがレポートされている
サイキットで売っている液晶をつないでみました。
サイキットにはほとんど資料はないのですが、すんさんが解明されています。
サイキットでは3種類のグラフィックLCDを販売しています。小型のがELバックライトで2mmピッチです。同じ大きさで色違いの残り2つはバックライトがLEDで2.54mmピッチです。
すんさんのレポートでは青色の液晶を使われているので、緑色の液晶を使ってみました。
このLCDのバックライトはやたらと電流が流れます。測ってみたら250mAくらい流れています(5V)。一応電流制限用のチップ抵抗R10がついているのですが、2R2と書いてあるので2.2Ωです。すんさんが使われた青色の方は330と書いてあるので33Ωみたいです。外に電流制限用に100Ωの半固定抵抗を増設してみましたが、少なくとも150mAは流さないとLEDは点灯しないようでした。バックライトなしでも、そこそこ見えるので点けない方が幸せかもしれません。
V850付録基板の5V(CON2 38pin)はUSBの電源に直結しているっぽいので、他に何も接続しないACアダプタ付のUSBハブを使って、CON2 38pinからバックライトLEDの電源をとっています。
あいかわらず複数の画像を貼る方法が分かっていないので、別記事にバックライトありとなしの画像をアップロードします。
LCDコントローラはKS0108B(HD61202の互換品)が2個です。
別の液晶ですが、同じコントローラなので制御法については
Chanさんの
S9894 128×48液晶表示器の試食も参考になります。
LCDの制御はデータが8pinと制御が6pinの14pinを使います。すんさんと同じP9に接続しています。最初はR/Wを0に固定(GNDに接続)して、適当にwaitをいれれば動くかなと思いましたが、それではうまくいきませんでした。微妙にタイミングがずれたり、コマンドが送れていなかったりしました。まじめにbusyをチェックしないといけないようです。
#define CTRL P9H
#define DATA P9L
#define RST P9H.5 // 0 reset
#define RW P9H.4 // 1 read 0 write
#define CS2 P9H.3 // 1 select
#define CS1 P9H.2 // 1 select
#define E P9H.1 // 立ち下がりでデータ取り込み
#define RS P9H.0 // 1 data 0 command
#define BUSY P9L.7 // read時busy
#define left() {CS2 = 0; CS1 = 1;}
#define right() {CS1 = 0; CS2 = 1;}
// ビジー待ち
void busywait(void)
{
PM9L = 0xff; // read mode
RS = 0; // command
RW = 1; // read
do {
E = 1;
E = 0;
} while(BUSY) ;
PM9 = 0x00; // write mode
RW = 0; // write
}
// コマンドを送る
void lcd_cmd(unsigned char c)
{
busywait();
RS = 0; // command
DATA = c;
E = 1;
E = 0;
}
// データを送る
void lcd_data(unsigned char c)
{
busywait();
RS = 1; // data
DATA = c;
E = 1;
E = 0;
}
// 座標移動
void lcd_move(unsigned char x, unsigned char y)
{
lcd_cmd(0x40 | (x & 0x3f)); // 横
lcd_cmd(0xb8 | (y & 7)); // 縦
}
// LCDクリア
void lcd_clear(void)
{
unsigned char x, y;
for(y = 0; y < 8; y++){
lcd_move(0, y);
for(x = 0; x < 64; x++) lcd_data(0x00);
}
}
// LCD初期化
void lcd_init(void)
{
CTRL = 0x20; // RST=1, RW=0, CS2=0, CS1=0, E=0, RS=0
RST = 0;
RST = 1;
left();
lcd_cmd(0xc0); // start line
lcd_clear();
lcd_cmd(0x3e | 1); // display on
right();
lcd_cmd(0xc0); // start line
lcd_clear();
lcd_cmd(0x3e | 1); // display on
}
void main(void)
{
int x, y, p;
lcd_init();
// 128x64画像の表示
p = 0;
for(y = 0; y < 8; y++){
left();
lcd_move(0, y);
for(x = 0; x < 64; x++) lcd_data(pic[p++]);
right();
lcd_move(0, y);
for(x = 0; x < 64; x++) lcd_data(pic[p++]);
}
while(1) ;
}