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

内容
前回、液晶の表示方法を説明しました。R8C/M12Aはリセット端子を除くと使えるI/O端子は16端子で、液晶との接続に6端子使用します。残る端子は、10端子になります。今回は、74HC595というシリアル→パラレル変換ICを使って、R8C/M12Aの使用端子を3本にして制御する方法を紹介します。

ワークスペース
※2012.04.27まで公開していたファイル(Ver.1.00)は、lcd_put_num関数、lcd_put_hex関数に不具合がありました。お手数ですが最新版(Ver.1.01)に差し替えをお願いいたします。

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

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

回路図
※液晶の1ピンと2ピンのVcc、GNDは、液晶によって違うことがあります。必ず付属の説明書を参照してください。

シリアル接続

直接接続とシリアル接続

前回は、R8C/M12Aと液晶を直接接続しました(下図)。

液晶

今回は、R8C/M12Aと液晶の間に74HC595というシリアル信号を8bit信号に変換するICを入れて、このICを介して液晶を制御します(下図)。

液晶

直接接続と74HC595を使ったときの違いまとめた表を下記に示します。

項目 液晶直接 74HC595使用
付加部品 無し 74HC595、抵抗10kΩ
マイコンの使用端子 6本 3本
制御スピード 高速 中速
R8C/M12Aで使用する
内蔵周辺機能
無し UART0

74HC595との接続には、R8C/M12AのUART0を使用します。「UART0による通信」で行った、パソコンとの通信はできなくなります。

74HC595の仕組み

R8C/M12Aの各端子から74HC595に入力する信号と、74HC595から出力される信号について説明します。
SINは信号IN、SCKは信号クロック、LCKはラッチクロックの意味です。
SINに信号をセットして、SCKを"0"→"1"にするとSINの信号が74HC595のQA〜QH端子に1bitずつシフトして記憶されます。これを8回繰り返しQA〜QH端子にデータをセットします。。下図は、"1010 0011"を出力するときの信号です。8bit分セットできたらLCK信号を"0"→"1"にします。この瞬間、QH〜QAの8本の端子から"1010 0011"が出力されます。

 仕組み

R8C/M12Aから74HC595のSIN信号、SCK信号への出力は、UART0のクロック同期式I/Oモードを使います。R8C/M12Aと74HC595を接続するとき、R8C/M12Aが接続することのできる端子を下表に示します。

74HC595の端子 R8C/M12Aと接続することのできる端子
SIN TXD0端子…P1_4,P4_2,P4_6のどれか
SCK CLK0端子…P1_6
LCK どの端子でも可能

R8C/M12Aのどの端子と74HC595を接続させるかは、「lcd_lib_sirial.h」で設定します。設定方法は後述します。
また、液晶の各信号を74HC595のどの信号に接続したかも、「lcd_lib_sirial.h」で設定します。

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

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

液晶の初期化(シリアル版)

■関数
書式 void lcd_sirial_init( void );
内容 74HC595に接続された液晶を4bitモードで初期化します。
引数 無し
戻り値 無し
使用例
  lcd_sirial_init(); // 液晶を初期化

液晶表示位置の設定

■関数
書式 void lcd_position( char x ,char y );
内容 液晶に表示する位置を設定します。
引数 x位置:0〜15 左から何文字目に表示するか設定します。一番左が0です。
y位置:0〜1 上から何行目に表示するか設定します。一番上が0です。
戻り値 無し
使用例
  // x=0, y=1に表示
  lcd_position( 0, 1 );

液晶のコマンド設定

■関数
書式 void lcd_control( unsigned char data );
内容 液晶にコマンドを設定します。
引数 LCD_CLEAR :表示クリア+カーソルをホームへ移動
LCD_CURSOR_DEC :カーソルオートデクリメント
LCD_CURSOR_INC :カーソルオートインクリメント
LCD_DISPLAY_OFF :表示OFF
LCD_DISPLAY_ON :表示ON
LCD_CURSOR_ON :表示ON+カーソルON +ブリンクOFF
LCD_CURSOR_OFF :表示ON+カーソルOFF+ブリンクOFF
LCD_CURSOR_BLINK:表示ON+カーソルOFF+ブリンクON
LCD_CURSOR_LEFT :カーソル左シフト
LCD_CURSOR_RIGHT:カーソル右シフト
戻り値 無し
使用例
  lcd_control( LCD_CLEAR );

液晶に文字列表示

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

  init();            /* 初期化       */
  lcd_sirial_init(); /* 液晶初期化   */

  lcd_position( 0, 0 );
  lcd_put_str( "モジレツヒョウジ" );

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

液晶に10進数を表示

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

液晶に16進数を表示

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

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

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

ヘッダファイルの登録

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

#include "sfr_r8m12a.h"     /* R8C/M12A SFRの定義ファイル */
#include "lcd_lib_sirial.h" /* 液晶初期化(シリアル版)   */

main関数

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

void main( void )
{
    init();             /* 初期化                  */
    lcd_sirial_init();  /* 液晶初期化(シリアル版)*/

    // 文字列の表示
    lcd_put_str( "モジレツヒョウジ" );

    while( 1 ) {
        // 10進数の表示
        lcd_position( 0, 1 );
        lcd_put_num( cnt_rb, 6 );

        // 16進数の表示
        lcd_position( 8, 1 );
        lcd_put_hex( cnt_rb, 6 );
    }
}

今回のプログラムは、液晶の横0文字目、縦0行目(以下、(0,0)と表記)に「モジレツヒョウジ」と表示します。
(0,1)に10進数でcnt_rb変数の値を6桁で表示します。(8,1)に16進数でcnt_rb変数の値を6桁で表示します。
cnt_rb変数の値が1234のときの表示している状態を下記に示します。

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

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

液晶と接続するポートの変更
R8C/M12Aと液晶を接続するポートは、変更することができます。「lcd_lib_sirial.h」を開きます。

R8C/M12Aと74HC595の接続

74HC595に接続するR8C/M12Aの端子を設定します。

/*======================================*/
/* シンボル定義                         */
/*======================================*/
/* 接続ポートに応じて、ポートを変更してください */
/* R8C/M12A <=> 74HC595間の設定 */
#define HC595_LCK p1_1    /* 74HC595のLCK端子の接続端子    */
#define TXD0      1       /* TXD0端子 1=P1_4 2=P4_2 3=P4_6 */

74HC595のLCK端子に接続するR8C/M12Aの端子を「HC595_LCK」で設定します。
74HC595のSIN端子に接続するR8C/M12Aの端子を「TXD0」で設定します。設定値が1ならP1_4端子と、2ならP4_2端子と、3ならP4_6端子と接続します。UART0のTXD0端子を使うのでそれ以外の端子とは接続できません。
74HC595のSCK端子に接続するR8C/M12Aの端子は、UART0のCLK0端子を使うので、P1_6端子しか接続できません。
74HC595のLCK端子、SIN端子をR8C/M12Aのどの端子に接続するか、設定してください。

74HC595と液晶の接続

液晶に接続する74HC595の端子を設定します。

/* 74HC595 <=> 液晶間の設定 */
#define LCD_E     (1<<6)  /* 液晶のE  端子の74HC595のQG(bit6) */
#define LCD_RS    (1<<4)  /* 液晶のRS 端子の74HC595のQE(bit4) */
#define LCD_DB7   (1<<3)  /* 液晶のDB7端子の74HC595のQD(bit3) */
#define LCD_DB6   (1<<2)  /* 液晶のDB6端子の74HC595のQC(bit2) */
#define LCD_DB5   (1<<1)  /* 液晶のDB5端子の74HC595のQB(bit1) */
#define LCD_DB4   (1<<0)  /* 液晶のDB4端子の74HC595のQA(bit0) */

液晶の6端子を、74HC595のQA〜QHのどの端子に接続するか設定します。
74HC595の接続端子とプログラムでの設定を、下表に示します。

74HC595の端子 設定値
QH端子 (1<<7)、または、0x80
QG端子 (1<<6)、または、0x40
QF端子 (1<<5)、または、0x20
QE端子 (1<<4)、または、0x10
QD端子 (1<<3)、または、0x08
QC端子 (1<<2)、または、0x04
QB端子 (1<<1)、または、0x02
QA端子 (1<<0)、または、0x01
※(1<<x)のxは、QA=0,QB=1・・・QH=7となります。

例えば、液晶のE端子を、74HC595のQH端子に接続するときは、表より「(1<<7)」なので、下記のように設定します。

#define LCD_E     (1<<7)  /* 液晶のE端子の74HC595のQH(bit7) */

このように、液晶の6端子を接続する74HC595の端子を設定してください。

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

ルネサス統合開発環境

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

@マイコンが動作し始めると「startup_r8cm12a.c」内のstart関数が実行されます(#pragma entry命令で設定した関数から実行されます)。この関数でマイコンのレジスタの初期化など、マイコン固有の初期化を行います。次にmain関数に移ります。
A「lcd_sirial.c」の最初に「lcd_lib_sirial.h」を読み込んで、「lcd_lib_sirial.c」に登録している関数を読み込みます。main関数を実行、この中で液晶を制御します。
B「lcd_lib_sirial.c」には液晶をシリアル変換IC(74HC595)を介して制御するための関数を用意しており、main関数などから呼び出されて使います。このCファイル単体では何もしません。


BACK