NETMF : GPIO 接続のキャラクターディスプレイの使い方と、GR ファミリー用クラスライブラリへの追加

前の記事 で GR ファミリーの Arduino 互換ピンの定義を紹介しました。
そこでのサンプルは GR-PEACH、GR-SAKURA の LED とボタンとを使いましたが、もちろん Arduino 互換ピンを含む、他の GPIO ポートでも同じ使い方ができます。

今回のテーマは、GPIO 接続のキャラクター液晶ディスプレイ (CLCD = Charactor Liquid Crystal Display) のプログラミングです。
なおすでに公開している GR ファミリー用のクラスライブラリ には、本稿で紹介する CLCD の機能を実装しています。本稿で GPIO や CLCD の背景を理解したあとは、クラスライブラリを使って簡単にプログラミングを楽しんでください。
(難しくはないのですが、初期化も文字出力も面倒です)


■ (復習) .NET Micro Framework の GPIO

.NET Micro Framework の GPIO は以下のクラスが対応しています。

デジタル出力 OutputPort OutputPort(<ポート番号>, <出力の初期値>);
デジタル入力 InputPort InputPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>);
デジタル出力 (値変更時のイベント発行付き) InterruptPort InterruptPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>, <イベント対象の方向>);

■ キャラクター液晶ディスプレイモジュールのプログラミングモデル

市販されているほとんどの CLCD は HD44780 互換のプログラミングモデルを採用しています。
つまり HD44780 の仕様を理解すれば、デバイスごとに仕様を覚える必要はないということです。
市販のモジュールは物理的なサイズ、色などいろいろな種類があるので、好みにあわせてハードウェアを選択できます。

HD44780 については、こちらのページ の解説が分かりやすいと思います。
またモジュールを買うと付いてくるデータシート(Web 上でも公開されていると思います) でも同様の解説が載っていると思います。

ポイントは、ビットモード制御命令、それにモジュールの初期化手順です。

  • ビットモード・・・HD44780 では、8ビットモードまたは4ビットモードを選択して使用します。8ビットモードは、データ用の GPIO が8個必要です。(他に、コントロール用に2個または3個の GPIO が必要です)
    Arduino 互換ピンは数が少ないので、CLCD への表示データだけで8個のピンを使うのはあまりうれしくないです。
    今回は、ライブラリでは4ビットモードだけ実装しています。
  • 制御命令・・・表示クリア、カーソル移動、表示オン・オフなどの制御命令が決まっています。
  • 初期化手順・・・CLCD の初期化手順は意外と面倒です。4ビットモードでは12回のデータ送信が必要です。こちらのページ やデータシートなどで確認してみてください。

制御命令や表示データをモジュールに送信するには、

  1. 制御命令の場合は RS ピン (Register Select) の信号レベルを L にする、文字コード出力時は RS ピンの信号レベルを H にする
  2. E ピン (Enable) の信号レベルを H にする
  3. D4~D7 ピンに送信したいレベルの信号を設定する(4ビットモードの場合)
  4. E ピンの信号レベルを L にする
  5. (文字コード出力の場合) 手順 1~4 を D0~D3 ピンに対しても実行する

という手順を踏みます。なお制御命令によっては次の制御命令を送る前にミリ秒程度の待ち時間が必要なものもあります。


■ 実際のコード例 (抜粋)

実際のコードのポイントを紹介します。
データシートなどと対比しながら読むと、実際にどの制御命令をどの順番で送信しているかが分かると思います。
なお動作する完全なコードは、クラスライブラリのソースコードを参照してください。

制御コマンド送信

private void WriteCommand(bool db7, bool db6, bool db5, bool db4, int wait = 1)
{
    _pinRs.Write(false);

    _pinEnable.Write(true);
    _pinDb7.Write(db7);
    _pinDb6.Write(db6);
    _pinDb5.Write(db5);
    _pinDb4.Write(db4);

    _pinEnable.Write(false);
    Thread.Sleep(wait);
}

初期化

public void InitDevice(int wait = 0)
{
    Thread.Sleep(1000);

    WriteCommand(false, false, true, true, wait + 5);       // 8ビットモードにセット + 5msウェイト
    WriteCommand(false, false, true, true, wait);           // 8ビットモードにセット
    WriteCommand(false, false, true, true, wait);           // 8ビットモードにセット (2回目)
    WriteCommand(false, false, true, false, wait);          // 4ビットモードにセット
    WriteCommand(false, false, true, false, wait);          // 行数とフォントの設定1
    WriteCommand(true, false, false, false, wait);          // 行数とフォントの設定2
    WriteCommand(false, false, false, false, wait);         // 表示をオフ1
    WriteCommand(true, false, false, false, wait);          // 表示をオフ2
    WriteCommand(false, false, false, false, wait);         // 表示データをクリア1
    WriteCommand(false, false, false, true, wait);          // 表示データをクリア2
    WriteCommand(false, false, false, false, wait);         // カーソルと表示のシフト設定1
    WriteCommand(false, true, true, false, wait);           // カーソルと表示のシフト設定2
    WriteCommand(false, false, false, false, wait);             // 表示をオン1
    WriteCommand(true, _displayOn, _cursorOn, _blinkOn, wait);  // 表示をオン2

    _commandWait = wait;

    Thread.Sleep(100);
}

文字コード出力

public void Write(byte data)
{
    _pinRs.Write(true);

    _pinEnable.Write(true);
    _pinDb7.Write((data &amp;amp; 0x80) != 0);
    _pinDb6.Write((data &amp;amp; 0x40) != 0);
    _pinDb5.Write((data &amp;amp; 0x20) != 0);
    _pinDb4.Write((data &amp;amp; 0x10) != 0);
    _pinEnable.Write(false);

    _pinEnable.Write(true);
    _pinDb7.Write((data &amp;amp; 0x08) != 0);
    _pinDb6.Write((data &amp;amp; 0x04) != 0);
    _pinDb5.Write((data &amp;amp; 0x02) != 0);
    _pinDb4.Write((data &amp;amp; 0x01) != 0);
    _pinEnable.Write(false);
}

文字列送信

public void Print(string msg)
{
    for (var i = 0; i < msg.Length; i++)
    {
        Write((byte)msg[i]);
    }
}

■ クラスライブラリの実行結果

クラスライブラリは汎用にしたので、GR-PEACH でも GR-SAKURA でも同じコードが動作します。

WP_20151011_003WP_20151011_002

また別の CLCD モジュールに対しても同じコードが動作します。
なお、プログラミングモデルは同一でも、モジュールによって物理的なピン配置が異なる(例えば下の CLCD モジュールでは、ピン配置が 15, 16, 1, 2, …, 13, 14 と並んでいます)、給電は 3.3Vか 5V か異なる、などに注意が必要です。
(私はこれでハマって、文字列を表示してくれないことにしばらく悩みました)

WP_20151011_001

上記の写真の CLCD モジュールとマイコンボードや VR との接続は以下を参考にしてください。

CLCD_CircuitCLCD_Pins

NETMF : GPIO 接続のキャラクターディスプレイの使い方と、GR ファミリー用クラスライブラリへの追加」への1件のフィードバック

コメントを残す