|  | 
        
          | 
              
                |  液晶の表示〜シリアル接続版〜
 |  |  
          |  |  
          | 内容
  前回、液晶の表示方法を説明しました。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の接続端子とプログラムでの設定を、下表に示します。
 
 
 
              ※(1<<x)のxは、QA=0,QB=1・・・QH=7となります。
                | 
                    
                      | 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 |  |  
 例えば、液晶の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つのファイルの関係を下図に示します。
 
 @マイコンが動作し始めると「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ファイル単体では何もしません。
 
 
 
 |  |