Lcdクラス

LCDを操作するプログラムを書こうとする人がLCDを操作するときLcdクラスのインスタンスを用います.このにはLCDへ送受信するクラスのインスタンスがあり,それらを使ってLCDへコマンドを送受信することができます.LCDを操作するときに用いるため,多くのメンバ関数があるため実装することは一苦労ですが頑張りましょう.なお,Lcdクラスにプログラミングするとき,LcdCmdTranceiver.hppをインクルードする必要があります.Lcd.cppの冒頭で「#include "LcdCmdTranceiver.hpp"」と書いておきましょう

  1. シングルトン関連

    Lcdクラスはシングルトンになっています.従いまして,コンストラクタ,コピーコンストラクタおよび代入演算子はすべてprivateです.また,staticなgetInstance関数によりシングルトンを取得することができるようにしてあります.以前紹介したこちらを参考に,下記の関数を実装してください
    コンストラクタ,コピーコンストラクタ,代入演算子,デストラクタ,getInstance(後ほど実装する_initialize関数を呼び出すようにしてください)
  2. _initialize関数

    この関数では,LCDをセットアップするときに行ういくつかのインストラクションを行います.下の図をご覧ください.多くのコマンドを設定し,一定時間待ったのち送信することの繰り返しです.下記のとおり,順番に処理を行うプログラムを作成してください.
    Lcd initialize
  3. writeChar関数

    この関数は引数として渡すx列y行の場所に1文字表示するためのものです.文字を表示するには,DDRAMアドレスセット(_ddramAddresSetCmd)を使い,文字を表示する位置を指定し,そののち文字コード書き込み(_writeCharacterCmd)を行います.なお,それぞれのインストラクションは既にインスタンス化してあります.Lcd.hを確認してください.下の図は,処理の流れを表したものです.参考にしてプログラミングしてください
    writeChar
  4. writeString関数

    この関数は文字列をLCDに表示することができます.内部的には,引数として渡されるstringから1文字ずつ順番に取り出し,writeChar関数を使って出力していきます.下の図はwriteString関数の流れを示したものです.制御変数iをfor文で繰り返し,1文字ずつwriteChar関数へ表示したい文字パターンのコードを送ります.また,表示する位置を右側に送るため,x+iをwriteChar関数に送る必要があります.この図を参考にプログラムを作成してください
    writeString
  5.  LCDを操作するための関数群

    Lcdクラスにメンバとして存在するコマンドクラスのインスタンスを使うことで,LCDを操作することができます.下の表にあるメンバ関数はいずれもLCDを操作するためのものですので,コマンドクラスのインスタンスをうまく使いこなして実装してください.ただし,setInterfaceDataWidth関数では,LcdCmdTranceiverにもデータ幅を設定するようにしてください.また,いずれのコマンドクラスのインスタンスもLcdCmdTranceiverのtransmit関数を使って送信してください.インスタンスにただ設定しただけではLCDに送信されません
    関数名 用途
    clear 画面をクリアする
    moveCursorToHome カーソルをホームへ移動する
    setEntryDirection 挿入される文字列の進行方向を設定する
    enableShift 表示のシフトをさせる
    disableShift 表示のシフトをしない
    displayAll すべての文字を表示する
    hideAll すべての文字を非表示にする
    displayCursor カーソルを表示する
    hideCursor カーソルを隠す
    blink 点滅させる
    light 点灯させる
    setCursorDirection カーソルのシフト方向を設定する
    setMovementObject 移動対象を設定する
    setLineNum 行数を設定する
    setFont フォントを設定する
    setInterfaceDataWidth インターフェースデータ幅を設定する
  6. writeHex関数

    writeHex関数は,与えられた数値を16進数で表示するときに用いられます.この内部では1文字分の16進数を表示するプライベートな_writeHex関数を使っており,この関数を16進数の桁ごとに呼び出しています._writeHex関数については後ほど説明するとして,ここでは16進数の桁ごとに分けて_writeHex関数を呼び出す処理について説明します.
    writeHex関数には,表示するさまざまな型に対応するため,オーバロードしてあります.方によって表示する桁数が異なり,例えばunsigned short型であれば16進数で4桁(=16ビット)となります.この桁数回だけ_writeHex関数を呼び出します.最上位4ビット,つまりビット12~15を取り出すには,そのビットのみ1となっている0xF000と論理積をとり,さらに《表示する数値のビット数(16)-4=12》右シフトします.この数値を_writeHex関数に渡せばよいのです.同様に,ビット8~11を取り出すには,0x0F00と論理和をとり,《表示する数値のビット数(16)-8=8》右シフトします.
    以上のように,各桁を取り出し,_writeHex関数を呼び出すようにしてください.下図はunsigned short の数値であるvalueを列x,行yに表示するwriteHex関数の流れ図を表しています._writeHex関数には3個の引数があり,第1引数に表示する数値,第2引数に列,第3引数に行があります.この関数を使って下記のようなプログラムを作成してください.さらに,writeHex関数の第1引数の型がunsigned charのもの,unsigned intのもの,unsigned long longのものも実装してください.
    writeHex
  7. _writeHex関数

    この関数では1文字分の16進数の数値,すなわち0~Fまでを表示します.表示する”数値”と言っていますが,その実は0~9までの"数値"と,A~Fまでの"文字"が混在しています.そこで,数値と文字を分けて取り扱うことにします.下図は_writeHex関数で行う処理の流れを表したものです.「1文字表示する」にはwriteChar関数を使用してください.これを参考にしてプログラミングしてください.
     writeHex
  8. writeBin関数

    writeBin関数でも内部では_writeBin関数を使っています.ただし,_writeHex関数のように1文字ずつ表示するのではなく,_writeBin関数では4文字ずつ,つまり4ビットずつ表示する仕様となっています.従いまして,writeHex関数と同じように,4ビットずつ区切りながら_writeBin関数を呼びます.下図はunsigned shortの値を2進数で表示するwriteBin関数の流れ図です.4ビットの2進数を表示するには_writeBin関数をお使いください._writeBin関数には3個の引数があり,第1引数に表示する数値,第2引数に列,第3引数に行があります.この関数を使って下記のようなプログラムを作成してください.さらに,writeBin関数の第1引数の型がunsigned charのもの,unsigned intのもの,unsigned long longのものも実装してください.
    writeBin
  9. _writeBin関数

    _writeBin関数では,staticでconstなテーブル_DEC_TO_BINを使って,引数valueを4桁の2進数に変換します.例えば,valueが3の場合,_DEC_TO_BIN[value]="0011"となりますので,この0011文字列をwriteStringで表示してください.以上のようなプログラムを記述してください.
  10. writeDec関数

    この関数では10進数の数字をLCDに表示することができます.下図ではwriteDecの処理内容を示しています.
    writeDec
    まず,表示する値valueが正数なのか負数なのか調べ,負数であったら最初に"-"を表示します.次に,下の桁から上の桁の順番でwriteCharを使い表示していきます.この処理を行う途中で桁数を得る処理が必要ですので,新たに_getDigitNum関数を作成します.一例として_getDigitNum関数を下に示します._getDigitNum関数などを使ってwriteDec関数を完成させてください.
    unsigned char Lcd::_getDigitNum(long long value){
      /* 比較対象 */
      long long tmp;
      /* 制御変数 */
      unsigned char i;
      /* 負数のとき0,0を含む正数のとき0となる変数 */
      unsigned char sign = 0;
      /* 絶対値を求める */
      if(value < 0) {
        value *= -1;
        sign = 1;
      }
      for(i=0, tmp=10; i<10; i++, tmp*=10) {
        if(tmp > value) {
          return i+sign;
        }
      }
      return 0;
    }

     

  11. setCharacterPattern関数

    この関数は,オリジナルのパターンをLCDに送信するときに用いられます.ここではプログラムを示しますのでコピーしてください.処理内容は,CGRAMのアドレスをセットしたうえでパターンを送信する,というところでしょうか.
    void Lcd::setCharacterPattern(unsigned char character_id, const LCDPattern* pattern){
      /* アドレスをインクリメントするようにする */
      _entryModeSetCmd.setDirection ( FORWARD );
      /* コマンドを送信する */
      LcdCmdTranceiver::getInstance()->transmit(&_entryModeSetCmd);
      /* アドレスを設定する */
      if(pattern->getPatternType() == W5H7) {
        _cgramAddressSetCmd.setCharacterPatternAddress(W5H7, character_id);
      }
      else if(pattern->getPatternType() == W5H10) {
        _cgramAddressSetCmd.setCharacterPatternAddress(W5H10, character_id);
      }
      /* コマンドを送信する */
      LcdCmdTranceiver::getInstance()->transmit(&_cgramAddressSetCmd);
    
      /* 幅5高さ7のパターンの場合 */
      if(pattern->getPatternType() == W5H7) {
        /* 0から7 */
        for(int y=0; y<7; y++) {
          /* パターンを設定する */
          _writeCharacterCmd.setCharacter(pattern->getRowData(y));
          /* コマンドを送信する */
          LcdCmdTranceiver::getInstance()->transmit(&_writeCharacterCmd);
        }
        /* カーソル部分は白画素にしておく */
        _writeCharacterCmd.setCharacter(0x00);
        /* コマンドを送信する */
        LcdCmdTranceiver::getInstance()->transmit(&_writeCharacterCmd);
      }
      /* 幅5高さ10のパターンの場合 */
      if(pattern->getPatternType() == W5H10) {
        for(int y=0; y<10; y++) {
          /* パターンを設定する */
          _writeCharacterCmd.setCharacter(pattern->getRowData(y));
          /* コマンドを送信する */
          LcdCmdTranceiver::getInstance()->transmit(&_writeCharacterCmd);
        }
        /* カーソル部分は白画素にしておく */
        _writeCharacterCmd.setCharacter(0x00);
        /* コマンドを送信する */
        LcdCmdTranceiver::getInstance()->transmit(&_writeCharacterCmd);
      }
    }
    

     

  12. getCharacterPattern関数

    この関数は,LCDに設定されているパターンをマイコンで取得するためのものです.ここではプログラムを示しますのでコピーしてください.
    void Lcd::getCharacterPattern(unsigned char character_id, LCDPattern* pattern){
      /* アドレスをインクリメントするようにする */
      _entryModeSetCmd.setDirection ( FORWARD );
      /* コマンドを送信する */
      LcdCmdTranceiver::getInstance()->transmit(&_entryModeSetCmd);
      /* アドレスを設定する */
      if(pattern->getPatternType() == W5H7) {
        _cgramAddressSetCmd.setCharacterPatternAddress(W5H7, character_id);
      }
      else if(pattern->getPatternType() == W5H10) {
        _cgramAddressSetCmd.setCharacterPatternAddress(W5H10, character_id);
      }
      /* コマンドを送信する */
      LcdCmdTranceiver::getInstance()->transmit(&_cgramAddressSetCmd);
    				
      /* 幅5高さ7のパターンの場合 */
      if(pattern->getPatternType() == W5H7) {
        /* 0から7 */
        for(int y=0; y<7; y++) {
          /* コマンドを受信する */
    						LcdCmdTranceiver::getInstance()->receive(&_readCharacterCmd);
          /* パターンを設定する */
          pattern->setRowData(y, _readCharacterCmd.getCharacter());
        }
        /* カーソル部分は白画素にしておく */
        pattern->setRowData(7, 0);
      }
      /* 幅5高さ10のパターンの場合 */
      if(pattern->getPatternType() == W5H10) {
        for(int y=0; y<10; y++) {
          /* コマンドを受信する */
    						LcdCmdTranceiver::getInstance()->receive(&_readCharacterCmd);
          /* パターンを設定する */
          pattern->setRowData(y,  _readCharacterCmd.getCharacter());
        }
        /* カーソル部分は白画素にしておく */
        pattern->setRowData(7, 0);
      }
    }

 以上でLcd.cppは完成したはずです.