SC1602 LCDモジュール (HD44780コンパチブル) の使い方

SC1602

(画像をクリックするとサンプルプログラムの動画を表示します。)

LCDのキャラクタディスプレイとして不動の地位を得ているHD44780コントローラー 互換のSC1602ディスプレイをPICで制御する方法について纏めたページです。過去に 似たようなページを作っていましたが、 情報が 古かったり不充分な点があったので、備忘録としての意味もあって改めて作成しました。

ライブラリおよびサンプルプログラムのソースはこちら

LCDモジュールの仕様について

ピンアサイン

Pin No Pin Out Description 備考
1VDD電源(+5V)互換品はVDD,VSSは逆転している場合がある。
ノイズ対策のため、VDD-VSS間に10uF程度のコンデンサを接続する事が推奨されます。
2VSSGND
3VoContrast Adj20kΩ程度のVRでVDD-VSS間で電圧調整出来るよう接続
4RSRegister Selectコマンド発行の際0,データ転送の際1にセット
5R/WRead/Write読出:Hi, 書込:Low
6EEnable Signal通常はLowにしておき、送受信の際Positive pulseを与える。
7DB0Data Bit04bitモードではBD0:3はオープン
8DB1Data Bit1
9DB2Data Bit2
10DB3Data Bit3
11DB4Data Bit4
12DB5Data Bit5
13DB6Data Bit6
14DB7Data Bit7

DD RAMアドレッシング

モジュールの桁数や行数、表示モードにより、アドレッシングが異なります。

基本的に80文字分のメモりがあり、そのうち表示可能な範囲を表示しています。表示されているかに関らず、任意の位置にWrite可能です。

16x1モードの場合

1 2 3 ... 39 40 41 ... 78 79 80
00h 01h 02h ... 26h 27h 28h ... 4Dh 4Eh 4Fh

16x2モードの場合

1 2 3 ... 38 39 40
00h 01h 02h ... 25h 26h 27h
40h 41h 42h ... 65h 66h 67h

文字コード表

Character code table

キャラクタコード0x0から0x7の8個はCG RAM(後述)に割当られています。

0x8-0xFのキャラクタコードは0x0-0x7と同一のキャラクタが重複して読み出されます。

CG RAMアドレッシング

CDRAM Addressing

CG RAMはユーザーがキャラクタパターンを定義する事ができるエリアです。キャラクタジェネレータが備えていない文字を定義して利用することができます。

CG RAMアドレスは6 bitなので、上位3 bitでキャラクタを指定、残りの3 bitでキャラクタパターンの行を指定します。各行毎のパターンはCG RAMデータとして与えます。キャラクタパターンが5x7 bitで表現されているので、データビット7:5は使用しません。

インストラクション

Instruction RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description 実行時間
Clear Display 0 0 0 0 0 0 0 0 0 1 全表示クリア後カーソルをホーム位置(0x00)へ戻す。 1.52ms(1.62ms)
Return Home 0 0 0 0 0 0 0 0 1 x カーソルをホーム位置へ戻す。ディスプレイシフトも初期位置に戻ります。
Entry Mode Set 0 0 0 0 0 0 0 1 I/D S カーソルのインクリメント方向、表示シフトを設定します。
I/D=1:右,I/D=0:左
S=1:表示シフトON,S=0:表示シフトOFF
37us(40us)
Display ON/OFF 0 0 0 0 0 0 1 D C B 表示、カーソルON/OFF
D=1:ディスプレイON
C=1:ブロックカーソルON
B=1:ブリンクON
Corsor or Display Shift 0 0 0 0 0 1 S/C R/L x x カーソル移動/表示シフト
S/C=1:表示シフト,S/C=0:カーソル移動
R/L=1:右,R/L=0:左
Function Set 0 0 0 0 1 DL N F x x 通信モード、行数、Font sizeの設定
DL=1:8bit,DL=0:4bit
N=1:2line,N=0:1line
F=1:5x10dot,F=0:5x7dot
Set CGRAM address 0 0 0 1 AC5 AC4 AC3 AC2 AC1 AC0 CG RAMのアドレスをセットします。以後CG RAMへのデータアクセスとなる。
Set DDRAM address 0 0 1 AC6 AC5 AC4 AC3 AC2 AC1 AC0 DD RAMのアドレス(カーソル位置)をセットします。以後DD RAMへのデータアクセスとなる。
Write data to RAM 1 0 D7 D6 D5 D4 D3 D2 D1 D0 CG RAM, DD RAMへのデータWrite
Read data from RAM 1 1 D7 D6 D5 D4 D3 D2 D1 D0 CG RAM, DD RAMからのデータ読出し
Read Busy flag and address 0 1 BF AC6 AC5 AC4 AC3 AC2 AC1 AC0 Busy flag, カレントDD ROM/CG ROMアドレスの読出し
BF=1:Busy,BF=0:Idle
0us

xは未使用ビットを示す。
(実行時間)はFosc=250KHzの時の値。三共社製、セイコー製がこのタイプのようです。

タイミングチャート

どのメーカーも同様のようです。三共社のものが解りやすいので、以下に示します。

Write

Write Timing
キャラクター 記号 Min Typ Max 単位
Eサイクル時間 to 1200 - - ns
E立上り/立下り時間 tr,tf - - 25
Eパルス幅(High,Low) tw 140 - -
R/WとRSセットアップ時間 tsu1 0 - -
R/WとRSホールド時間 th1 10 - -
データセットアップ時間 tsu2 40 - -
データホールド時間 th2 10 - -

Read

Read Timing
キャラクター 記号 Min Typ Max 単位
Eサイクル時間 to 1200 - - ns
E立上り/立下り時間 tr,tf - - 25
Eパルス幅(High,Low) tw 140 - -
R/WとRSセットアップ時間 tsu 0 - -
R/WとRSホールド時間 th 10 - -
データ遅延時間 tD - - 100
データホールド時間 tDH 10 - -

アドレスカウンタのインクリメント

Address Counter Update Timing

BFが0になった後、アドレスカウンタの自動インクリメントには6us程度の遅延時間(TAdd)があるので、直ちに次の書込を行う場合は注意が必要です。

初期化処理

以下にインストラクションによる初期可処理を示します。

HD44780のマニュアルによると電源条件を満せば自動初期化が可能な ようですが、三共社以外マニュアルに記載が見付かりません。外付け回路に依存するため、 SUNLIKEや他の互換品で利用できるか不明です。

最初のFunction setの後の待ち時間を忘れがちなので注意しましょう。
Display offについては、on/off何れでもよいようです。

8bitモード

initialization with 8 bit mode

4bitモード

initialization with 4 bit mode

PICとの接続

設計のポイント

基本的な使用方法

転送モード

4bitモードと8bitモードが選択できます。4bitモードでは接続ピン数が少くなる一方で、 1 byte送るのに2回にわけなければならないので、転送に要する時間やプログラムの ステップ数は増加します。元々、高速に転送出来るデバイスではないので、ピン数の節約 の方が優先されるケースが殆どのようです。

空きピンは特に必要がない限り、オープンにしておきます。このあたりはマニュアルに 記載されてなかったりしますが、HD44780のマニュアルではopenとなっています。

このページで示したH/W、S/Wの何れも、4bitモードを想定して作成していますが、8bit モードの方が制御は簡単なので、応用は容易だと思います。

Busy flagチェック

メリットとしては、BFをチェックする事で、待時間を幾らか短くしたり、別の処理を 行ってからチェックすることで時間を有効に使う事ができます。
ただし、最大命令実行時間に対し、劇的に短くなるとは思えませんし、予め時間が判って いる別の処理ならば、待時間に行わせる事は可能なので、大きなアドバンテージはなさ そうです。

一方、デメリットとしては、処理が複雑になることがあげられます。
また、LCDモジュール側の故障でBFが0にならないケースで、処理系のデッドロックを防止 するためにはタイムアウトを設ける必要があります。

BFをチェックしない場合は、waitを入れるだけでよいので、処理時間が重要視される 処理で無い場合は処理が簡単になります。さらに、もし一切Readを行わないのであれば、 マイコンとの接続数を減らすこともできます。

R/W pin

上記でのべたとおり、Readを行わない場合、プルダウンする事により、接続ピン数を 減らす事ができるが、改行や画面スクロールなどを実装する場合、ソフトウェアで カーソル位置を管理するより、LCDモジュールのアドレスカウンタを利用する方が簡単で 確実です。EやRSの分を考えると、1 Port(8 Pin)全てをLCD用に割当ててしまうケースが 多いので、R/Wを用いて自動改行などを実装するのは、悪い考えではないと思います。

実行時間

他社製品との互換牲を考えると、実行時間の長いほうに合せておけばよいので、Display clearとReturn Homeが1.62ms、それ以外は40us以上掛ると想定しておくのが良いでしょう。
仕様書をみると、FsocのMINは190kHzとなっているので、個体差や環境によっては1.4倍位 の実行時間になる可能性も無いとは言いきれませんが、特に問題が出たことがないので、 可能性を知っておけば十分でしょう。

インストラクションの処理時間が入るため、Writeサイクル(tc)が1.2usを切ってしまうことはあまりないと思います。

EのPositive Pulse幅(tw)を140ns以上確保する為には、4 clock cycleのPICでは28.5MHzを超えるとwaitを入れる必要があるかもしれません。
その他の100ns以下のdelayは2 clock sycleで20MBを超えるなど、よほど高速なPICでない限り気にする必要はないはずです。

Busy flag を用いたWrite場合はアドレスカウンタのインクリメントについては配慮する必要があります。

回路

test circuit

典型的な構成です。R/W pinはGNDに落し、Write専用としています。

プログラミング

ライブラリ

XC8用にライブラリも書き直したので、合せて公開します(サンプルソースに同梱しています)。変更して使っていただいてもよいですし、実装やサンプルプログラムが参考になれば幸いです。

セットアップ

lcd4.hに若干の変更が必要です。
周波数とポートの設定です。bit操作が必要部分をうまい事自動で設定されると良いのですが、旨い方法が見付かりませんでした。

// CONFIG
#define _XTAL_FREQ      10000000      // clock frequency in Hz
#define LCD4_PORT       PORTB         // output port
#define LCD4_CONFIGREG  TRISB         // config register for the output port
#define LCD4_E          PORTBbits.RB0 // output port which is connected E
#define LCD4_RS         PORTBbits.RB1 // output port which is connected RS

Init_LCD3(void);

LCDをコマンドを用いて4bit modeに初期化します。引数は不要です。

Clr_LCD4;

LCDをクリアします。0x01を書き込んだ後、2ms waitします。

MoveHome_LCD4;

カーソルをホームポジションへ移動します。0x02を書き込んだ後、2ms waitします。

Putc_LCD4(unsigned char);

キャラクタを出力します。引数にキャラクタコードを指定します。

Cmd_LCD4(unsigned char);

任意のコマンドをWriteします。引数にコマンドを指定します。実行後40us waitします。
代表的なコマンドはlcd4.hに定義してあるので、マクロ変数で引数を指定するとわかりやすいです。

Puts_LCD4(unsigned char *);

文字列を出力します。引数に文字列の開始ポインタを指定します。文字はNULLでターミネートされている必要があります。よって、CG RAM(0)は含めることができません。

Shift_L; Shift_R; Shift_LN(int n); Shift_RN(int n);

表示範囲を左/右に1文字、あるいはn文字シフトします。

Cursor_L; Cursor_R; Cursor_LN(int); Cursor_RN(int);

カーソルを左/右に1文字、あるいはn文字移動します。

Set_DDA(unsigned char);

カーソルを任意の位置に移動します。引数にDD RAMアドレスを指定します。以降のアクセスは指定したDD RAMアドレスに行われます。

Set_CGA(unsigned char);

CG RAMアドレスを設定します。以降のアクセスは指定したCG RAMアドレスに行われます。

CGRAM_LCD4(unsigned char, unsigned char *);

メモリ上のデータを用いてCG RAMにユーザー定義文字をセットします。引数には、キャラクタコードとデータの開始アドレスを指定します。データは8bytesの連続領域に置かれている必要があります。

ROM2CGRAM(unsigned char, unsigned char);

EEPROM上のデータを用いてCG RAMにユーザー定義文字をセットします。引数には、キャラクタコードとデータの開始EEPROMアドレスを指定します。データはあらかじめ8bytesの連続EEPROM領域に書き込んでおく必要があります。

サンプルプログラム

文字列の出力、shiftによる表示範囲の移動、CG RAMへのキャラクタパターンのWriteとそれを用いた表示を行います。

キャラクタ、文字列出力

putch()にキャラクタ出力関数を定義することで、printf()などの標準出力関数が使用できるようになりますので、printfを用いて文字列をDDRAMに書き込んでいます。
printfは便利な関数ですが、プログラムメモリを食うので、メモリが小さいPICでは厳しいものがあります。

表示シフト

表示範囲を1文字ずつ左右にシフトさせることにより、表示をスクロールさせています。

CG RAMの使いかた

サンプルプログラムでは、EEPROMに保存されているデータから、CGRAMへキャラクタをセットしています。バーグラフを表示するために、5種類のキャラクタをセットしています。
80までの数値と横に80 dotのバーグラフを表示します。全て黒で塗りつぶされているキャラクタは、0xffが使えるので、5の倍数で余りが出る場合のみユーザーキャラクタを表示します。数値の表示にprintfを使うとプログラムメモリに収まりきらなかったので、数値を文字列に変換するサブルーチンを使っています。

トラブルシュート

タイミング

多くの場合、必要な待ち時間が確保されていないなど、タイミングissueが多いと思われます、シュミレーター等でタイミングを確認することをお勧めします。

初期化失敗時の挙動

初期化に失敗した場合でも、文字化けした出力が出る場合があるので、そのような場合は初期化の失敗を疑って下さい。

全く出力しない

電源の逆接、ピン番号が逆になっている場合、コントラスト調整の不具合が疑われます。

参考資料

日立 HD44780U仕様書
SUNLIKE SC1602B仕様書
三共社 L1672DJ000仕様書
三共社 アプリケーションノート