ArduinoでグラフィックLCDを動かす(SG12232C編)(1)

このページをスマホなどでご覧になる場合は、画面を横長にする方が読みやすくなります。
目次へ  前のページへ (1) (2) (3) (4) (5) 次のページへ
Arduino用のSG12232Cのシールド
Arduino用のSG12232Cのシールド

目次

1. はじめに … 1ページ
2. ハードウェアについて … 1ページ
3. LCD制御コマンドについて … 1ページ
4. 画面表示のサンプルスケッチ … 2ページ
5. モノクログラフィックLCD制御用ライブラリMGLCD … 3ページ
6. MGLCDライブラリのインストール・アンインストール … 3ページ
7. MGLCDライブラリでHello World … 3ページ
8. MGLCDライブラリのデモ用スケッチ … 3ページ
9. 描画速度のテスト … 3ページ
10. MGLCDライブラリの主な関数(テキスト表示編) … 4ページ
10-1. 内蔵フォント … 4ページ
10-2. print関数およびprintln関数 … 4ページ
10-3. ClearScreen関数 … 4ページ
10-4. Locate関数 … 4ページ
11. MGLCDライブラリの主な関数(グラフィック表示編) … 5ページ
11-1. グラフィック座標系 … 5ページ
11-2. SetPixel関数 … 5ページ
11-3. Line関数 … 5ページ
11-4. Rect関数 … 5ページ
11-5. FillRect関数 … 5ページ
11-6. Circle関数 … 5ページ
11-7. FillCircle関数 … 5ページ
11-8. Line関数を用いたデモスケッチ … 5ページ

1.はじめに

秋月電子SG12232CというグラフィックLCDモジュールArduino Unoで動かしてみました。

比較的簡単な制御でドットマトリックスの2階調グラフィック表示ができます。価格(1,000円)のわりに表示できる情報量が多く、形状も小型です。英数かなフォントをArduinoに実装して、キャラクタLCDモジュールとして使っても、同程度の文字数が表示できるキャラクタLCDモジュールより割安だという利点もあります。

ただし、配線が多いのでArduinoの空きピンが少なくなるのが難点です。

以前は次の様なシールド基板を作って、このページで紹介していました。

写真1、以前作ったシールド(Arduinoに装着、LCD付き、表面)
↑ 画像をクリックすると拡大
写真1、以前作ったシールド(Arduinoに装着、LCD付き、表面)
写真2、以前作ったシールド(Arduinoに装着、LCD付き側面)
↑ 画像をクリックすると拡大
写真2、以前作ったシールド(Arduinoに装着、LCD付き側面)
写真3、以前作ったシールド(Arduinoに装着、裏面)
↑ 画像をクリックすると拡大
写真3、以前作ったシールド(Arduinoに装着、裏面)
写真4、以前作ったシールド(LCD外す、表面)
↑ 画像をクリックすると拡大
写真4、以前作ったシールド(LCD外す、表面)
写真5、以前作ったシールド(LCD外す、裏面)
↑ 画像をクリックすると拡大
写真5、以前作ったシールド(LCD外す、裏面)

しかし、基板の見た目が良くないことと、動作に必要のないコネクタが付いていて、動作が理解しにくいことから、今回、新たに次の様なシールド基板を作り直しました。

写真6、今回作ったシールド(Arduinoに装着、LCD付き、表面)
↑ 画像をクリックすると拡大
写真6、今回作ったシールド(Arduinoに装着、LCD付き、表面)
写真7、今回作ったシールド(Arduinoに装着、LCD付き、側面)
↑ 画像をクリックすると拡大
写真7、今回作ったシールド(Arduinoに装着、LCD付き、側面)
写真8、今回作ったシールド(Arduinoに装着、裏面)
↑ 画像をクリックすると拡大
写真8、今回作ったシールド(Arduinoに装着、裏面)
写真9、今回作ったシールド(LCD外す、表面)
↑ 画像をクリックすると拡大
写真9、今回作ったシールド(LCD外す、表面)
写真10、今回作ったシールド(LCD外す、裏面)
↑ 画像をクリックすると拡大
写真10、今回作ったシールド(LCD外す、裏面)

この新しいシールドを使って、今回(2013年9月)、記事を書き直しました。また、LCDを制御するMGLCDライブラリもVer. 0.34Aにバージョンが上がっているので、ソフトの解説もVer 0.34Aのライブラリに準じて行っています。以前の記事ではソフトがArduino Unoにしか対応していませんでしたが、今回はArduino Uno/Mega 2560/Leonardo/Pro 328 5V 16MHzに対応しています

2.ハードウェアについて

SG12232Cは、5V単一電源で動作する122×32ピクセルの2階調グラフィックLCDモジュールです。8ビットバスでホストマイコンと通信します。

コネクタには20ピンの端子がありますが、次の表のような働きをします。

表1、SG12232Cの端子説明
番号 名称 説明
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を制御しています。

図1、Z80系インターフェースのタイミングチャート
図1、Z80系インターフェースのタイミングチャート
図2、68系インターフェースのタイミングチャート
図2、68系インターフェースのタイミングチャート

RES(18番ピン)は、LCDコントローラICのリセット信号と、68系インターフェース/Z80系インターフェースの選択信号を兼ねています。LHの遷移で、リセットがかかると同時に、68系インターフェースになります。HLの遷移で、リセットがかかると同時に、Z80系インターフェースになります。

他のサイトでは、RESをHに固定して、68系インタフェースとして利用している例が見受けられます。しかし電源と同時にRESを立ち上げると、リセットがかかる保証がありませんので、電源が立ち上がった後にRESを立ち上げるようにすべきです。今回は、RES信号をArduinoのRESETピンからもらっています。RES信号をArduinoのIOピンで制御すればより確実ですが、空きピンが1つ減るので、今回はその方法を採用しませんでした。

DB0~7のバスは、ビットマップデータの送受信、制御コマンドの送信、ステータスの受信のために使われます。

A0(4番ピン)は、データバス上の信号の種類を決める信号です。A0がLの場合、ライト時にはバス上のデータは制御コマンドの種類を表します。リード時にはバス上のデータはLCDコントローラのステータスを表します。A0がHの場合、バス上のデータはビットマップデータを表します。

図3、今回作ったシールドの回路図
↑ 画像をクリックするとPDFファイルで表示
図3、今回作ったシールドの回路図

上の回路図のように、LCDモジュールとArduinoを接続しました。

ArduinoのアナログI/Oピンが1本、デジタルI/Oピンが6本(シリアル接続時にのみ使用するRXTXを含む)残っている状態です。

また、C3の47μFのコンデンサは、LCDをArduinoの至近距離に置くのが確実な場合(今回のようにシールドとして組んだ場合など)は必ずしも必要ありません。

VR1は、LCDのコントラスト調整用の半固定抵抗です。LCDに何も映らないと思っていたら、コントラストが下がっていただけというケースがありますので、表示が見やすいようにコントラストを調整する事を忘れないでください。

今回は液晶のバックライトを光らせていないので、19番ピンと20番ピンは使用していません。

広告

3.LCD制御コマンドについて

SG12232Cは、640バイトのVRAMを持っています。画面に何かを表示するには、このVRAMにデータを書き込むことになります。VRAMの構造は図4のようになります。

図4、VRAMの構造
図4、VRAMの構造

先ほど説明したように、画面の左半分(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に送るコマンドの種類を以下にに説明します。

表示OFF
A0をLにし、DB0~DB7に0xAEを送信すると、LEDの表示がOFFになります。
表示ON
A0をLにし、DB0~DB7に0xAFを送信すると、LEDの表示がOFFになります。
表示開始ラインの設定
A0をLにし、DB0~DB7に0xC0+lineを送信すると、表示開始ラインを設定できます。ここでlineは0~31の数です。line=0の場合は、図3の通り、LCDに表示される一番上のラインがページ0のLSBとなりますが、lineを0以外に設定することにより、表示開始ラインを1ドット単位で設定できます。画面のスムーズスクロールなどに利用できます。逆に言えば、スムーズスクロールなどを行わないならば、このコマンドを利用する必要はありません。
ページアドレスセット
A0をLにし、DB0~DB7に0xB8+pageを送信すると、ページアドレスをセットできます。ここでpageは0~3の数です。このコマンドを発行して以降、VRAMに書き込み/読み込みを行うと、pageで指定したページの書き込み/読み込みとなります。
カラムアドレスセット
A0をLにし、DB0~DB7に0x00+colを送信すると、カラムアドレスをセットできます。colは0~79の数です。このコマンドを発行した直後にVRAMに書き込み/読み込みを行うと、colで指定したカラムアドレスの書き込み/読み込みになります。
ステータスリード
A0をLにし、読み込み動作を行うと、DB4~DB7にLCD制御ICのステータスが返ります。DB0~DB3は0になります。ステータスの各ビットは次の通りです。
VRAMへの書き込み
A0をHにし、DB0~DB7にデータを書き込むと、VRAMへの書き込みになります。書き込み後はカラムアドレスが自動的にインクリメントされますので、連続したカラムアドレスへ複数バイトのデータを書き込む際は、毎回カラムアドレスをセットする必要はありません。
VRAMからの読み出し
A0をHにし、読み込み動作を行うと、DB0~DB7にVRAMのデータが読み出せます。読み込み後はカラムデータが自動的にインクリメントされますので、連続したカラムアドレスから複数バイトのデータを読み込む際は、毎回カラムアドレスをセットする必要はありません。なお、カラムアドレスをセットした直後は、ダミーのリードを1回行う必要があります
左右非反転表示
A0をLにし、DB0~DB7に0xA0を送信すると、カラムアドレス0が左端に対応する、左右非反転表示を行います。このコマンドを使う必要はほぼないと考えられます。
左右反転表示
A0をLにし、DB0~DB7に0xA1を送信すると、カラムアドレス79が左端に対応する、左右反転表示を行います。このコマンドを使う必要はほぼないと考えられます。
スタティックドライブOFF
A0をLにし、DB0~DB7に0xA4を送信すると、スタティックドライブ(全点灯強制)をOFFします。
スタティックドライブON
A0をLにし、DB0~DB7に0xA5を送信すると、スタティックドライブ(強制的に全ピクセル点灯)を行います。
デューティセレクト
A0をLにし、DB0~DB7に0xA8を送信すると、液晶駆動のデューティが1/16になります。またA0をLにし、DB0~DB7に0xA9を送信すると、液晶駆動のデューティが1/16になります。SG12232Cの場合はデューティを必ず1/32に設定する必要があり、リセット時には1/32に設定されているので、このコマンドを使う理由は全くありません。
リードモディファイライト
A0をLにし、DB0~DB7に0xE0を送信すると、エンドコマンドが発行されるまで、リードモディファイライト動作になります。使用頻度の低いコマンドなので、動作の詳細は省略します。
エンド
A0をLにし、DB0~DB7に0xEEを送信すると、リードモディファイ動作を終了します。使用頻度の低いコマンドなので、動作の詳細は省略します。
リセット
A0をLにし、DB0~DB7に0xE2を送信すると、表示開始ラインレジスタとページアドレスレジスタを初期化します。

次のページでは、簡単なテストスケッチを作って、LCDに文字を表示してみます。

目次へ  前のページへ (1) (2) (3) (4) (5) 次のページへ

このページで使われている用語の解説

関連ページ

Arduino 電子工作
このサイトの記事が本になりました。
書名:Arduino 電子工作
ISBN:978-4-7775-1941-5
工学社の書籍の内容の紹介ページ
本のカバーの写真か書名をクリックすると、Amazonの書籍購入ページに移動します。