ArduinoでaitendoのTFT液晶(M-Z18SPI-2PB)を制御するライブラリを作成するための調査(6)

投稿者: | ↻ : 2019年2月5日

はじめに

ArduinoでaitendoのTFT液晶(M-Z18SPI-2PB,Z180SN009)を制御するライブラリを作成するための調査(5)」の続きで、初期化のために送信しているコマンドの内容を調べて行きます。

Adafruit_ST7735クラス

初期化に必要なコマンドとパラメータ

commandListで送信しているコマンドの配列から、制御チップの初期化に必要なコマンドとパラメータを調べます。定義されているコマンドの配列は7つあります。最初に呼び出す初期化処理(initBinitR)から調査対象を絞ります。

Adafruit_ST7735.cppからの抜粋

// Initialization for ST7735B screens
void Adafruit_ST7735::initB(void) {
  commonInit(Bcmd);
  setRotation(0);
}

// Initialization for ST7735R screens (green or red tabs)
void Adafruit_ST7735::initR(uint8_t options) {
  commonInit(Rcmd1);
  if(options == INITR_GREENTAB) {
    commandList(Rcmd2green);					
    colstart = 2;
    rowstart = 1;
  } else if(options == INITR_144GREENTAB) {
    _height = ST7735_TFTHEIGHT_128;
    _width = ST7735_TFTWIDTH_128;
    commandList(Rcmd2green144);
    colstart = 2;
    rowstart = 3;
  } else if(options == INITR_MINI160x80) {
    _height = ST7735_TFTHEIGHT_160;
    _width = ST7735_TFTWIDTH_80;
    commandList(Rcmd2green160x80);
    colstart = 24;
    rowstart = 0;
  } else {
    // colstart, rowstart left at default '0' values
    commandList(Rcmd2red);
  }
  commandList(Rcmd3);

  // if black, change MADCTL color filter
  if ((options == INITR_BLACKTAB) || (options == INITR_MINI160x80)) {
    writecommand(ST7735_MADCTL);
    writedata(0xC0);
  }

  tabcolor = options;
  setRotation(0);
}

まず、BcmdinitBでしか使用していないので調査対象から外します。

ST7735Sを利用する場合はoptionINITR_BLACKTABを渡してinitRを呼び出すので、INITR_BLACKTABの時に利用されないRcmd2greenRcmd2green144Rcmd2green160x80も調査対象から外します。

残ったRcmd1Rcmd2redRcmd3を調査対象にします。

Rcmd1

コマンド数:15

#コマンド
(16進数)
パラメータ数パラメータ
(16進数)
説明
1SWREST(01)なしソフトウェアリセット
2SLPOUT(11)なしスリープからの復帰
3FRMCTR1(B1)31,2C,2Dフレームレートの設定
4FRMCTR2(B2)31,2C,2D
5FRMCTR3(B3)61,2C,2D
1,2C,2D
6INVCTR(B4)17フレーム反転方式の設定
7PWCTR1(C0)3A2,2,84液晶駆動出力電圧の設定
8PWCTR2(C1)1C5
9PWCTR3(C2)2A,0液晶駆動出力電流の設定
10PWCTR4(C3)28A,2A
11PWCTR5(C4)28A,EE
12VMCTR1(C5)1Eコモン電圧の設定
13INVOFF(20)なし反転表示設定(OFF)
14MADCTL(36)1C8読み書き、色順、走査方向の設定
※ この設定値は未使用に等しい
15COLMOD(3A)15色深度の設定
SWREST

最初にSWRESTによりソフトウェア・リセットを行なっています。しかし、ハードウェア・リセットを行なった後なので、あまり意味はありません。

SLPOUT

起動(およびリセット)後はスリープモードなので、SLPOUTによりスリープモードから抜ける必要があります。コマンドは特定のモードでないと有効にならない場合があるので、モードを意識する必要があります。

FRMCTR[1,2,3]

液晶パネルのリフレッシュレートと、画像の更新タイミングが合っていない場合、画像がズレて見えるティアリング(Tearing Effect)が発生します。フレームレートとはフレーム(≒1画面)の1秒間の更新頻度のことで、フレーム周波数(frame frequency)とも呼ばれ、単位はヘルツ(Hz)で表される。60Hzなら1秒間に60フレームとなります。

このフレームレートをDisplay Modeごとに設定する必要があります。起動(およびリセット)後はDisplay Modenormal modeなので、idle modepertial modeについては後の課題として深追いしません。

#Display ModeColor Format対応するコマンド
1normal modefull colorFRMCTR1
2idle mode8-colorsFRMCTR2
3Partial modefull colorFRMCTR3

データシートを見るとGM0,GM1(Panel Resolution Selection Pins)ピンによりデフォルト値が異なるようです。GM[0,1]ピンは液晶の解像度を決めるピンで、液晶モジュールになった時点で決まっています。aitendoの液晶モジュール[Z180SN009]は128×160の解像度なのでGM[0,1]は”11″になっています。

デフォルト値は05h/3Ch/3Ch、Adafruitのライブラリで設定している値は1h/2Ch/2Dhです。式を見ると全て分母を増加させる要素なので、デフォルト値より小さくして、フレームレートを上げていることになります。

ただし、ArduinoでST7735Sを制御する場合の最適値かは分かりません。調整が必要かも要調査です

INVCTR

液晶パネルの駆動方式を設定しています。駆動方式は複数あり、ST7735Sでは2つに対応しています。

フレーム反転方式

液晶表示では直流駆動すると寿命が短くなるため、交流電圧を加えることで駆動する交流電圧駆動が行われている。この交流の印加方式にいくつか種類があるが、いずれもフレームごとに反転させる。

列ライン反転駆動方式
列ライン反転駆動方式、又はVライン反転駆動方式は、フレームごとに列方向のサブ画素を互い違いに正極と負極を反転させる方式である。
ドット反転駆動方式
ドット反転駆動方式は、フレームごとに1つおきのサブ画素を互い違いに正極と負極を反転させる方式である。

(wikipedia – 液晶ディスプレイ – 液晶パネルの駆動技術より)

ライブラリでの設定値はデフォルト値と同じ07hなので列ライン反転駆動方式になります。

PWCTR[1,2]

液晶駆動に必要な電源回路が内蔵されているため、少ない部品で表示システムを構成することができる。

(ST7735Sのデータシートの「1 GENERAL DESCRIPTION」から)

この電源回路の設定を行うコマンドです。

TFT液晶パネルに必要な電圧(信号)は?

ソース電圧、ゲート電圧、コモン電圧の3種類の電圧(信号)が必要になります。

液晶パネルには複数の駆動方式があり、それぞれの構造的理由により必要な電圧が異なります。

aitendoの液晶モジュール[Z180SN009]はTFT型の液晶パネルなので、アクティブ・マトリクス駆動方式です。アクティブ・マトリクス駆動方式は、格子状に配線された電極の交差する部分にTFTを配置し、TFTをスイッチとして画素単位で液晶素子に電圧をかけます。

液晶素子は両極に電圧をかけられると分子の並びが変わり、シャッターのように透過、不透過の状態に変化します。かける電圧の大きさにより透過度が変わるため、電圧を調整して明暗(階調)を作りだします。

液晶素子は正負どちらの方向で電圧をかけてもよく、一方方向の電圧だけで使用すると電荷が偏り寿命が短くなるので、正負を切り替えて電圧をかけます。

接続を図にすると以下のようになります。

1ピクセルの赤、緑、青に対して1つの素子が対応しています。

どの画素を制御するかはソース電圧(列)とゲート電圧(行)により決まります。

ソース電圧にかける電圧の大きさを調整して各色(赤、緑、青)の階調を制御します。調整した電圧をそのまま使用するでなく、ガンマ補正後の電圧を利用します。

PWCTR1では、AVDD(アナログ回路用の電源)、GVDD/GVCL(ガンマ補正回路で参照する電圧)を設定しています。PWCTR2では、VGH / VGL(ゲート電圧)を設定しています。

PWCTR[3,4,5]

Display Mode別に液晶パネルを駆動させるための出力電流の増幅量を設定します。

VMCTR1

この液晶は列ライン反転駆動かドット反転駆動で動作するので、共通電極の電位の掛け方が「コモンDC方式」になります。

共通電極の電位差

フレーム反転方式での液晶駆動では、カラーフィルタ基板側の透明電極である共通電極(コモン電極、対向電極)の電位の掛け方の違いで2方式に分けられる。

コモンDC方式
コモンDC方式では共通電極の電圧は一定で、液晶への電圧印加はアレイ基板側のサブ画素の個別の電極だけで行われる。フレーム反転の度に正電位と負電位を反転させるには、共通電極の電圧が一定のままであるために、例えば+5Vから-5Vまでの10Vの振幅が駆動回路に求められる。

(wikipedia – 液晶ディスプレイ – 共通電極の電位差より)

設定値されている値は0Ehで-0.775Vとなります。初期値は05hで-0.55Vです。影響の度合いが掴めません。

ここもハードウェアの知識が足りなくて、はっきりと何に必要な値か理解できてないので後の課題ノωT)

INVOFF

反転表示をOFFに設定にします。

MADCTL

フレームメモリーの読み込み/書き込みの方向、色の並び(RGBかBGR)、液晶パネルへ表示する際の走査方向を設定します。前回の「ArduinoでaitendoのTFT液晶(M-Z18SPI-2PB)を制御するライブラリを作成するための調査(5)」で調べたsetRotationの中で送信していたコマンドです。

初期化の最後でsetRotationにより必ず上書きされます。設定されている値はC8hで「読み書き180°反転、色の並びはBGR、走査方向は上から下、左から右」となります。しかし、直後にsetRotationの中で「読み書き180°、色の並びはRGB、走査方向は上から下、左から右」と色の並びだけ異なる設定で上書きしています。

なので、この配列にあるMADCTLの設定値は無視されます。

COLMOD

色深度(1ピクセルあたりのビット数)を設定します。

4つ設定があり、各設定の詳細(ビット数、色数、ビットの割当て)は以下のようになります。原色は赤緑青の3色です。

  • 12ビットカラー (4,096色)、1原色あたり4ビット(16階調)
  • 16ビットカラー (65,536色)、RedとBlueに5ビット(32階調)、Greenに6ビット(64階調)
  • 18ビットカラー (262,144色)、1原色あたり6ビット(64階調)

起動(およびハードウェア・リセット)後のデフォルト値は110、18ビットカラーです。

ST7735Sのデータシートを見ると説明の無いビットに値を設定するように書かれています。

The Command 3Ah should be set at 55h when writing 16-bit/pixel data into frame memory, but 3Ah should be re-set to 66h when reading pixel data from frame memory.

コマンド3Ahは、16ビット/ピクセルデータをフレームメモリに書き込む場合は55hに設定する必要がありますが、フレームメモリからピクセルデータを読み取る場合は、3Ahを66hに再設定する必要があります。

(google翻訳)

さらにIFPF[0,1,2]しか無いのにデフォルト値が4ビットの0110になってます。ST7735Sの誤植かと思ったけど、ST7735、ST7735Rも同じままだった。

設定値は05hなので、16ビットカラーの設定になります。aitendoの液晶モジュール[Z180SN009]は18ビット対応なので色数が少ない状態になります。ただし、2バイトのデータを送信するので制御が楽になります。18ビットカラーの場合はビットが連続せず1原色毎に、6ビット+2ビットのダミーを送信するので3バイトになります。

16ビットカラーでは、1ピクセルが2バイトぴったりに納まるので、データを送信する制御が楽になります。18ビットカラーの場合はビットが連続せず1原色毎に、6ビット+2ビットのダミーを送信するので3バイトになります。12ビットカラーの場合は、2バイト目に次のピクセルのデータが重なるので、制御が複雑になります。

ST7735Sのデータシートの「9.8.22 Write Data for 18-bit/Pixel」に送信する信号の図が載っています。

Rcmd2red

コマンド数:2

#コマンド
(16進数)
パラメータ数パラメータ
(16進数)
説明
1CASET40,0,0,7Fフレームメモリーの
列の開始と終了
2RASET40,0,0,9Fフレームメモリーの
行の開始と終了
CASET、RASET

一見、フレームメモリーのサイズを設定しているようですが、このコマンドは書き込みを行う場合の領域(矩形)を設定します。パラメータの先頭2バイトが開始位置、後半2バイトが終了位置となります。XYの入れ替えを行なっている場合は、列と行の最大値も入れ替える必要があるので注意です。Adafruitのライブラリでは、列と行の最大値を保持してsetRotationで調整しています。

この矩形の範囲で書き込みが行われます。イメージは以下の通りです。

CASET(column address set)で列の開始と終了、RASET(row address set)で行の開始と終了を設定して矩形を表します。

2019.2.5 図上のコマンド名のtypoと、XS,YS,XE,YEの対応を修正しました。

  • 修正前:CASETで(XS,YS)〜、RESETで(XE,YE)〜
  • 修正後:CASETで(XS,XE)〜、RASETで(YS,YE)〜

setAddrWindowにより描画処理前に必ず設定しているため、この初期化に意味がありません。また、GMピンで設定している解像度によりデフォルト値が決まっているので、このタイミングで呼び出さなくても問題はありません。初期設定の処理で、このコマンドを送る必要はなさそうです。

Rcom3

コマンド数:4

#コマンド
(16進数)
パラメータ数パラメータ
(16進数)
説明
1GMCTRP11602, 1c, 07, 12,
37, 32, 29, 2d,
29, 25, 2B, 39,
00, 01, 03, 10,
ガンマ(正極性)補正特性設定
 GMCTRN11603, 1d, 07, 06,
2E, 2C, 29, 2D,
2E, 2E, 37, 3F,
00, 00, 02, 10
ガンマ(負極性)補正特性設定
3NORONなしDisplay Modeを
Normal Displayモードに設定
2DISPONなし 
GMCTRP1

ガンマ補正(正極性)の各階調の電圧を設定します。

ST7735Sのデータシートの「12 Gamma Structure 」の図にある通り、梯子状に階層化された抵抗により64段階に電圧を分割しています。設定できるのは最大・最小と、その間の14の電圧です。

中間の電圧は「12.2 Gamma Voltage Formula (Positive/ Negative Polarity)」の表にある計算式に従います。

GMCTRN1

ガンマ補正(負極性)の各階調の電圧と、上下の電圧を設定します。

DISPON

フレームメモリーから液晶パネルへの出力を有効にして、画面の表示をONにします。

NORON

Display ModeNormal Modeに設定します。

一括ではなく個別に送信しているコマンド

optionINITR_BLACKTABINITR_MINI160x80を指定した場合は、追加でMADCTLを送信し設定を変更していますが、setRotationに同じ目的の処理があり意味をなさず不要です。

Gitの履歴を確認すると、この処理はST7735S対応で追加された処理だが急ぎすぎたのか、変更途中のコードが残ったものです。

まとめ

送信するコマンドを調べるなかで、液晶パネルの仕組みについての理解が深まり、他の制御チップでも同じ駆動方式ならば、データシートを参照する場所のあたりが付きそうです。

初期設定で、いくつかデフォルト値と同じ値を設定していることが分かりました。ライブラリを自作する場合は以下の理由により、デフォルト値でも動作に影響する設定なら、明示的に送信するのがいいと考えます。

  • 実行中に別の設定に変更されても初期状態に戻せる。
  • 意図的か、忘れたかを迷わないようにする。(コメントだってミスがある)

プログラムサイズを考えても数バイトなので可読性を優先します。

ガンマ補正に関しては後から個別の調整するような値なので、設定方法さえあればデフォルト値で使用してもいいのではと考えています。

参考サイト