LCDに文字を表示する



 ここで扱う液晶(LCD)は、秋月電子で販売しているLCD、SC1602BS(2行×16文字)を使うプログラムです。
R8C/M12Aのポート1に接続しています。

(1)LCD制御命令
 説明書に記述してあるように、このLCDには11の制御命令が設定されています。この命令
をコントロールすることによって液晶の表示を行うことが可能となる。

 命令を送るときは、RS=0にセットしてからコマンドを送る。
 データを送るときは、RS=1にセットしてからデータを送る。
  

 命令 RS R〜W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
 表示クリヤ   0   0   0   0   0   0   0   0   0   1
 カーソルホーム   0   0   0   0   0   0   0   0   1   X
 エントリモード   0   0   0   0   0   0   0   1  I/D   X
 ディスプレー 
 ON/OFF
  0   0   0   0   0   0   1   D   C   B
 カーソル表示
 ディスプレーシフト
  0   0   0   0   0   1   S/C   R/L   X   X
 ファンクションセット   0   0   0   0   1   DL   N   F   X   X
 CGRAMセット   0   0   0   1          CGRAMアドレス
 DDRAMセット   0   0   1        DDRAMアドレス
 BFアドレス
 読み出し
  0   1   BF        アドレスカウンタ
 CGRAM/DDRAM
 書き込み
  1   0       DDRAM/CGRAMへの書き込みデータ
 CGRAM/DDRAM
 読み出し
  1   1       DDRAM/CGRAMからの読み込みデータ

カーソル表示/ディスプレーシフト    ・・・R/L=1で右シフト、R/L=0で左シフト
                    ・・・S/C=1でカーソルと一緒に移動、0でカーソル位置

ファンクションセット          ・・・DL:インターフェイス長設定 1で8ビット、0で4ビットモード
                       N :表示行数設定、1で2行、0で上1行のみ、F:0で5x7ドット文字
                       (ファンクションセットは他の制御命令より先に実行しなければならない)


(2) LCDの初期設定
  1. 電源ON      ・・・電源ON以後15ms以上wait
      ↓
  2. wait()       初期化開始
      ↓          RS→0   E→1  8ビット転送
  3. 0010 0011 ・・・1回目のファンクションセット RS→0 E→1 8ビット転送
      ↓
  4. 0010 0011 ・・・2回目のファンクションセット RS→0 E→1 8ビット転送
      ↓

  5. 0010 0011 ・・・3回目のファンクションセット RS→0 E→1 8ビット転送
      ↓
  6. 0010 0011 ・・・4回目のファンクションセット RS→0 E→1 8ビット転送

                  E→0 データ長4ビットに設定
      ↓
  7. 0010 1000 ・・・ファンクションセット
                  DL=0:転送長4ビット N=1:表示2行 F=0
      ↓
  8. 0000 1110 ・・・カーソル/ディスプレイ制御
                 ディスプレィON カーソルON ブリンクOFF
      ↓  
  9. 0000 0110 ・・・エントリーモード
                  カーソル移動方向インクリメント、ディスプレーシフトしない
      ↓ 
  10. 0000 0001 ・・・クリヤディスプレイ




(3) 液晶へ文字を表示させる仕方を下記の2通りの方法で対処できるようにしました。

方法1) 配列str1(1行目表示用)、str2(2行目表示用)に表示したい文字を1文字づつ
    配列番号に従っていれる。配列の添え字番号が表示列位置番号にな っています。
    lcd_str(str1、1)は、配列str1に入っている文字列を液晶の1行目に表示する意味
    になります。 ただし、スクロールさせて文字列を表示させるのであれば最大1行80
    文字まで 表示させることができると思います。

方法2) 直接表示したい文字列をそのまま下記のように記述する。
      lcd_str(”表示文字列¥0”、表示行数1または2);


◎結線はプログラム内のコメント文にも記述していますが、

下記のようになっています。表示は4ビットモードで行っています。

LCD側 R8C/M12A側
VDD
VSS
VO(コントラスト)
RS P1_b4
R/W GND
E P1_b5
DB0
DB1
DB2
DB3
DB4 P1_b0
DB5 P1_b1
DB6 P1_b2
DB7 P1_b3

◎ LCD基盤の配線図(基盤ハンダ面) 

    LCD 側       R8CM12A 側

    1: Vdd              
    2: Vss              
    3: Vo(Contrast)        
    4: RS          P1-B4
    5: R/W         GND
    6: E           P1-B5
    7: DB0              
    8: DB1              
    9: DB2              
   10: DB3             
   11: DB4         P1-B0
   12: DB5         P1-B1
   13: DB6         P1-B2
   14: DB7         P1-B3




Rは液晶画面の明るさを調節する可変抵抗です。1kΩを付けています。

◎プログラムを実行したLCD表示画面


   




(4)プログラムの作成

  HEWを立ち上げ、新規プロジェクトワークスペースの作成でワークスペース名を「M12_LCD」とします。
  下のメインプログラムを打ち込んで作成します。

1)メインプログラム M12_LCD.c
  #include "sfr_r8m12a.h"
  #include "lcd_ctrl.h"

  void main(void)
  {
    unsigned int i;
    unsigned char str1[16]; // LCD1行目表示配列
    unsigned char str2[16]; // LCD2行目表示配列

    init();
    lcd_init();
    lcd_clear();
    for(i=0;i<16;i++){
        str1[i]=' '; // LCD1行目表示配列初期化
        str2[i]=' '; // LCD2行目表示配列初期化
    }

    lcd_cursor_off();
    lcd_str("0123456789abcdef",1);

    str2[0]='モ';str2[1]='シ';str2[2]='ノ';str2[3]='ヒ';str2[4]='ョ';
    str2[5]='ウ';str2[6]='シ';str2[7]='テ';str2[8]='ス';str2[9]='ト';
    lcd_str(str2,2);
  }

2)LCD制御関数 lcd_ctrl.c
 次の液晶表示制御関数 lcd_ctrl.cを別ファイルとして、エディター等で作成してメインファイルと
同じフォルダに保存します。

     RS命令を送るときはRS_Low、データを送るときはRS_Highにセット
    
     RS=0 R/W=0 Control Command 出力
     RS=1 R/W=0 書き込みデータ出力

     str1[i] 1行目に表示する文字を格納する配列 i=0〜15
     str2[i] 2行目に表示する文字を格納する配列 i=0〜15

    LCD表示の仕方は

    1) lcd_str(str1,line)  配列str1[i]に表示する文字を記入して文字str1をlineで指定した行に表示する

    2) lcd_str("文字列\0",line)   表示したい文字列を直接"文字列"に記入してlineで指定した行に表示する



  #include "sfr_r8m12a.h"
  #include "lcd_ctrl.h"

  /* I/O初期化関数 */
  void init(void)
  {
    int i;
    /**** 高速オンチップオシレータで動作する場合 ****/
    prc0 = 1;// プロテクトレジスタ解除
    hocoe = 1;// 高速オンチップオシレータ発振開始
    for(i=0;i<50;i++);//発振安定まで待つ
    hscksel =1;// 高速オンチップオシレータ選択ビットを1にする
    scksel =1;// システム基準クロックを高速にする
    prc0 = 0;// プロテクトレジスタ禁止
    pd1 = 0x7f;// ポートディレクションレジスタ p0〜p6出力ポート設定
    p1 = 0x00;
  }

  /* us単位のwait関数 */
  void wait_us(unsigned long usec)
  {
    usec = (usec * CLOCK) / 45000;
    while(usec --);{}
  }

  /* データ出力関数 */
  void lcd_out(unsigned char code,unsigned char flag)
  {
    p1=code & 0x0f;
    if( flag == 0)
        RS_High;
    else
        RS_Low;
        asm("NOP");
        E_High;
        asm("NOP");
        asm("NOP");
        asm("NOP");
    asm("NOP");
    E_Low;
  }

  /* 画面消去関数 */
  void lcd_clear(void)
  {
    lcd_cmd(0x01);
  }
  /* カーソル表示OFF */
  void lcd_cursor_off(void)
  {
    lcd_cmd(0x0c);
  }


  /* 1文字出力関数 */
  void lcd_data(unsigned char asci)
  {
    lcd_out(asci>>4,0); // 上位4ビット出力
    lcd_out(asci,0); // 下位4ビット出力
    wait_us( 50 );
  }

  /* コマンド出力関数 */
  void lcd_cmd(unsigned char cmd)
  {
    lcd_out(cmd >>4,1);
    lcd_out(cmd,1);
    if((cmd == 0x01) || (cmd == 0x02))
        wait_us(2000);
    else
        wait_us(50);
  }


  /* 文字列出力関数 */
  void lcd_str(unsigned char *str,unsigned char line)
  {
    if(line==1)
        lcd_cmd(0x02);
    else
        lcd_cmd(0xc0);

    while(*str != 0x00){
        lcd_data(*str);
        str++;
    }
  }


  /* LCD初期化関数 */
  void lcd_init(void)
  {
    wait_us(20000);
    lcd_out(0x03,1); // LCD初期化1回目 0010 0011 E=1,RS=0 8ビット転送
    wait_us(5000);
    lcd_out(0x03,1); // LCD初期化2回目 0010 0011 E=1,RS=0 8ビット転送
    wait_us(4000);
    lcd_out(0x03,1); // LCD初期化3回目 0010 0011 E=1,RS=0 8ビット転送
    wait_us(4000);
    lcd_out(0x02,1); // LCD初期化4回目 0010 0010 E=1,RS=0 8ビット転送 データ長4ビットに設定
    wait_us(4000);
    lcd_cmd(0x28); // 001 0 1000 セットファンクション b4=0:転送長4ビット,b3=1:表示数2行,b2=0:表示ドット5x7
    wait_us(4000);
    lcd_cmd(0x08); // 0000 1000 ディスプレイOFF,D=C=B=0
    wait_us(4000);
    lcd_cmd(0x0e); // 0000 1110 b2=1:ディスプレイON,b1=1:カーソルON,b0=0:ブリンクOFF
    wait_us(4000);
    lcd_cmd(0x06); // 0000 01 10 エントリーモード b1=1:カーソル移動方向インクリメント,b0=0:ディスプレイシフトしない
    wait_us(4000);
    lcd_cmd(0x01); // 0000 000 1 クリアディスプレイ
    wait_us(4000);
  }



 lcd_ctrl.cは分割コンパイルの構成ファイルとして作成しますが、作成したけではHEW立ち上げ画面の左側の
プロジェクト一覧の中には組み込まれません。手動で追加してやる必要があります。「C source file」の
「M12_LCD.c」の上でマウスを右クリックすると、サブメニューが出てくる。その項目の4段目のファイルの追加を
選択して、「M12_LCD.c」と同じフォルダに保存してある「lcd_ctrl.c」を追加するとプロジェクト欄に表示され
るようになります。


3)プロトタイプ宣言と変数定義をまとめたヘッダーファイル lcd_ctrl.h
 次の「lcd_ctrl.h」もエディター等で作成して同じフォルダに保存します。このヘッダーファイルも作成
保存しただけではプロジェクト欄には表示されません。全部のファイルを作成保存した後、ビルドすると、
プロジェクト欄に表示されるようになります。

  void init(void);
  void lcd_init(void); /* LCD初期化関数 */
  void lcd_clear(void); /* LCD画面クリアー */
  void lcd_cursor_off(void); /* LCDカーソルoff */
  void lcd_out(unsigned char,unsigned char); /* データ出力関数 */
  void lcd_data(unsigned char); /* 一文字出力関数 */
  void lcd_cmd(unsigned char cmd);/* コマンド出力関数 */
  void wait_us(unsigned long usec);/* us単位のウエイト関数 */
  void lcd_str(unsigned char *str,unsigned char); /* 文字列出力関数 */


  #define CLOCK 20000
  #define LCD p1 // LCDのデータポート

  /* LCDのレジスターセレクション */
  #define RS_High (p1_4 = 1)
  #define RS_Low (p1_4 = 0)

  /* LCDのディスプレーイネーブル */
  #define E_High (p1_5 = 1)
  #define E_Low (p1_5 = 0)


プロジェクトファイルのダウンロード



メニューに戻る