目次
はじめに
「ArduinoでaitendoのTFT液晶(M-Z18SPI-2PB,Z180SN009)を制御するライブラリを作成するための調査(5)」の続きで、初期化のために送信しているコマンドの内容を調べて行きます。
Adafruit_ST7735クラス
初期化に必要なコマンドとパラメータ
commandList
で送信しているコマンドの配列から、制御チップの初期化に必要なコマンドとパラメータを調べます。定義されているコマンドの配列は7つあります。最初に呼び出す初期化処理(initB
とinitR
)から調査対象を絞ります。
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);
}
まず、Bcmd
はinitB
でしか使用していないので調査対象から外します。
ST7735Sを利用する場合はoption
にINITR_BLACKTAB
を渡してinitR
を呼び出すので、INITR_BLACKTAB
の時に利用されないRcmd2green
、Rcmd2green144
、Rcmd2green160x80
も調査対象から外します。
残ったRcmd1
、Rcmd2red
、Rcmd3
を調査対象にします。
Rcmd1
コマンド数:15
# | コマンド (16進数) | パラメータ数 | パラメータ (16進数) | 説明 |
---|---|---|---|---|
1 | SWREST(01) | – | なし | ソフトウェアリセット |
2 | SLPOUT(11) | – | なし | スリープからの復帰 |
3 | FRMCTR1(B1) | 3 | 1,2C,2D | フレームレートの設定 |
4 | FRMCTR2(B2) | 3 | 1,2C,2D | 〃 |
5 | FRMCTR3(B3) | 6 | 1,2C,2D 1,2C,2D | 〃 |
6 | INVCTR(B4) | 1 | 7 | フレーム反転方式の設定 |
7 | PWCTR1(C0) | 3 | A2,2,84 | 液晶駆動出力電圧の設定 |
8 | PWCTR2(C1) | 1 | C5 | 〃 |
9 | PWCTR3(C2) | 2 | A,0 | 液晶駆動出力電流の設定 |
10 | PWCTR4(C3) | 2 | 8A,2A | 〃 |
11 | PWCTR5(C4) | 2 | 8A,EE | 〃 |
12 | VMCTR1(C5) | 1 | E | コモン電圧の設定 |
13 | INVOFF(20) | – | なし | 反転表示設定(OFF) |
14 | MADCTL(36) | 1 | C8 | 読み書き、色順、走査方向の設定 ※ この設定値は未使用に等しい |
15 | COLMOD(3A) | 1 | 5 | 色深度の設定 |
SWREST
最初にSWREST
によりソフトウェア・リセットを行なっています。しかし、ハードウェア・リセットを行なった後なので、あまり意味はありません。
SLPOUT
起動(およびリセット)後はスリープモードなので、SLPOUT
によりスリープモードから抜ける必要があります。コマンドは特定のモードでないと有効にならない場合があるので、モードを意識する必要があります。
FRMCTR[1,2,3]
液晶パネルのリフレッシュレートと、画像の更新タイミングが合っていない場合、画像がズレて見えるティアリング(Tearing Effect)が発生します。フレームレートとはフレーム(≒1画面)の1秒間の更新頻度のことで、フレーム周波数(frame frequency)とも呼ばれ、単位はヘルツ(Hz)で表される。60Hzなら1秒間に60フレームとなります。
このフレームレートをDisplay Mode
ごとに設定する必要があります。起動(およびリセット)後はDisplay Mode
がnormal mode
なので、idle mode
とpertial mode
については後の課題として深追いしません。
# | Display Mode | Color Format | 対応するコマンド |
---|---|---|---|
1 | normal mode | full color | FRMCTR1 |
2 | idle mode | 8-colors | FRMCTR2 |
3 | Partial mode | full color | FRMCTR3 |
データシートを見ると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進数) | 説明 |
---|---|---|---|---|
1 | CASET | 4 | 0,0,0,7F | フレームメモリーの 列の開始と終了 |
2 | RASET | 4 | 0,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進数) | 説明 |
---|---|---|---|---|
1 | GMCTRP1 | 16 | 02, 1c, 07, 12, 37, 32, 29, 2d, 29, 25, 2B, 39, 00, 01, 03, 10, | ガンマ(正極性)補正特性設定 |
GMCTRN1 | 16 | 03, 1d, 07, 06, 2E, 2C, 29, 2D, 2E, 2E, 37, 3F, 00, 00, 02, 10 | ガンマ(負極性)補正特性設定 | |
3 | NORON | – | なし | Display Modeを Normal Displayモードに設定 |
2 | DISPON | – | なし |
GMCTRP1
ガンマ補正(正極性)の各階調の電圧を設定します。
ST7735Sのデータシートの「12 Gamma Structure 」の図にある通り、梯子状に階層化された抵抗により64段階に電圧を分割しています。設定できるのは最大・最小と、その間の14の電圧です。
中間の電圧は「12.2 Gamma Voltage Formula (Positive/ Negative Polarity)」の表にある計算式に従います。
GMCTRN1
ガンマ補正(負極性)の各階調の電圧と、上下の電圧を設定します。
DISPON
フレームメモリーから液晶パネルへの出力を有効にして、画面の表示をONにします。
NORON
Display Mode
をNormal Mode
に設定します。
一括ではなく個別に送信しているコマンド
option
にINITR_BLACKTAB
かINITR_MINI160x80
を指定した場合は、追加でMADCTL
を送信し設定を変更していますが、setRotation
に同じ目的の処理があり意味をなさず不要です。
Gitの履歴を確認すると、この処理はST7735S
対応で追加された処理だが急ぎすぎたのか、変更途中のコードが残ったものです。
まとめ
送信するコマンドを調べるなかで、液晶パネルの仕組みについての理解が深まり、他の制御チップでも同じ駆動方式ならば、データシートを参照する場所のあたりが付きそうです。
初期設定で、いくつかデフォルト値と同じ値を設定していることが分かりました。ライブラリを自作する場合は以下の理由により、デフォルト値でも動作に影響する設定なら、明示的に送信するのがいいと考えます。
- 実行中に別の設定に変更されても初期状態に戻せる。
- 意図的か、忘れたかを迷わないようにする。(コメントだってミスがある)
プログラムサイズを考えても数バイトなので可読性を優先します。
ガンマ補正に関しては後から個別の調整するような値なので、設定方法さえあればデフォルト値で使用してもいいのではと考えています。
参考サイト
- wikipedia – 液晶ディスプレイ
- JEITA(電子情報技術産業協会) – 2007年度成果 – 液晶ドライバICに関する用語と文字記号
(直リンクではなく、PDFファイルのリンクがあるページのURLです)