[トップページへ戻る]

デバッグ支援 1行表示ディスプレイ S-10551D

2009年9月 ※2013/03 ページデザイン変更
LCDモジュールネタが続きます。SD1602(16文字x2行)は様々な用途に対応できるLCDモジュールですが、若干高価です。
これより情報量が少ない8文字x2行や16文字x1行の安価なLCDモジュールもあります。用途を限ればこれでも十分役目を果たせます。
というわけで、デバッグサポート用にシンプルなディスプレイが欲しくなったので、安価なS-10551D(16文字x1行)を使ってシリアル制御のディスプレイを製作しました。

このページではLCDモジュールS-10551Dを紹介します。
製作したディスプレイの回路図や制御プログラム、表示用のライブラリを公開します。


S-10551Dの特徴
秋月で売っている16文字x1行のLCDモジュールです。バックライトはありません。
コントローラはHD44780A00(U)です。お馴染みのLCDモジュールSD1602などと同様です。
写真では表面保護のビニールが貼り付いていますが、造作なく剥がせます。


ピン配列もSD1602と同じなので単純に差し替えて使うことができ、制御ソフトもそのまま使えます。
ただし、ピンの並び順の関係で取り付け方向が逆さまになります。


この写真で気付いたかもしれませんが、実はS-10551Dの中身は16文字x1行ではなく、8文字x2行です。

SD1602のDDRAMアドレス(16進数表記)
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

S-10551DのDDRAMアドレス(16進数表記)
00 01 02 03 04 05 06 07 40 41 42 43 44 45 46 47


使い方のコツ
S-10551D用に文字列表示の関数を組む場合、16文字x1行のように見せるには、文字数をカウントして8文字目の位置をまたぐときにDDRAMアドレスを0x40にセットするコマンドを実行する必要があります。さもなくば8文字x2行のディスプレイだと割り切って使います。
「時刻と温度の表示計」のような、もともと短い文字列を並べて表示する使い方が向いています。それがこのLCDモジュールの本来の使い方かもしれません。
8桁あれば符号付き16ビット整数が表示できます("-32768"で最大6桁)。左側に数値を、右側に単位などを表示すれば、デバッグ用ディスプレイとして活躍してくれそうです。


デバッグ用ディスプレイの製作
S-10551Dでデバッグ用ディスプレイを製作しました。今後、マイコン工作で使っていこうと思います。

回路図


LCDモジュールの制御にはATtiny2313を使っています。回路は単純です。
  • シリアル通信で受信するためのRXD端子がある。未使用だがTXD端子も出ている。
  • 通信速度を決めるジャンパースイッチ。
    ※撮影後にプログラムを変更したのでラベル表記と実際の設定値は異なります。しかも24は書き損ねで、本当は48と書くところです。
  • コントラスト(文字の濃さ)調節用の半固定抵抗。
  • 電源ランプ(LED)。


LCDモジュールはソケットに抜き差しできるようにしてあります。SD1602も挿せます。先述の通り逆向きの取り付けになるので、正位置で読むには基板全体を逆向きに置いて使うことになります。


このLCDモジュールをソケットに挿せるようにするには工夫が必要です。SD1602の場合はスルーホールになっていてピンヘッダを部品面/ハンダ面どちら向きにもハンダ付けできましたが、S-10551Dはハンダ面にしかランドがないので、ピンヘッダの頭をハンダ面から差し込んでも部品面でハンダ付けできません。
L型ピンヘッダを付けて上辺方向からL型ピンソケットで受けるようにするか、リボンケーブルを付けて背面へ回すかと考えましたが、いずれも基板との接続がスマートにキマリません。


結局、普通のピンヘッダを強引に付けました。ピンヘッダの根元を押し出し、LCDモジュールの部品側からはめてハンダ付けします。押し出した長さ以内(2〜3mm)でハンダ付けすれば、ピンソケットに奥まで挿しても干渉しません。これでブレッドボードにも挿せるようになりました。製作中、便利でした。



制御プログラムと表示用ライブラリ
ダウンロード
LCDモジュール制御プログラム→ここをクリック (LCD16x1_v090.zip)
表示ライブラリ→ここをクリック (printlib_v100.zip)

このディスプレイは、何かを開発中(製作中)のマイコンから表示位置指定のコマンドやデバッグ情報である数値や文字列のデータを受け取り、画面に表示します。受信専用です。送信側は lprint(-2468); lprints("START!!"); などとデータを送ります。

制御プログラムの説明
ディスプレイ基板上のATtiny2313に lcd16x1.hex を書き込んでください。
この制御プログラムは次のような動作をしています。
  • 起動時にLCDモジュールを初期化し、通信速度を設定するピン入力を読み、決定します。
  • その後、シリアル通信の受信待ちをするループに入ります。
  • コマンドとデータを受信したら解釈し、実行します。
表示することに特化してシンプルな機能にしています。拡張するならこんなアイデアがあります。
  • 直近20〜30個のデータをメモリ上に持っておき、後から見られるようにする。
    またはEEPROMに保存してオフラインでも見られるようにする。
  • スイッチを付けて、押してる間は表示を更新しないようにする(データは受信し続ける)。
    表示が速すぎて見づらいときに、表示のみ一時停止できるようにするということ。
この手のシリアル制御ディスプレイで情報を表示させるには、通常はコマンドもデータも文字として送信します。受信側はコマンドとデータを判別し、データなら受信内容をそのまま表示すればよいことになります。数値も1桁ずつ文字'0'〜'9'として送られてくるからです。一方、送信側は数値を1桁ずつに分解しなければならないので負担がかかります。ライブラリのサイズも増大します。
また、文字にすると送信するデータ量が増えます。16ビット整数は(当たり前ですが)値によらず2byteのデータ量です。これを文字にすると最大6byteのデータ量になります(-10000〜-32768のとき → 例:{ '-', '3', '2', '7', '6', '8' } )。受信側でバッファを用意するなら、そちらも容量がかさみます。
手短に送信したいことと、送信側の処理の負担を減らしたいことで、このディスプレイでは数値は数値のまま送信するようにしました。これが吉と出るか凶と出るか、使ってみないと分かりませんが。
※【後日追記】そりゃ凶と出ます。受信側からしてみれば、数値データなのか制御コードなのか区別が付かないわけで。
 シリアルポート通信の基本を忘れていました。


受信処理に割り込みを使用していません。受信バッファはデータ1個分しか持っていません。送信側とのタイミングが合わなければデータの取りこぼしが続発するでしょう。このディスプレイ、作ったもののまだ開発作業で活用していません。まずはこのソフトでスタートして、実際に使用しながら仕上げていくことにします。
それゆえ ver 0.90 としてリリースします。ただしバージョンアップしてもここに掲載しないかもしれません。これを使ってくれというよりも、これを参考にして利用者が好き好きに作ればよいと思っています。

表示ライブラリの説明
lprintInit() ディスプレイを初期化する。
他のlprint関数に先立って実行すること。
lprintCls() ディスプレイの表示を消去する。
実行完了に5msかかる。
lprintSetPos(uint8_t x) 表示位置を指定する。
0 <= x <= 7 または 0x40 <= x <= 0x47 であること。
定数 LCD_PRINT_HALF_POS (0x40 …9文字目の位置) が使える。
→例:12文字目の位置に表示する
→lprintSetPos(LCD_PRINT_HALF_POS + 3);

一度表示位置を設定すると、以降の
lprint8(), lprintU8(), lprint16(), lprintU16(), lprints()
は全てこの表示位置に従う。
lprint8(int8_t n) 符号付き8ビット整数を出力する。
lprintU8(uint8_t n) 符号なし8ビット整数を出力する。
lprint16(int16_t n) 符号付き16ビット整数を出力する。
lprintU16(uint16_t n) 符号なし16ビット整数を出力する。
lprintc(char c) 文字を出力する。
連続して文字を出力する場合、1文字目はlprintSetPos()で設定した位置に表示され、
2文字目以降は右隣へ続けて表示される。
lprints(char* s) ヌル終端文字列を出力する。
文字列の長さは 0 <= strlen(s) <= 8 となる長さであること
(ヌルを含まない部分が0文字以上8文字以下であること)。
lprint(n) lprint8(n) または lprint16(n) の別名定義。ユーザー任意で書き換える。
・簡素な記述にするため、頻繁に使う方を置き換える。
・サイズ削減のため片方を削除し、残った方を置き換える。
lprintu(n) lprintU8(n) または lprintU16(n) の別名定義。ユーザー任意で書き換える。
・簡素な記述にするため、頻繁に使う方を置き換える。
・サイズ削減のため片方を削除し、残った方を置き換える。

printlib.h
表示ライブラリのヘッダファイルです。送信側のマイコンでプログラムに#includeしてください。
#defineで関数名の読み替えをしています。都合に合わせて書き換えても構いません。

printlib.c
表示ライブラリの本体です。先頭付近でボーレート(通信速度)を#defineしているので適宜書き換えてください。初期化関数の引数にするより、プログラムサイズ節約の点で有利です(コンパイル時に値が確定するので)。

AVR Studioのコンフィグ設定内のFrequency、またはWinAVRのmakeの引数でCPU動作クロック(F_CPU)を定義してください。
  • lprintInit()内でボーレートを決定する際にF_CPUの値を使っています。
  • lprintCls()内で_delay_ms()を使っているのでF_CPUの記述が必要です。
このライブラリを使うと、もちろんプログラムのサイズが増大します。プログラム容量に余裕がないときは、使わない関数の定義を削除(コメントアウト)するなどしてサイズを減らしてください。極端な例ですが、lprintInit(), lprint16() の2つに絞って利用することも考えられます。
※lprintSetPos()の定義が2通りあるのは軽量化の試行錯誤をした痕跡です。コメントアウトして一応残しておきます。
 printlibLcdPrint1()と掛かる関数を削除したとき、lprintSetPos()だけは必要だったのでマクロから関数に変更した、という状況でした。


注意
lprintCls()は時間がかかる処理です。LCDモジュールのClearDisplayコマンドを呼び出しており、これがもともと4ms弱かかる処理です。送信側プログラムの中で、時間待ちが動作に影響する場所ではlprintCls()を実行しないでください。

テストプログラムについて
表示ライブラリのzipファイルに表示デモ用のlprinttest.cを同梱しています。
まずprintlib.cのLCD_PRINT_BAUD_RATE(通信速度)を適宜変更します。
次にlprinttest.cのF_CPUの値を書き換えて(またはAVR Studioのコンフィグ設定やWinAVRのmakeで指定して)ビルドし、lprinttest.hexを適当なAVRに書き込んで、TXDピンをディスプレイのRXDピンに接続します。
そしてディスプレイの通信速度の設定を適宜変更します(ジャンパースイッチ)。
以上の準備ができたらディスプレイの電源を入れ、次に送信側のAVRの電源を入れます。
すると直ちに、ディスプレイに数値や文字列が表示されます。
何も表示されない場合や繰り返し見るときは、送信側もディスプレイも電源の接続状態はそのままで、送信側のAVRをリセットしてください。
このテストプログラムは ATtiny2313 1MHz、通信速度4800bps で正常動作を確認しました。

ハードウェア面の説明
送信元はTXDピンを空ける
ディスプレイの表示にはシリアル通信を使うため、送信側のマイコンはTXDピンを空ける必要があります。ライブラリは、送信役を任意のピンに割り当てられるようには作られていません。送信側のマイコンがATtiny2313(プログラム領域が2KBと小さい)でも使えるよう、ライブラリのサイズを小さくするためソフトウェアUSERTは実装していません。

ディスプレイの通信速度を設定する
出力側のマイコンが安定して出せる通信速度に、ディスプレイの通信速度を合わせます。ディスプレイ側のATtiny2313は8MHzで動いており、最高速度38400bpsとしています。
ジャンパースイッチで4つの速度を切り替えます。電源投入時/リセット時に設定を読みます。
下図で「・」はピンヘッダを、「==」はジャンパーピンを表します(2つのピンヘッダをショートする)。
38400bps
PA0とGNDをショート
19200bps
PA1とGNDをショート
9600bps
PA0とPA1をショート
4800bps
GND同士をショート
GND・・PA1
GND==PA0
GND==PA1
GND・・PA0
GND・||PA1
GND・||PA0
GND||・PA1
GND||・PA0
4800bpsではGND同士をショートしていますが、これはジャンパーピンを挿さない状態と同じです。ジャンパーピンを無くしても、最低速であれば送信元のマイコンが通信速度を合わせられるだろう、というつもりなのですが、まぁ、ジャンパーピンを無くさないようここに挿しておこう、くらいで。

ディスプレイの電源を先に入れる
送信元のマイコンより先にディスプレイの電源を入れてください。送信元がlprintInit()を実行する前にディスプレイの受信準備をしておくためです。
ディスプレイはRXDをGNDに接続して電源を入れると、ジャンパースイッチで設定した通信速度を表示します。目的の設定ができているか確認してください。

オマケのデバッグ補助具
単なるLEDアレイです。点灯パターンを見てポートの出力状態を確認できます。
LEDアレイはICソケットに刺さっているので、向きを変えてソース電流/シンク電流どちらにも使えます。


こんなものに回路図も何もあったもんじゃないですが一応掲載しておきます。


部品について
本当のところ、S-10551Dありきでこの製作はスタートしました。秋月のサイトを眺めていて、「安いLCDモジュールはどれだろう? これか、16文字x1行か、何に使おうか? よし、デバッグ用ディスプレイを作ろう!」

せっかくS-10551Dが安価なので、全体的にシンプルに安価に製作しています。LCDモジュール以外は既に部品箱に入っていると思います。


デバッグ用ディスプレイ 部品一覧 (回路図はここをクリック
部品名 部品番号 個数 参考価格/備考
AVR(マイコン) U ATtiny2313 1 100円(秋月電子
LCDモジュール
キャラクタ液晶
LCD S-10551D 1 300円(秋月電子)
積層セラミックコンデンサ C 0.1uF [104] 1 10個100円
半固定抵抗 VR 10kΩ 1 1個30円
ピンヘッダ JMP 2x2ピン 1 ジャンパースイッチとして
ピンヘッダ -- 14ピン 1 40ピン50円/折って使う
S-10551Dに付ける
ジャンパーピン (JMP) -- 1 10個60円
ピンソケット -- 14ピン 1 1個50円/S-10551Dを挿す


◆ ◆ ◆
これからの開発に活かすためのデバッグ用ディスプレイを製作しました。
ライブラリの開発時にこれ自身が活躍しました。


(C) 『昼夜逆転』工作室 [トップページへ戻る]
inserted by FC2 system