2016年03月04日 | 公開。 |
それではAQM1248Aを、Arduinoをはじめとするマイコンに接続する方法について説明します。
AQM1248Aを動作させるのに必要な周辺回路(図1)を再掲しますのでご覧ください。
この様に、周辺にたくさんのコンデンサ(とプルアップ抵抗)が必要ですが、それらは超小型グラフィックLCD用ピッチ変換基板を使えば、その基板上に実装されています。ここでは、ピッチ変換基板を用いる事を前提に話をします。
ピッチ変換基板の短辺に、端子が7つ出ています。
これらの端子の接続は、次の表の様になっています。
端子番号 | 端子の名称 | 端子の意味 |
---|---|---|
1 | VDD | 電源端子。(2.4~3.6V) |
2 | /CS | SPIバスの/CS(Chip Select)端子。負論理。 |
3 | /RESET | リセット端子。負論理。(図1には/RSTと表記) |
4 | RS | SDI端子に入力される信号がコマンド(RSがL)かデータ(RSがH)かを区別するための信号。 |
5 | SCLK | SPIバスのSCLK(Serial Clock)信号。 |
6 | SDI | SPIバスのMOSI(Master Out Slave In)端子。マイコンから送られてきたコマンドやデータが入力される。 |
7 | GND | グランド端子。(0V) |
表1の内、電源線(VDDとGND)を除く5つの信号線(/CS、/RESET、RS、SCLK、SDI)は全て、LCD側から見て入力端子になっています。すなわち、マイコンがAQM1248Aから情報を読み出す手段がないということです。
AQM1248Aはフレームバッファ(VRAM)を内蔵したグラフィックLCDモジュールで、表示の際に、1フレームごとに表示画像を転送しなくてもいい仕組みにはなっているのですが、残念ながらAQM1248Aに内蔵されたフレームバッファの内容を、マイコン側が読み出せなくなっています。
グラフィック画面に線などを描くには、通常フレームバッファ中のグラフィックデータを読み出し、描画したい線のグラフィックデータとの論理和(OR)を取って、フレームバッファに書き戻す処理を行います。(コラム「グラフィックLCDへの描画の方法」参照) AQM1248の場合はフレームバッファを読めないので、通常のやり方ではこの処理は行えません。
そこで、AQM1248Aに何かグラフィックデータを転送する場合には、マイコンの内蔵RAM内に仮想的なフレームバッファを用意しておき、そのフレームバッファにも転送したのと同じデータを書き込んで、LCD側とマイコン側で2重にグラフィックデータを持っておく必要があります。
AQM1248Aは128X48ピクセルのモノクロLCDモジュールですから、128X48÷8=768バイトのフレームバッファを、マイコン側に用意する必要があります。これは、搭載RAMの少ないマイコンにとっては、結構負担になります。
例えば8ビットのArduino Uno(搭載マイコンはATmega328P)の場合、RAMが2kBしかありませんから、その37.5%をフレームバッファのために使用する必要があります。もしマイコンとしてATmega88やATmega168を使う場合は、内蔵RAMの75%をVRAMに使ってしまう計算になり、複雑な処理はできなくなりそうなのが分かると思います。
一方で32ビットのArduino Dueの場合、RAMが96kBもありますから、VRAMに使う768バイトは、ほとんど気にする必要がありません。
フレームバッファ(VRM)を持ったグラフィックLCDモジュールに、線などのグラフィックデータを書く方法について説明します。ここでは、横10X縦8ピクセルの仮想のモノクログラフィックLCDモジュールを例に挙げて説明します。グラフィックLCDモジュール内部では、フレームバッファの1ビットが1ピクセルに相当し、ビットが1ならピクセルは黒、ビットが0ならピクセルは白になるものと仮定します。
初期状態で図2(a)の様に、なだらかな右肩下がりの直線が描かれていたとし、そこに図2(b)の様な急な右肩上がりの直線を書き加える事を考えます。
もしグラフィックデータを1ピクセルごとにグラフィックLCDモジュールに書き込めるなら、図2(b)の線を、1ピクセルずつグラフィックLCDモジュールに書き込んでいけばよいのですが、残念ながら、グラフィックLCDモジュールは通常、フレームバッファの読み書きを1バイト(8ビット)単位でしか行えません。ここでは、図1の赤い線で囲ったように、縦方向に8ピクセルずつのデータを1度に読み書きするものとします。
この場合、図2(b)のデータを、単純にグラフィックLCDモジュールに書き込んだのでは、図2(b)の直線のみがLCDに表示され、元々あった図2(a)の 直線は消えてしまいます。
そこで、一旦グラフィックLCDモジュール内のフレームバッファ(図2(a))を読み出し、描きたい画像のグラフィックデータ(図2(b))との論理和(OR)を取って、その結果(図2(c))をグラフィックLCDモジュールに書き戻すという方法を取ります。
ところで、SPI接続のグラフィックLCDモジュールの場合、たいていは内蔵されているフレームバッファが読み出せなくなっています。(パラレル接続やI2C接続のグラフィックLCDモジュールは、通常フレームバッファが読み出せる) その場合、マイコン内蔵メモリ内にもフレームバッファ(のコピー)を設けて、それを読む必要があります。
通常、電源投入時のグラフィックLCDモジュールのフレームバッファの内容は不定ですが、LCDの初期化ルーチンにおいて、グラフィックLCDモジュール内のフレームバッファと、マイコン内のフレームバッファを、両方とも消去(0で埋める)すると、両方のフレームバッファは同じ内容になります。それ以降は、グラフィックLCDモジュールに何かを書き込むたびに、マイコン内のフレームバッファにも同じ内容を書き込めば、2つのフレームバッファの内容は、常に同じに維持されます。よって、グラフィックLCDモジュールのフレームバッファを読む必要がなくなります。
3番端子の/RESET信号は、Lにすると、AQM1248Aをハードウェア的にリセットします。(リセットコマンドをSPIバス経由で送って、ソフトウェア的にリセットする方法もある) ただ、AQM1248Aにはパワーオンリセット回路(電源投入時に自発的にリセットを掛ける回路)が内蔵されていますので、通常は/RESET信号を用いてリセットを掛ける必要はありません。
ピッチ変換基板には、/RESET信号にプルアップ抵抗(R2)が入っていますから、3番端子はオープンにしておけば、問題ありません。
2番端子の/CS、5番端子のSCLK、6番端子のSDIの3つが、SPIバスの信号となります。先ほど述べたように、AQM1248Aからマイコンに情報を送り返す信号(SDOまたはMISO)がありません。
/CSの信号がHなら、SCLKやSDIの信号は無視されますが、/CSの信号がLなら、SDIから送られて来たデータを、SCLKの立ち上がりエッジに同期して取り込みます。情報の読み取りは8ビット単位で行われます
タイミングチャートは図3の様になり、SPIのモード3で動作することになります。
4番端子のRS信号は、SDI信号で送られてきた信号がコマンド(RSがL)かデータ(RSがH)かを区別するための信号で、8番目のクロックの立ち上がりで取り込まれます。図3は1バイトのデータまたはコマンドを送った場合のタイミングチャートですが、/CS信号がLになってから、続けて2バイト以上のデータまたはコマンドを送った場合でも、/CS信号がLになってから、8番目のクロックの立ち上がりだけでRS信号が取り込まれます。
バスサイクル時間(1クロックの周期)は50ns以上なので、最高で20MHzのクロックでSPIバスが動作します。その他にもパルス幅やセットアップ時間、ホールド時間などの色々なタイミング制約がありますが、詳しいことはAQM1248Aに内蔵されている液晶制御ICである、ST7565Rのデータシートを参照してください。(秋月電子のAQM1248の購入ページからダウンロードできます)
次のページでは、ハードウェアSPIとソフトウェアSPIの違い、および3.3VのArduinoとAQM1248Aとの接続法について説明します。
商品名 | 122X32モノクログラフィックLCDシールド | |
税抜き小売価格 | 3333円 | |
販売店 | スイッチサイエンス | |
サポートページ | 122X32モノクログラフィックLCDシールドサポートページ |
商品名 | GLCD学習シールドキット | |
税抜き小売価格 | 1410円 | |
販売店 | スイッチサイエンス | |
サポートページ | GLCD学習シールドキットサポートページ |