秋月電子のSG12232CというグラフィックLCDモジュールをArduino Unoで動かしてみました。
比較的簡単な制御でドットマトリックスの2階調グラフィック表示ができます。価格(1,000円)のわりに表示できる情報量が多く、形状も小型です。英数かなフォントをArduinoに実装して、キャラクタLCDモジュールとして使っても、同程度の文字数が表示できるキャラクタLCDモジュールより割安だという利点もあります。
ただし、配線が多いのでArduinoの空きピンが少なくなるのが難点です。
以前は次の様なシールド基板を作って、このページで紹介していました。
しかし、基板の見た目が良くないことと、動作に必要のないコネクタが付いていて、動作が理解しにくいことから、今回、新たに次の様なシールド基板を作り直しました。
この新しいシールドを使って、今回(2013年9月)、記事を書き直しました。また、LCDを制御するMGLCDライブラリもVer. 0.34Aにバージョンが上がっているので、ソフトの解説もVer 0.34Aのライブラリに準じて行っています。以前の記事ではソフトがArduino Unoにしか対応していませんでしたが、今回はArduino Uno/Mega 2560/Leonardo/Pro 328 5V 16MHzに対応しています。
SG12232Cは、5V単一電源で動作する122×32ピクセルの2階調グラフィックLCDモジュールです。8ビットバスでホストマイコンと通信します。
コネクタには20ピンの端子がありますが、次の表のような働きをします。
番号 | 名称 | 説明 |
---|---|---|
1 | VSS | GND |
2 | VDD | 5V電源入力 |
3 | Vo | コントラスト調整用入力端子。電圧が低いほど文字が濃く表示される。 |
4 | A0 | 0 : CPUからのDB0~7が制御コマンドである事を示す。 1 : CPUからのDB0~7がデータである事を示す。 |
5 | CS1 | アクティブロー。左半分用チップセレクト信号。 |
6 | CS2 | アクティブロー。右半分用チップセレクト信号。 |
7 | CL | 液晶駆動クロック入力 (2kHz) |
8 | E | 68系インターフェースの場合、H→Lの遷移でDB0~7がリードまたはライトされる。 |
RD | Z80系インターフェースの場合、Lの期間、LCDのDB0~7が出力状態になる。 | |
9 | R/W | 68系インターフェースの場合、この信号がHならリード。Lならライト。 |
WR | Z80系インターフェースの場合、L→Hの遷移でLCDにDB0~7が書き込まれる。 | |
10~17 | DB0~7 | データバス。(制御コマンドもこのバスで送る) |
18 | RES | リセット信号。LからHに切り替えると、68系インターフェースになる。HからLに切り替えるとZ80系インターフェースになる。 |
19 | A | バックライトLEDのアノード。 |
20 | K | バックライトLEDのカソード。 |
このLCDモジュールで注意が必要なのは、CL(7番ピン)に2kHzのクロックを入力する必要があることです。周波数の精度はあまり必要がない様で、1~3kHzの範囲でOKみたいです。このクロックはデータバスとは非同期です。このクロックををArduinoで生成すると、余計にピンを1つ消費するので、今回はタイマICのLCM555で成しました。また、LCDに5V電源が供給されている時は、常に2kHzのクロックを与えておかないと、LCDパネルを傷める原因となります。Arduinoのタイマーでも2kHzを生成できますが、Arduinoの初期化時や暴走時にクロックの生成が止まるという観点でも好ましくありません。
このLCDモジュールは、画面の左半分と右半分を別々のLCDコントローラICで制御しているのが特徴です。そのため、チップセレクト信号が2つあります。(CS1とCS2) LCDコントローラICの初期化も、左右それぞれに行う必要があるのですが、CS1とCS2を同時にLにして、初期化コマンドを送ると、2個のコントローラに同時に初期化がかかります。
データバスの制御は、Z80系CPUに合わせたインターフェース(図1)と、68系CPUに合わせたインターフェース(図2)が選択できます。ライトアクセスとリードアクセスの制御は、Z80系インターフェースの場合、RD(8番ピン)とWR(9番ピン)で行います。68系インターフェースの場合、E(8番ピン)とR/W(9番ピン)で行います。今回は、68系インターフェースでLCDを制御しています。
RES(18番ピン)は、LCDコントローラICのリセット信号と、68系インターフェース/Z80系インターフェースの選択信号を兼ねています。L→Hの遷移で、リセットがかかると同時に、68系インターフェースになります。H→Lの遷移で、リセットがかかると同時に、Z80系インターフェースになります。
他のサイトでは、RESをHに固定して、68系インタフェースとして利用している例が見受けられます。しかし電源と同時にRESを立ち上げると、リセットがかかる保証がありませんので、電源が立ち上がった後にRESを立ち上げるようにすべきです。今回は、RES信号をArduinoのRESETピンからもらっています。RES信号をArduinoのIOピンで制御すればより確実ですが、空きピンが1つ減るので、今回はその方法を採用しませんでした。
DB0~7のバスは、ビットマップデータの送受信、制御コマンドの送信、ステータスの受信のために使われます。
A0(4番ピン)は、データバス上の信号の種類を決める信号です。A0がLの場合、ライト時にはバス上のデータは制御コマンドの種類を表します。リード時にはバス上のデータはLCDコントローラのステータスを表します。A0がHの場合、バス上のデータはビットマップデータを表します。
上の回路図のように、LCDモジュールとArduinoを接続しました。
ArduinoのアナログI/Oピンが1本、デジタルI/Oピンが6本(シリアル接続時にのみ使用するRXとTXを含む)残っている状態です。
また、C3の47μFのコンデンサは、LCDをArduinoの至近距離に置くのが確実な場合(今回のようにシールドとして組んだ場合など)は必ずしも必要ありません。
VR1は、LCDのコントラスト調整用の半固定抵抗です。LCDに何も映らないと思っていたら、コントラストが下がっていただけというケースがありますので、表示が見やすいようにコントラストを調整する事を忘れないでください。
今回は液晶のバックライトを光らせていないので、19番ピンと20番ピンは使用していません。
SG12232Cは、640バイトのVRAMを持っています。画面に何かを表示するには、このVRAMにデータを書き込むことになります。VRAMの構造は図4のようになります。
先ほど説明したように、画面の左半分(CS1空間)を制御するICと右半分(CS2空間)を制御するICが独立しており、それぞれにVRAMを持っています。
VRAMは1バイトごとに0~3のページアドレスと、0~79のカラムアドレスが付いています。1バイトの情報は、縦方向の8ドット分の表示内容を保持しています。LSBが一番上のドットを、MSBが一番下のドットを表します。1になっているビットが黒を、0になっているビットが白を表します。ページアドレスは画面の縦方向の位置を表すアドレスです。カラムアドレスアドレスは横方向の位置を表すアドレスです。
カラムアドレスの最大値は79ですが、LCDに表示されるのは、0~60の範囲です。61~79の範囲のVRAMに書き込んでも、画面表示に反映されません。(無効領域)
LCDに送るコマンドの種類を以下にに説明します。
次のページでは、簡単なテストスケッチを作って、LCDに文字を表示してみます。