今回は液晶モジュール(AQM1602XA/ST7032)の制御方法の説明です。
AQM1602XAで表示できる文字
実践編で使用する液晶モジュール(AQM1602XA)はキャラクタディスプレイです。そこで、最初にこの液晶モジュールで表示できる文字の種類を確認しておきます。
以下はAQM1602XAのデータシートに記載さている、表示できる文字種です。
表示する文字の指定は1文字1バイト(=8ビット)で指定します。表の縦横ともに2進数が記載さていますが、上の欄の赤枠は上位4ビット、左の欄の青枠は下位4ビットです。例えば「A」という文字を表示したい場合、2進数では0b01000001(=0x41)を液晶モジュールに送ることになります。
この表を見ると、0b00100000のスペースから0b01111010の「z」までは通常のASCII文字になっています。そのため、例えば「A」という文字を表示したい場合、I2C通信で送信するデータは、C言語のプログラムでは0b01000001(=0x41)と表記する必要はなく、単に ‘A’ と表記すればOKです。(C言語の文字と文字列表記について忘れてしまっている方は、入門書などを復習してみてください。ここで、”A”と’A’の違いなども含めて整理しておきましょう)
また、左上の方にある領域、0b00000000から0b00000111は「CG RAM」と記載されてまいす。この8文字分はユーザが自由に文字を登録できる部分になります。この液晶モジュールは1文字5ドットx8ドットですので、この範囲で自由な文字のデザインを液晶モジュールに登録して利用することができます。ただ、実践編の説明では文字の登録まではカバーしませんので、ご要望があれは補足記事を書きたいと思います。
天気予報の「晴」「曇」「雨」の絵(アイコン)をこのCG RAMに登録して表示できるといいですが、5ドットx8ドットで天気マークを表現するのは難しそうです。2文字で表現すると隙間が空いてしまいますが、もしかしたらうまく表現できるかもしれません。
AQM1602XAの制御方法概要
液晶モジュールの制御はかなり複雑です。慣れないと何をしているのかさっぱり、という感じになってしまいますので、まずは制御方法の概要を確認しておきましょう。
液晶モジュールの制御には、大きく分けて以下の2種類あります。
- 液晶モジュールの動作設定
液晶モジュールに電源を供給すると動作を始めますが、そのままでは文字データを送っても何も表示されません。電源供給後、最初に液晶モジュールのコントラストを設定したり、画面をクリアして表示状態にする、などの制御が必要です。 - 表示制御
動作設定後、上の表に従って文字データを送るとその文字が表示されます。
今回の記事では、液晶モジュールの動作設定を中心に説明します。表示制御については次回の記事で説明します。
液晶モジュールの制御データ構成
それでは、液晶モジュールのデータ通信方法について、最初にどのようなデータをやりとりすればよいかを説明し、その後にI2C通信手順を詳細に説明、最後に動作設定方法を説明します。
先ほど、液晶モジュールの制御は大きく分けて「動作設定」と「表示制御」がある、と説明しました。PICマイコンから液晶モジュールに送信するデータが「動作設定」のためのデータなのか、「表示制御」のためのデータなのか区別する必要があります。
例えば、「V」という文字を表示する場合、先ほどの表示文字の表では「0b01010110」つまり0x56を液晶モジュールに送信することになります。
一方、0x56はコントラストを設定するための動作設定のデータでもあるんです。
このように同じデータでも異なる意味があるため、それが動作設定データなのか、表示文字データなのか区別する必要があります。このような区別をするために、液晶モジュールにデータを送る際、
「データの種別を示す1バイト」 と 「データ」
の2バイトのデータを送信します。この「データの種別を示す1バイト」は以下のようになっています。
値 | 意味 |
---|---|
0x00 | 動作設定データ |
0x40 | 表示文字データ |
例えば先ほどの「0x56」の場合、液晶モジュールに「0x00、0x56」の2バイトを送ると、液晶モジュールは動作設定のための0x56が送られてきたと認識してコントラストの設定を行います。また「0x40、0x56」の場合は表示文字データが送られてきた、と認識して、液晶画面に「V」を表示します。
送信データはこの2バイト1組が基本です。あとはI2C通信手順に従ってこの2バイト1組のデータを送信します。
液晶モジュールのI2C通信手順
液晶モジュールを制御するには、I2C通信手順については十分な理解が必要ですので、忘れてしまった場合は今までの記事を読み返してみてください。一般的なI2C通信手順を簡単にまとめておくと、
という順番でデータをやりとりすればよかったんですよね。今回制御する液晶モジュールの場合、送信するデータは2バイト(「種別を示す1バイト」と「データ1バイト」)ですので、I2C通信手順は以下のようになります。
この図で、具体的にどのようなデータをやり取りすればよいか説明します。
I2C通信を行うモジュールのデータシートでは、SCLとSDAのタイミングチャートで説明しているケースがあります。一方、以下のようにそれぞれの信号を1ビット単位で説明しているケースもあります。
この図で「S」や「A」とありますが、「S」はスタートコンディション、「A」はACK/NACK信号です。
それぞれ1ビットの情報と見立てて、このようにビット表現しています。
先ほどの液晶モジュールのI2C通信手順をこのようにビット表現すると、以下のようになります。先ほどの図の色と対応させています。
最初の赤色の部分は、スタートコンデションで通信を開始し、スレーブアドレス+読書きビットを送信し、ACK/NACK信号から構成されています。液晶モジュールのスレーブアドレスは0x3Eで、マスターからスレーブにデータを送信(書き込み)しますので、読書きビットは0です。つまり最初の1バイトは、0x7Cとなります。
次の青色の部分は、データの種別を示す1バイトです。先ほど「動作設定は0x00、文字表示は0x40」と説明しましたが、このようになる理由を詳しく説明します。
この1バイトは、第7ビットがCo、第6ビットがRSとなっています。
第7ビットの「Co」はContinuousの略で、「データの種別を示す1バイト」と「データ」の2バイト1組のデータを一度に何組も送る場合、後続の1組のデータがある場合にCoビットを1にします。2バイト1組のデータを1組だけ送る場合はCoビットを0にします。
実践編で作成するプログラムは、1回のI2C通信(スタートコンディション〜ストップコンディション)で2バイト1組のデータを送る関数を作成し、それを使って複数のデータを送るように作成します。
第6ビットの「RS」はRegister Selectの略で、このビットにより、送信するデータが動作設定データなのか表示文字データなのかを指定します。「Register Select」は「レジスタ選択」という意味ですが、レジスタの選択とデータの意味の指定は結びつかないですよね。液晶モジュールのコントローラ(ST7032)には多くのレジスタがあり、動作設定をするレジスタ、文字表示をするレジスタなどがあるため、このような名前がつけられているようです。
このRSビットは、0の時は動作設定データ、1の時は表示文字データとなります。
残りの第5ビットから第0ビットは0を設定します。
つまりこの青色のデータは、Coビットは常に0、RSビットで動作設定か文字表示かの設定、残りのビットは0になりますので、以下のようなデータとなります。
2進数 | 16進数 | 意味 |
---|---|---|
0b00000000 | 0x00 | 動作設定データ |
0b01000000 | 0x40 | 表示文字データ |
最後の緑色の部分は実際に液晶モジュールに送信するデータです。先ほどの青色の部分で動作設定データを指定した場合はこのデータは動作設定のためのデータ、表示文字データを指定した場合は液晶モジュールに表示する文字のデータとなります。
ここまでわかったところで、実際の液晶モジュール(ST7032コントローラ)のデータシートを確認してみましょう。今後、自分が使いたい液晶モジュールがある場合、データシートでデータ通信方法を確認する必要が出てきます。今回はデータシートの読み方に慣れておきたいと思います。
それでは、ST7032のデータシートで、I2Cの通信手順を確認します。以下の図はST7032のデータシートに記載されているI2C通信によるデータ通信方法です。
この図では、「データの種別を示す1バイト」と「データ1バイト」を2バイト1組のデータを2回、つまり合計4バイトを送信する例を示しています。そのため、最初の1組のCoビットは1、次の1組のCoビットは0になっています。
また、図中の「S」「P」「A」は他のI2C通信モジュールでもよく使われる表現ですので覚えておくとよいと思います。なお、Co、RSビットについてはこの液晶モジュールコントローラ(ST7032)特有ですので、データシートには以下のように説明があります。見慣れないビットについてはデータシートのどこかに説明があります。
ST7032の動作設定コマンド
それでは、ST7032の動作設定をするためのデータ(コマンド)はどのようになっているか確認してみましょう。
ST7032の動作設定コマンドは、基本コマンド(9種類)と、コマンドグループ1(2種類)、コマンドグループ2(5種類)があります(データシートではこのような呼び方ではありませんが、わかりやすくこのように説明します)。合計16種類ありますが、普段使いするコマンドのみ説明します。
基本コマンド
基本コマンドには9種類ありますが、液晶モジュールを通常の文字表示をする場合に必要な3種類のコマンドを説明します。
液晶ディスプレイに何か文字を表示している場合、一括で消去する場合のコマンドです。16進数では0x01になります。液晶モジュールに0x00, 0x01の2バイトを送ると画面が消去されます。
第2ビットでは、ディスプレイのON/OFFを設定します。1にするとディスプレイが表示され、0にすると非表示になります。0にして非表示にした場合でも、表示されている内容は保存されていますので、再度ONにするとその内容が表示されます。
第1ビットでは、カーソルの表示/非表示を設定します。カーソルは、エディタなどで呼ばれているカーソルと同じです。以下のように表示した文字の下にカーソルが表示されます。
1に設定すると表示、0に設定すると非表示になります。
第0ビットはカーソル点滅のON/OFFを設定します。以下のように表示している文字が表示されたり黒く塗りつぶされたり、という状態が交互に表示されます。
1に設定するとカーソル点滅ON、0に設定するとOFFになります。
第3ビットと第2ビットは基本的に組みで設定します。第3ビットのNは、液晶ディスプレイを2行モードで使用するか1行モードで使用するかの設定を行います。1に設定すると2行モード、0に設定すると1行モードとなります。2行のディスプレイをわざわざ1行モードに設定して1行だけ使用するというのはあまり意味がありません。
第2ビットのDHは文字の大きさを設定するビットで、このビットを1にすると文字の縦の大きさが2倍になります。0に設定すると通常の大きさになります。
第3ビットと第2ビットをそれぞれ「2行モード、通常の大きさの文字」「1行モード、縦2倍の大きさの文字」という組み合わせで設定すると、以下のように表示文字の大きさを切り替えることができます。
第0ビットのIS(Instruction Set)は非常に重要なビットです。このビットで、コマンドグループ1かコマンドグループ2のどちらのコマンドを使用するか指定します。ISを0設定するとコマンドグループ1のコマンド、1に設定するとコマンドグループ2のコマンドが使用できます。
なお、コマンドグループ1のコマンドは通常あまり使用しませんので説明は省略します。以下にコマンドグループ2の通常使用するコマンドを説明します。
コマンドグループ2
第3ビットのBSは、内部電源回路の設定で通常は0を指定します。
第2ビット〜第0ビットは、内部発振回路の周波数で液晶ディスプレイのリフレッシュレートの設定になります。通常はF2〜F0は0b100を設定します。
特に変更する必要がなければ、通常は0b00010100(0x14)の設定となります。
第3ビットのIon(ICON Display)は、アイコン表示のON/OFF設定です。動作確認しておらず申し訳ないのですが、ST7032はアイコンを登録できるようで、サイズは5ドット x 16ドットです。アイコン表示モードにするかかどうかの設定です。通常は使用しませんので0を設定します。
第2ビットのBonは内部のブースター回路をONにするかOFFにするかの設定です。ここでブースター回路について簡単に説明しておきます。液晶ディスプレイを動作させるには5Vが必要なものが多く、実践編で使用する液晶モジュールも5V動作が基本です。ただ、実践編の回路では3.3V電源を使用しています。ブースター回路とは電圧を上げるための回路で、この回路を使用すると3.3Vの電源でも内部で電圧を上げて液晶ディスプレイを制御することができます。実践編のプログラムでは1に設定してブースター回路をONにします。
第1ビットと第0ビットはコントラストを設定するビットです。ST7032のコントラスト設定は6ビット(64段階)ですが、上位2ビットはここで設定します。実践編のプログラムでは、コントラストは0b100000を設定しています。64段階の中間の32となります。もし表示が薄すぎたり濃すぎたりするようでしたらこの値を変更してみてください。0b100000を設定しますので、C5は1、C4は0になります。
ということで、設定値は0b01010110(0x56)となります。
この設定は電子回路の理解が必要ですので詳細な説明は省略します。通常はFonが1、Rab2が1、Rab1とRab0は0に設定します。
電子回路をご存知の方に向けて簡単に概要を説明します。液晶ディスプレイのコントラスト設定は、内部では液晶制御電圧を調整しています。内部回路としては以下のようになっています。
液晶制御電圧はV0で、64段階のコントラスト設定値(Vref)に対し、どの程度の倍率で増幅するかの設定ができます。先ほどのFonは、この増幅回路のON/OFF制御、Rab2〜Rab0はオペアンプ増幅回路の帰還抵抗比率設定です。1倍から3.75倍まで設定でき、通常は2倍が適切なようです。2倍にする場合、Rab2〜Rab0は0b100ですので、先ほどのような設定になります。
最後はコントラスト設定です。第3ビットのC3から第0ビットのC0でコントラストの下位4ビットを設定します。コントラストは0b100000に設定しますので、C3〜C0は0に設定します。
設定値としては0x70になります。
以上が通常使用する動作設定コマンドです。
ST7032の動作設定方法
動作設定について一通り説明しましたので、液晶モジュール電源投入後の動作設定をまとめます。
以下は、ATM1602のデータシートに記載されている、一般的な動作設定の流れです。この動作設定で使用されているコマンドは上に一通り説明していますので、ここでは要点のみ図中に説明します。
注意点としては、電源投入後は40ms以上ウエイト、コマンドとコマンドの間は少なくとも26.3μsウエイト、また途中の電源設定では内部電源が安定するまで200ms以上ウエイトが必要です。
実践編のプログラムは以下の内容で動作設定しますが、コントラスト設定は異なりますので、異なる部分は赤で示しています。
次回は文字表示方法を説明します。
更新履歴
日付 | 内容 |
---|---|
2018.7.15 | 新規投稿 |
I2c液晶のCG-RAMにオリジナルのデーターを登録しようと試行錯誤しております。
control byte部分がCo:RSが有って残り6bitはどの部分をセットすれば良いのでしょうか?
現在の液晶制御設定:
start:液晶選択(h7c):ack:ディレ-:Co/RS(h80):エントリーモード(h38);デレ-:Co/RS(h80):CG-RAMアドレス選択(h40)とセットしますが、h40を入れた時点で2行目1番左に移動します。
*なお初期設定は済みで、表示等は出ております。
追伸です
instruction codeを送った後は必ずACKコードを送っていることを未記載でした。
以上よろしくお願い申し上げます。
ご連絡が遅くなってしまい申し訳ございませんでした。
ご質問は「コントロールバイトはCoとRSビットの他に6ビットが余っているが、何を設定すれば良いか」という内容でしょうか。
この記事中にも解説してありますが、コントロールバイトは0x00が次のデータはコマンド、0x40が次のデータはデータ、という意味になります。そのため残りの6バイトは0になります。
また「0x40を入れた時点で2行目1番左に移動」というのは、カーソルを表示している設定で、0x40のあとそのカーソルが2行目の先頭に移動してしまう、ということでしょうか。
0x38でInstruction Tableを0にしていますので、その後の0x40ではCGRAMのアドレスが0に設定されるだけですので、カーソルが移動する原因は不明ですが、0x40のあと、登録データは送信していますでしょうか。0x40のあと登録データを8バイト送る必要があると思いますので、送信すると状況が変わるかもしれませんのでお試しいただけますでしょうか。
追記で
内部電源設定回路で可変抵抗(Reb)の倍率で電圧を上げることにより
液晶のコントラストの濃さを設定するという認識で良いのですか?
はい、オペアンプの非反転増幅回路で、非反転入力のVrefは64段階で指定、その電圧を、Ra/Rbの比率倍してコントラストの濃さの設定をしている、ということになります。
返信ありがとうございます
認識が有ってる様なので安心しました
お世話になります
44回の例文を使って弄ってるんですが
カーソルを基本コマンドで出せるまでは分かったんですが
カーソルは常に文字列の最後尾に表示されます
カーソルは任意に移動は出来ないのでしょうか?
出来なくても問題ないですが、なんか気になりました
ご質問どうもありがとうございます。
すみません、実機確認していないのですが、動作確認で使用している「lcdLocateCursor」関数でカーソル位置指定できませんでしょうか。現在動作する実機がなく、確認せずの回答で申し訳ございません。
返信ありがとうございます
カーソル関数をもう一つ作り
printfの後にカーソル位置と表示のコマンドを入れたら
任意のカーソル移動が出来ました
lcdLocateCursor_1(0,0)
printf
lcdLocateCursor_2(1,0)
/////////////////////////////
void lcdLocateCursor_1(uint8_t position_x, uint8_t position_y){
lcdSendCommandData( 0x80 + 0x40 * position_y + position_x);
return;
}
void lcdLocateCursor_2(uint8_t position_x, uint8_t position_y){
lcdSendCommandData( 0x80 + 0x40 * position_y + position_x);
lcdSendCommandData(0b00001111);
return;
}
お返事どうもありがとうございました。
lcdLocateCursor関数でカーソル位置指定できる、とのことでよかったです。
こちらで実機確認できずにすみませんでした。またお返事いただきましてありがとうございました。