Micom Car Rally NET
MCR - Micom Car Rally
2015大会 マイコンカーラリーとは? 今から始めるマイコンカーラリー 技術情報 大会記録 MCRファン倶楽部 お問い合せ
マイコンカーラリートップへ マイコンカーラリートップへ
技術情報 >> R8C/M12A 技術情報
技術情報
アプリケーション
R8C/M12A 技術情報
上位入賞マイコンカー
参加者レポート
よくある質問(FAQ)
ダウンロード
R8C/M12A 技術情報
グラフィック液晶の表示

内容
R8C/M12Aを使ってグラフィック液晶(GLCDと略します)を表示します。グラフィック液晶は、(株)秋月電子通商などで売っている「グラフィック液晶表示器[128x64ドット]」を使用します。R8C/M12Aと液晶を接続するポートは、プログラムで変更することができます(ただし、グラフィック液晶のDB0〜DB7は、マイコンのポートxのbit0〜bit7に接続する必要があります、R8C/M12Aでbit0〜bit7があるのはポート1のみなので、今回は必ずポート1に接続することになります)。

ワークスペース
r8cm12a_graphic_lcd_100.zip
ファイルを解凍し、フォルダを「c:\worksapce」に入れてください。

回路
回路を下図に示します。

回路図

※グラフィック液晶のピン配置は、グラフィック液晶によって違うことがあります。必ず付属の説明書を参照してください。

ブレッドボード実装図
ブレッドボードの実装を下図に示します。
ブレッドボード実装図

※グラフィック液晶のピン番号は、グラフィック液晶によって違うことがあります。必ず付属の説明書を参照してください。
※グラフィック液晶の20ピンコネクタ部分は半田づけが必要です。また単線も足りませんので各自でご用意ください。

グラフィック液晶

今回使用するグラフィック液晶

今回は、(株)秋月電子通商などで販売されている「バックライト付グラフィック液晶表示器(LCD)[128x64ドット]SG12864ASLB−GB」を使用して、文字を表示してみます。横128×縦64ドットです。今回は1文字8×8ドットのフォントを使うので、横は128÷8=16文字、縦は64÷8=8文字、表示することができます。前回紹介した液晶は、16×2文字でしたので、縦が4倍になった計算です。
ただし、グラフィック液晶との結線は13本の線が必要で、R8C/M12Aはリセット端子を除くとI/Oが16本なので、残りは3端子しかありません。グラフィック液晶+3端子の空きで済むなら今回の結線で大丈夫です。「グラフィック液晶の表示(74HC595を使って使用する端子を3本にする)」では、74HC595を2個追加して、R8C/M12Aの端子を3本で制御する方法を紹介しますので、使える端子を増やしたい場合は、「グラフィック液晶の表示(74HC595を使って使用する端子を3本にする)」を参照してください。

液晶

この液晶には、下記の端子があります。

ピン 端子名 詳細
1 GND GND(0V)を接続します。
2 Vcc +5Vを供給します。
3 Vo コントラストです。ボリュームで0〜5Vを供給できるようにしてます。液晶表示の濃さを調節します。
4 RS "1"にするとDB7〜DB0の信号は液晶を制御する信号、"0"にするととDB7〜DB0は液晶に表示するデータという意味になります。
5 RW "1"にするとグラフィック液晶→マイコンへの信号、"0"にするとマイコン→グラフィック液晶への信号になります。今回はグラフィック液晶からのデータは読み込みません。よってマイコンには接続せずにGND(0V)に接続します。
6 E "1"にするとRS端子、RW端子、DB7〜DB0端子の情報を液晶で読み込み、液晶を動作させます。この端子を"1"にするまではとRS端子、RW端子、DB7〜DB0端子を変更しても何も起きません。
7 DB0 データバスbit0です。
8 DB1 データバスbit1です。
9 DB2 データバスbit2です。
10 DB3 データバスbit3です。
11 DB4 データバスbit4です。
12 DB5 データバスbit5です。
13 DB6 データバスbit6です。
14 DB7 データバスbit7です。
15 CS1 右半分を有効にします。
16 CS2 左半分を有効にします。
17 /RES "0"にするとグラフィック液晶がリセットします。起動時、リセットさせてから動作させます。
18 Vout グラフィック液晶のコントラスト調整用ボリュームの1ピンに接続します。
19 A グラフィック液晶にバックライトが付いているとき、バックライトLEDのアノード(A)端子です。
20 K グラフィック液晶にバックライトが付いているとき、バックライトLEDのカソード(K)端子です。
※グラフィック液晶のピン番号は、グラフィック液晶によって違うことがあります。必ず付属の説明書を参照してください。

グラフィック液晶の制御方法

グラフィック液晶は、RST端子、CS2端子、CS1端子、E端子、RS端子、RW端子、DB7〜DB0端子の合計14端子をマイコンと接続する必要があります。R8C/M12Aは16端子(PA_0を入れると17端子)しかI/Oがないため、できるだけ接続数を減らしたいです。
RW端子は、マイコンからグラフィック液晶にコマンドや表示データを書き込むときは"0"に、グラフィック液晶から送られてくるデータをマイコンが読み込むときは"1"にします。グラフィック液晶から送られてくるデータとは、液晶に表示データを送った後、実際に表示されたかどうかの信号をグラフィック液晶からマイコンに出力します。マイコンは表示されたことを確認して、次の表示データを送ります。グラフィック液晶のデータシートには表示されるまでの時間は最大で10msと書いてあります。今回は、実際に表示されたか確認せずに10ms待つことにしてRW端子は使わないことにします。そのため、マイコン→グラフィック液晶への信号のみなのでRW端子はGND(0V)に接続します。
よって、今回のR8C/M12Aと液晶の接続は、先に説明した端子からRW端子を除いた13本となります。

回路

プログラム「glcd_lib.c」の説明

「glcd_lib.c」は、グラフィック液晶を制御するための関数をまとめたファイルです。このCファイルをルネサス統合開発環境に組み込んで使用します。このファイルを組み込むと使うことのできる関数を説明します。

グラフィック液晶の初期化

■glcd_init関数
書式 void glcd_init( void );
内容 グラフィック液晶を初期化します。
引数 無し
戻り値 無し
使用例
  glcd_init();   // 液晶を初期化

グラフィック液晶表示位置の設定

■glcd_position関数
書式 void glcd_position( unsigned char x, unsigned char y );
内容 グラフィック液晶に表示する位置を設定します。
引数 x位置:0〜127 左からxドット目に表示します。一番左が0です。
y位置:0〜7 上から(y×8)ドット目に表示します。一番上が0です。
戻り値 無し
使用例
  // x=0, y=8に表示
  glcd_position( 0, 1 );

グラフィック液晶は横128ドット、縦64ドットです。横は1ドット単位で指定します。縦は8ドットが1単位のため、glcd_position関数で指定したy位置×8の部分が、実際のグラフィック液晶に表示される位置になります。例えば、、glcd_position(0, 1 )とすると、ドット数としてはx=0、y=8の位置から表示します。glcd_position関数のx位置、y位置と、実際に表示される位置の関係を下記に示します。
※(x, y)=glcd_position( x, y )です。



液晶に文字列表示

■glcd_put_str関数
書式 void glcd_put_str( const char *str );
内容 グラフィック液晶に文字を表示します。
引数 表示する文字列の先頭ポインタ
文字列の終わりは0x00(\0)にします。0x00になると表示を終わります。
C言語の仕様で、文字列をダブルクォーテーション(”)でくくると、自動的に'\0'が付加されます。
例)"abcdefg"→"abcdefg"+'\0'
戻り値 無し
使用例
void main( void ) {
  int i;
  char s[2];

  init();           /* 初期化             */
  glcd_init();      /* グラフィック液晶初期化  */

  glcd_position( 0, 0 );
  glcd_put_str( "モジレツヒョウジ" );

  glcd_position( 0, 1 );
  for( i=0; i<16; i++ ) {
    s[0] = i + 'a';
    s[1] = '\0';  // 終了コード
    lcd_put_str( s );
  }
}

グラフィック液晶に10進数を表示

■glcd_put_num関数
書式 void glcd_put_num( long value, int keta );
内容 グラフィック液晶に10進数を表示します。
引数 表示する値:0〜99999999
表示する桁:1〜8
戻り値 無し
使用例
  glcd_position( 0, 1 );
  glcd_put_num( 12345, 6 ); // '012345'と表示

グラフィック液晶に16進数を表示

■glcd_put_hex関数
書式 void glcd_put_hex( unsigned long value, int keta );
内容 液晶に16進数を表示します。
引数 表示する値:0〜0xffffffff
表示する桁:1〜8
戻り値 無し
使用例
  glcd_position( 0, 1 );
  glcd_put_hex( 0x1a2b3c4d, 8 );  // "1a2b3c4d"と表示

グラフィック液晶にオリジナルデータを表示

■glcd_put_data関数
書式 void glcd_put_data( unsigned char data );
内容 液晶にオリジナルデータを表示します。
引数 表示するデータ0x00〜0xff
戻り値 無し
使用例
  glcd_position( 0, 0 );
  glcd_put_data( 0xc8 );  // 下から上に1100 1000を表示

オリジナルデータの表示は、横1ドット×縦8ドットが1つの単位です。また縦は、yの値が大きいほうが上位ビット、小さいほうが下位ビットになります。(0,0)の位置に0xc8を表示させたときの状態を下記に示します。




プログラム「graphic_lcd.c」の説明

「graphic_lcd.c」は、main関数があるCファイルです。このファイルから、「glcd_lib.c」に登録している関数を呼び出して液晶を制御しています。呼び出し方を説明します。

ヘッダファイルの登録

拡張子が「h」のファイルをヘッダファイルといい、Cファイルに登録している関数を宣言しているファイルです(今回の説明の場合)。「glcd_lib.c」と「glcd_lib.h」はペアで作られていて、「glcd_lib.c」の中にどのような関数があるかを「glcd_lib.h」で宣言しています。要は、hファイルはCファイルの目次のようなものです。
今回、main関数がある「graphic_lcd.c」から「glcd_lib.c」の関数を呼び出すために、目次である「glcd_lib.h」を登録します。

#include "sfr_r8m12a.h" /* R8C/M12A SFRの定義ファイル   */
#include "glcd_lib.h"   /* グラフィック液晶制御ライブラリ    */


main関数

init関数の次に、グラフィック液晶の初期化をする「glcd_init」関数を実行します。その後はグラフィック液晶を制御する関数を使って、グラフィック液晶に文字を表示します。

const unsigned char original_data[] = { /* オリジナルデータ */
    0xff, 0x81, 0xff, 0x85, 0x89, 0x89, 0x85, 0xff,
    0x81, 0xbd, 0xc3, 0xc3, 0xc3, 0xa5, 0x81, 0xff,
    0x8b, 0x8b, 0x9b, 0xab, 0xc5, 0x81, 0xff, 0x00 };

void main( void )
{
    int x;

    init();         /* 初期化                   */
    glcd_init();    /* グラフィック液晶初期化   */

    glcd_kana( 0 );     // カタカナ表示
    glcd_position( 0, 1 );
    glcd_put_str( "アイウエオカキクケコワヲン" );

    glcd_kana( 1 );     // ひらがな表示
    glcd_position( 0, 2 );
    glcd_put_str( "アイウエオカキクケコワヲン" );

    // オリジナルのデータを表示
    glcd_position( 0, 7 );
    for( x=0; x<sizeof(original_data); x++ ) {
        glcd_put_data( original_data[x] );
    }

    while( 1 ) {
        glcd_position( 0, 4 );
        glcd_put_num( cnt_rb,  8 );
        glcd_position( 0, 5 );
        glcd_put_hex( cnt_rb,  8 );
    }
}

今回のプログラムは、
・グラフィック液晶の横0文字目、縦0行目(以下、(0,0)と表記)に「Hello World!」と表示
・(0,1)に「アイウエオカキクケコワヲン」とカタカナを表示
・(0,2)に「あいうえおかきくけこわをん」とひらがなを表示
・(0,4)に10進数でcnt_rb変数の値を8桁で表示
・(0,5)に16進数でcnt_rb変数の値を8桁で表示
・(0,7)に、オリジナルデータを表示(original_data配列にMCRを四角で囲ったデータを登録しておき、このデータを表示)
します。
cnt_rb変数の値が1234のときの表示している状態を下記に示します。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
         
     
     
                               
               
               
                               
                         

※glcd_put_num関数を実行するときのcnt_rb変数の値と、glcd_put_hex関数を実行するときのcnt_rb変数の値は違うので、実際は上画面のように10進数の値=16進数の値にはなりません。

「font_8x8.h」の説明

液晶の表示」で紹介したLCDキャラクタディスプレイモジュールには、文字フォントが内蔵されており、キャラクターコード(1バイトデータ)を送ると内蔵されている文字フォントを表示します。グラフィック液晶は、グラフィックを自由に表示できますがフォントを内蔵していないため、マイコン側から文字フォントを送る必要があります。
「font_8x8.h」には、アスキーコードのフォントと、アスキーコードの文字が登録されていない部分に独自にひらがなフォントを登録しています。文字を表示させたいときは、このフォントデータを呼び出します。今回は、1文字8×8ドットとし、1文字で8バイトのデータ数となります。文字数は、キャラクタコード0x20〜0xfdの221バイト分を登録して、容量は1768バイトになります。漢字フォントを登録すれば漢字も表示することができますが、R8C/M12Aは8KBしかROMがないので、ROM容量の上限にならないようにしてください。
プログラムの一部を下記に示します。

// キャラクタデータ 0x20〜0xfd
const char font[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    // 0x20 ' '
0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,    // 0x21 '!'
 :
中略
 :
0x00,0x3e,0x41,0x41,0x41,0x41,0x3e,0x00,    // 0x30 '0'
0x00,0x00,0x42,0x7f,0x40,0x00,0x00,0x00,    // 0x31 '1'
0x00,0x62,0x51,0x51,0x49,0x49,0x46,0x00,    // 0x32 '2'
0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00,    // 0x33 '3'
0x00,0x30,0x28,0x24,0x22,0x7f,0x20,0x00,    // 0x34 '4'
0x00,0x2f,0x45,0x45,0x45,0x45,0x39,0x00,    // 0x35 '5'
0x00,0x3e,0x49,0x49,0x49,0x49,0x32,0x00,    // 0x36 '6'
0x00,0x01,0x01,0x61,0x19,0x05,0x03,0x00,    // 0x37 '7'
0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00,    // 0x38 '8'
0x00,0x26,0x49,0x49,0x49,0x49,0x3e,0x00,    // 0x39 '9'
 :
以下、略

「2」のフォントを説明します。
「2」は「@0x00 A0x62 B0x51 C0x51 D0x49 E0x49 F0x46 G0x00」の8バイトデータです。@のデータbit7〜0を縦に下から上に並べます("0"=□、"1"=■)。続けてA〜Gのデータを並べると「2」のフォントデータになります。
bit0:□□■■■■□□
bit1:□■□□□□■□
bit2:□□□□□□■□
bit3:□□□□■■□□
bit4:□□■■□□□□
bit5:□■□□□□□□
bit6:□■■■■■■□
bit7:□□□□□□□□
      ↑↑↑↑↑↑↑↑
      @ABCDEFG
      0 0 0 0 0 0 0 0
      x x x x x x x x
      0 6 5 5 4 4 4 0
      0 2 1 1 9 9 6 0

※本フォントは、『8×8 ドット日本語フォント「美咲フォント」』を16進数データに変換して使用しています。フリーで提供されている門真なむ様にはお礼申し上げます。

液晶と接続するポートの変更
R8C/M12Aとグラフィック液晶を接続するポートは、変更することができます。「glcd_lib.h」を開きます。

/*======================================*/
/* シンボル定義                         */
/*======================================*/
/* 接続ポートに応じて、ポートを変更してください */
#define  GLCD_RST   p3_5    /* GLCDのPST端子                */
#define  GLCD_CS2   p4_7    /* GLCDのCS2端子                */
#define  GLCD_CS1   p4_6    /* GLCDのCS1端子                */
#define  GLCD_E     p4_5    /* GLCDのE端子                  */
#define  GLCD_RS    p4_2    /* GLCDのRS端子                 */
#define  GLCD_DATA  p1      /* GLCDのDATAポートのレジスタ   */

例えば5行目は、『グラフィック液晶のRST端子(GLCD_RST)は、マイコンのp3_5とつなぐ』という意味です。この「p3_5」部分を実際につなぐポートに変更してください。
GLCD_DATAは、グラフィック液晶のDB7〜DB0端子に接続するポートを設定します。DB7〜DB0端子は、1つのポートのbit7〜bit0に接続します。R8C/M12Aでbit7〜bit0までそろっているのはポート1しかないので、今回は必ず「p1」を設定することになります。
「graphic_lcd.c」のinit関数で行う入出力設定について、液晶につなぐ13端子は出力に設定してください。

Cファイルの関係
今回のプロジェクトのC source fileには、「startup_r8cm12a.c」、「glcd_lib.c」、「graphic_lcd.c」の3つのCファイルが登録されています。

ルネサス統合開発環境

3つのファイルの関係を下図に示します。
3つのファイルの関係

@マイコンの電源が入ると「startup_r8cm12a.c」内のstart関数が実行されます(#pragma entry命令で設定した関数が最初に実行されます)。この関数の中で、マイコン固有の初期化を行います。次にmain関数に移ります。
A「graphic_lcd.c」の最初に「glcd_lib.h」を読み込んで、「glcd_lib.c」に登録されている関数名を確認します。main関数を実行、この中でグラフィック液晶を制御します。
B「glcd_lib.c」はグラフィック液晶を制御するための関数をまとめたファイルで、main関数などから呼び出されて使います。このCファイル単体では何もしません。


BACK