2009年7月
マイコン工作でLチカと並ぶポピュラーなテーマ、LCDモジュールの駆動。
キャラクタLCDを操作するライブラリはいくつも公開されており、サンプルコードも豊富なので何かを表示させること自体はすぐにできるでしょう。
これを使ってセンサーの値を表示するもよし。デバッグ出力に使うもよし。ここでは応用例としてカレンダー付き時計を紹介します。
回路図とプログラムのソースを公開しています。
そして意外と知られていない(?)「外字登録」…ユーザー定義文字の設定方法を説明します。時計作りよりもこちらが主題です。
※2012/03 記事を改訂。
※2019/04 記事を改訂。プログラムを更新(「令和」に対応)。
本工作では秋月電子通商(以下、秋月)で販売されている「SD1602HUOB(-XA-G-R)」を使いました。16文字×2行、バックライト付き小型LCDモジュールです。
キャラクタLCDモジュールには、SUNLIKE社のSC1602A や
Xiamen Ocular Optics社のGDM1602K など様々な製品がありますが、
どれもHD44780互換コントローラなので同じ制御プログラムが使えます。
→HD44780のデータシートを検索
これらのLCDモジュールは制御線3本の他に、8bitまたは4bitのデータ線でコマンドやデータを送受信します。
以下、この記事では4bitモードで作業したことを書いています。
データ線も8本中4本のみ配線した状態です。マイコンはATtiny2313(内蔵発振器1MHz動作)を使用しています。
制御ライブラリを用意する
キャラクタLCD用のライブラリは「lcdlib.c」「lcd_lib.c」などで検索するといくつも見つかります。
「これがスタンダードだ」というものはなく、勉強がてら自作するのも一興です。
ライブラリを自作するならタイミングに注意
データシートを確認し、信号送出のタイミング(マイクロ秒、ミリ秒単位の時間)さえ守れば制御プログラムは動きます。この点が重要です。
回数を決めて空ループで時間待ちをするプログラムだと、マイコンの動作クロックによって待ち時間が変わってしまいます。
そのようなプログラムではマイコンが1MHz動作のときは表示できても20MHzでは表示できない、ということも起こります。
このため、AVRなら _delay_us(), _delay_ms()を使うのがよいと思います。
そもそも、コントローラから通知されるBusyFlagを監視するのが真っ当な制御方法です。
まぁそうなのですが、その都度マイコンのI/Oを制御するのが面倒だし、
LCDモジュールからの読み込み処理を無くせばR/Wレジスタの制御を省略できるので(GND接続してWrite固定)、
BusyFlagを使わない方法(一定時間待つ方法)で済ませることが多いようです。
初期化の注意点
初期化シーケンスはLCDモジュールのデータシートに書いてあります。
その中で、待ち時間が「100 s」とあったら「100us」の誤記です(PDF化のときに'μ'が消えたのでしょう)。
初期化シーケンスではデータ線のDB7~DB4に0011を3回送出しています。
これは、LCD内部状態が現在8bitモードか4bitモードか不定であるとして、配線が4bit線か8bit線かによらず一旦8bitモードにしていることになります。
LCDモジュールを4bitモードで使用する場合は、ここでさらに0010を送出して4bitモードへ移行させます。
その後、表示動作を設定します。
さて、秋月でLCDモジュールを購入すると独自編集のデータシートが付いてきます。
その設定内容に従って文字表示をテストすると… SD1602には何も表示されません。実は説明が間違っています。
キャラクタLCDモジュールにはユーザーが定義した文字を格納することができます。
RAMなので電源を切ったら定義したデータも消えてしまいますが、プログラム実行中は書き換え自由です。
一度に持てる文字数は8個です。これを活用してLCD工作の応用範囲を広げましょう!
ユーザー定義文字の文字コード
文字コード0x00~0x07に外字が登録できます。図の赤枠(□)の範囲です。
そこに外字を登録すると0x08~0x0F(図の灰色枠(□))にも反映されますが、
データの読み書きともこちらの文字コードを使用する必要はありません。
16文字登録できない理由は後述するSet CGRAM Addressコマンドの説明を参照してください。惜しいですが仕方ありません。
※図はデータシートより抜粋。
コマンド | RS | R/W | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | 説明 |
---|---|---|---|---|---|---|---|---|---|---|---|
Set CGRAM Address | 0 | 0 | 0 | 1 | AC5 | AC4 | AC3 | AC2 | AC1 | AC0 | アドレスカウンタに CGRAMアドレスをセットする |
ライン | ドットパターン | 2進表記 | AC5 | AC4 | AC3 | AC2 | AC1 | AC0 |
---|---|---|---|---|---|---|---|---|
0 | □■■■■ | 0b00001111 | 0 | 1 | 0 | 0 | 0 | 0 |
1 | □■□□■ | 0b00001001 | 0 | 1 | 0 | 0 | 0 | 1 |
2 | □■■■■ | 0b00001111 | 0 | 1 | 0 | 0 | 1 | 0 |
3 | □■□□■ | 0b00001001 | 0 | 1 | 0 | 0 | 1 | 1 |
4 | □■■■■ | 0b00001111 | 0 | 1 | 0 | 1 | 0 | 0 |
5 | □■□□■ | 0b00001001 | 0 | 1 | 0 | 1 | 0 | 1 |
6 | ■□□□■ | 0b00010001 | 0 | 1 | 0 | 1 | 1 | 0 |
7 | □□□□□ | 0b00000000 | 0 | 1 | 0 | 1 | 1 | 1 |
文字コード 0x02 | ライン 0~7 |
コマンド/動作 | RS | R/W | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | 説明 |
---|---|---|---|---|---|---|---|---|---|---|---|
Set CGRAM Address | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 文字コード0x02の、ライン0のアドレス |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | ライン0(1ライン目)のデータ |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | ライン1(2ライン目)のデータ |
… | … | … | … | … | … | … | … | … | … | … | … |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ライン7(8ライン目)のデータ |
コマンド/動作 | RS | R/W | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | 説明 |
---|---|---|---|---|---|---|---|---|---|---|---|
Set CGRAM Address | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 文字コード0x02の、ライン0のアドレス |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | ライン0(1ライン目)のデータ |
Set CGRAM Address | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | ライン1のアドレス |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | ライン1(2ライン目)のデータ |
… | … | … | … | … | … | … | … | … | … | … | … |
… | … | … | … | … | … | … | … | … | … | … | … |
Set CGRAM Address | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | ライン7のアドレス |
Write Data to RAM | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ライン7(8ライン目)のデータ |
マイコンはATtiny2313(内蔵発振器1MHz動作)。正確な時間は刻めませんが作例としては十分です。
カレンダーは西暦/元号の切り替え対応。時計は24時間制/12時間制の切り替え対応。組み合わせで4通りの表示方法を選べます。
回路図
文字コード | 字形 | 説明 |
---|---|---|
0x00 | 年 | |
0x01 | 月 | |
0x02 | 日 | |
0x03 | (曜日) | 月,火,水,木,金,土,日 |
0x04 | 令 | 平→令に変更 |
0x05 | 和 | 成→和に変更 |
0x06 | A M | 5x8の領域で縦にAとM |
0x07 | P M | 5x8の領域で縦にPとM |
電源投入で下記のように表示されます。時計は動いています。この状態が「表示モード」です。
LCDモジュールはお好みで選んで構いません。端子の並び順に注意して配線してください。
【2019/04】 価格は2009年当時のものです。
部品名 | 部品番号 | 値 | 個数 | 参考価格/備考 |
---|---|---|---|---|
AVR(マイコン) | U | ATtiny2313 | 1 | 100円(秋月) |
LCDモジュール キャラクタ液晶 |
LCD | SD1602HUOB (-XA-G-R) |
1 | 900円(秋月) バックライト:オレンジ |
抵抗 | R1 | 20~100Ω | 1 | 上記LCDには100Ωが数個、 オマケで入っています |
半固定抵抗 | VR1 | 10kΩ | 1 | 30円 |
積層セラミックコンデンサ | C1 | 0.1uF [104] | 1 | 10個100円 |
タクトスイッチ | SW1,SW2 | -- | 2 | 10個180円(千石電商 店頭価格) |
LCDモジュールは外字登録のやり方が分かると面白くなってきます。
デバッグ出力に使うだけではもったいないですね。レベルメーターのバー表示もやってみましたが、
同じネタばかりになるのでカレンダー付き時計を作りました。
ここでは紹介しませんが、電光掲示板のように文字列がサーッと流れて行くようにもできます。
それはソフトで意識せずともハードでやってくれます。便利。
光り物好きとしてはバックライトや液晶の色違いをいくつか試してみたくもなります。綺麗。