LCDの使い方
LCDの使い方
ここでは,MEMEsに実装されているLCDの使い方を学ぶ.
使用するLCDについて
LCD は,Liquid Crystal Display の略で,液晶ディスプレイとも呼ばれる.腕時計などに組込まれているいる小型のものから,パソコン用ディスプレイや液晶テレビなどの大型のものまで広く使われている.
今回のターゲットは,MEMEsボードの16文字×2行の液晶モジュールである.この液晶は文字表示用であり,英数字を表示することができる.
この液晶モジュールの内部構造は図1のようになっている.
図1のインストラクションレジスタ(IR)とデータレジスタ(DR)に対して,各種コマンドやデータを読み書きすることにより液晶と文字を表示することができる.
具体的には,表示データRAM(DDRAM)に文字コードを書き込むと,対応した場所に文字が表示される.
以下,文字を表示するための予備知識と手順を説明する.
LCDモジュールの信号と接続
LCDモジュールには次のような信号線がある.
ピン番号 | 信号名 | 機能 |
1-8 | DB[7:0] | データバス4ビットモードにしたとき,db[7:4]を使う |
9 | E | イネーブルR/W=0のとき:1 → 0 でデータ書き込みR/W=1のとき:1でデータ出力 |
10 | R/W | リード/ライト(本テキストではライトのみ使用)0:LCDへの書き込み1:LCDからの読み出し |
11 | RS | レジスタ選択0:インストラクションレジスタ1:データレジスタ |
12 | Vo | コントラスト調整 |
13 | Vss | GND |
14 | Vdd | 電源 |
LCDモジュールとSH7085とは図2のように接続されている.
図2:SH7085とLCDモジュールの接続
また,LCDモジュールをリード/ライトするには,信号を図3のように操作しなければばらない.
図3:信号のタイミング
書き込みの場合は次のような手順になる.
- E=0にする(PA23を操作)
- インストラクション(命令)の場合はRS=0,データの場合はRS=1にする(PA22を操作)
- R/W=0(書き込み)にする(PD23を操作)
- E=1にする(PA23を操作)
- 書き込む値をDB0-DB7に与える(PD24-PD31を操作)
- E=0にする(PA23を操作)
インストラクションコードの書き込みはCプログラミングでは次のようになっている.
#define LCD_RS (PA.DR.BIT.B22) #define LCD_E (PA.DR.BIT.B23) #define LCD_RW (PD.DR.BIT.B23) #define LCD_DATA (PD.DR.BYTE.HH) void LCD_inst (char inst) { LCD_E = 0; LCD_RS = 0; LCD_RW = 0; LCD_E = 1; LCD_DATA = inst; LCD_E = 0; wait_us(40); }
本テキストでは使用しないが,読み出しの場合は次のような手順になる.
- E=0にする(PA23を操作)
- ステータスを読む場合はRS=0,データを読む場合はRS=1にする(PA22を操作)
- R/W=1(読み出し)にする(PD23を操作)
- E=1にする(PA23を操作)
- DB0-DB7に現れるデータを取得する(PD24-PD31を読み込む)
- E=0にする(PA23を操作)
今まで扱ってきたメモリやマイコン内部のモジュールは,CPUのバスに接続されていた.そのためCPUからは,0x04000000のように特定番地をリード/ライトすることによりアクセスをすることができた.
しかしLCDモジュールはCPUのバスではなくSH7085の汎用I/Oポートに接続されているため,CPUからは特定の番地のリード/ライトでアクセスすることはできない.アクセスするには上に示したように汎用I/Oポートを操作して,図3の波形を作る必要がある.
初期設定
LCDに対して各種インストラクションを送ったり,文字コードを送ったりする前に,LCDモジュールの初期化を行う必要がある.初期化では接続バス幅の設定や各種動作モードの設定を行う.
LCDのインストラクション一覧を表2に示す.
表2:インストラクション一覧
- ID・・・1:インクリメント,0:デクリメント
- S・・・1:表示のシフトを伴う,0:表示のシフトを伴わない
- SC・・・1:表示のシフト,0:カーソルの移動
- DL・・・1:8ビット,0:4ビット
- N・・・1:2行,0:1行
- F・・・1:5×10ドット,0:5×7ドット
- D・・・1:ディスプレイをオン,0:ディスプレイをオフ
- C・・・1:カーソルをオン,0:カーソルをオフ
- B・・・1:カーソルにある文字を点滅,0:カーソルにある文字を点滅させない
- BF・・・1:内部動作中,0:インストラクション受付可
- ACC・・・GCCRAMアドレス
- ADD・・・DDRAMアドレス
- AC・・・アドレスカウンタ
初期設定には図4のような手順の規定があり,これを守らないと正しい設定ができない.
図4:初期化手順
文字表示
初期化が完了すれば,LCDに文字を表示できるようになる.次にその手順を説明する.
DDRAMアドレスと文字の位置
LCD上の文字の位置とDDRAMアドレスとは,図5のように1対1に対応している.
図5:DDRAMアドレスと表示位置の関係
一行目の左端は0x00番地,右端は0x0f番地であり,二行目の左端は0x40番地,右端は0x4f番地である.
例えばDDRAMの0x00番地に0x41(’A’の文字コード)を書き込むと,LCDの左上に’A’が表示される.
DDRAMアドレスの指定は,上のインストラクション一覧の「DDRAMアドレスセット」を使用する.インストラクションコードは0x80であり,下位7ビットにDDRAMアドレスを設定する.
例えば右下(DDRAMアドレス0x4f)にセットしたい場合,0x80 | 0x4f = 0xcf をインストラクションとして書き込む.
このインストラクションにより,現在の書き込み位置(カーソル位置)が右下にセットされる.
続いて,カーソル位置に文字コードを書き込む.これは単にLCDに対して文字コードを(インストラクションではなく)データとして書き込むだけでよい.
LCD.zip
演習問題
1.(LCD_prog1)LCD_init() 関数を完成させよ.
2.(LCD_prog1)LCD の右上に’A’の文字を表示させよ.
動画1:初期化して’A’を表示
3.(LCD_prog1)wait_us() 関数を,CMT0 を使用するように改造せよ.
現状ではソフトウェアタイマとなっていて,待ち時間は不正確である.これをCMT を使った正確なタイマに改造する.
分周比は,1/32 とする.この場合,CMCOR0 の設定は1.6us 単位となるので,引数を0.625 倍(10倍してから16で割る)した値を設定する.
カウントできる最大値を考慮して,引数がそれより大きい場合は,最大値に制限する.
なお,改造前の関数で使用している nop() は,”何もしない”という特殊な命令 ”NOP” を実行する.ここでは,確実な時間稼ぎのために使用している.NOPはNo OPerationの略である.
4.(LCD_prog1)関数LCD_cursor() を完成させよ.
書き込み位置(カーソル位置)を設定する関数である.
左上を x = 0, y = 0 とし、引数 x は 0 ~ 15 に,引数 y は 0 ~ 1 に値制限してから使用すること.
5.(LCD_prog1)関数LCD_putch() を完成させよ.
現在の書き込み位置に1文字表示する関数である.
メイン関数内で,下記のように関数を呼び出している.
LCD_cursor(8, 0); LCD_putch('B');
動画2:LCD_cursor と LCD_putch 関数の動作例
6.(LCD_prog1)関数LCD_putstr() を完成させよ.
引数は文字列へのポインタである.文字列が終了するまで前問のLCD_putch()を何回か呼び出す.
メイン関数内で,下記ように関数を呼び出している.
LCD_cursor(10, 1); LCD_putch("CDEF");
動画3:LCD_cursor と LCD_putstr 関数の動作例
7.(LCD_prog2)hterm から X 座標,Y 座標と文字列を入力し,LCDに表示するプログラムを作成せよ.
まず scanf() 関数を使い,座標と文字列を取得する.
次に LCD_cursor() 関数で座標を指定し,LCD_putstr() 関数で文字列を表示する.
ターミナルからは,下記のように座標と文字列を与えている.
: G X Y String : 0 0 test <- 0 0 test と入力している X Y String : 2 1 sample <- 2 1 sample と入力している X Y String : 4 0 microcomputer <- 4 0 microcomputer と入力している
動画4:ターミナルから座標を指定して文字列を表示させた例
8.(LCD_prog2)CMT1を使い,hterm から入力した文字列が 500ms ごとに左から右へ移動するプログラムを作成せよ.
ターミナルからは,下記のように座標と文字列を与えている.
: G X Y String : 0 0 test <- 0 0 test と入力している X Y String : 2 1 sample <- 2 1 sample と入力している X Y String : 4 0 micon <- 4 0 micon と入力している X Y String : 3 1 SH7085 <- 3 1 SH7085 と入力している
動画5:ターミナルから入力した文字列が右へシフトする例