キャラクタLCDモジュールに表示を行う

〔PICの動かせ方入門に戻る〕


キャラクタLCDのSD1602を使って文字を表示させます。
キャラクタLCDは秋月電子のこちらから購入しました。
SD1602タイプがブレッドボードに直接挿せるので便利に使えます、 他のLCDだとジャンパー線で引き出してブレッドボードに線を挿す感じで使用できます。

また、本回路を利用してデバッグモニターを作成する方法はこちらを参照して下さい。

文字を表示させるだけの機能しかないので基本部分は530バイト程とコンパクトに出来ています。
LCDの4ビットモードを使用するから、配線は6本(デジタル出力)で済みますが、 PIC12F系統は出力が5本しかないので無理です。

LCD1

今回使用するピンは14番(VDD)と5番(VSS)の電源に、8番〜13番(RB2〜RB7)のデジタル出力です。

@まずは、下記図画面の様に配線しましょう。
 LCDの接続端子はヘッダピンを半だ付けしないといけません。
 LCDのPICへ接続するピンは14番〜11番と6番、4番で、
 RB7-D7 RB6-D6 RB5-D5 RB4-D4 RB3-E RB2-RS の計6本をそれぞれ配線します。
 LCDのR/W(5番)はGNDに接続します。
 尚、他のLCDを使用する場合はピンの信号名を良く見て接続すれば利用できます。

LCD2

LCD4

 こんな感じで実験しました、LCD表示部の1行目下の方横1ライン欠けていますが....
 注意)上の回路図と下写真の電源5VとGNDラインは上下逆です。
 でもこの下写真回路LCDのVSS(5,1,16番ピン)がGNDと繋がっていない!、よく動いているなぁ (^_^;)

 16F1827

 16F819は古い石なので16F1827を使った場合のサンプルプログラムを載せて置きます。
 回路は上の実態配線図と同じです。 *3)
 16F1827のサンプルは、MPLAB X(v2.15)MPLAB(R) XC8 C Compiler Version 1.32コンパイラ
 使った内容に変更しました。 *4)


AMPLAB IDEを起動させます。

B下記がプログラムソースです、ちょっと長いです。
 HI-TECH C Compiler for PIC10/12/16 MCUs(Lite Mode) V9.80コンパイラを使用しています。
 プロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。
 プログラムソースをダウンロードしてプロジェクトに取込む事も出来ます。
---------------------------------------------------------------------
#include <stdlib.h>
#include <pic.h>
#include <htc.h>               // delay用

#define _XTAL_FREQ  8000000    // delay用(クロック8MHzで動作時)

// 異なるピンを使う場合はここを変更する
#define LCD_RS    RB2
#define LCD_EN    RB3
#define LCD_D4    RB4
#define LCD_D5    RB5
#define LCD_D6    RB6
#define LCD_D7    RB7

#define	LCD_STROBE()	((LCD_EN=1),(LCD_EN=0))

// アナログ出力CCP1はRB3の9番ピンから行う
// デバッグしない(DEBUGDIS):低電圧プログラミング機能使用しない(LVPDIS)
// メモリを保護しない(UNPROTECT):外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(MCLRDIS)
// 電源電圧降下常時監視機能ON(BOREN):電源ONから72ms後にプログラムを開始する(PWRTEN)
// ウオッチドックタイマ無し(WDTDIS):内部クロックを使用する(INTIO)
__CONFIG(CCPRB3 & DEBUGDIS & LVPDIS & UNPROTECT & MCLRDIS & BOREN & PWRTEN & WDTDIS & INTIO) ;


// 遅延の処理
void Wait(unsigned int num)
{
     int i ;

     // numで指定した回数だけ繰り返す
     for (i=0 ; i<num ; i++) {
          __delay_ms(10) ;     // 10msプログラムの一時停止
     }
}
// LCDにデータを実際に送信する処理
void lcd_write(unsigned char c)
{
     // 送信データのバイト列上位4ビットを処理
     LCD_D4 = ( ( c >> 4 ) & 0x01 ) ;
     LCD_D5 = ( ( c >> 5 ) & 0x01 ) ;
     LCD_D6 = ( ( c >> 6 ) & 0x01 ) ;
     LCD_D7 = ( ( c >> 7 ) & 0x01 ) ;
     LCD_STROBE() ;
     // 送信データのバイト列下位4ビットを処理
     LCD_D4 = ( ( c ) & 0x01 ) ;
     LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
     LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
     LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
     LCD_STROBE() ;
}
// LCDにコマンドを発行する処理
void command(unsigned char c)
{
     LCD_RS = 0 ;
     LCD_D4 = ( ( c ) & 0x01 ) ;
     LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
     LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
     LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
     LCD_STROBE() ;
}
/*******************************************************************************
*    lcd_clear - LCDモジュールの画面を消す処理                              *
*******************************************************************************/
void lcd_clear(void)
{
     LCD_RS = 0 ;
     lcd_write(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
     __delay_ms(2) ;   // LCDが処理(1.53ms)するのを待ちます
}
/*******************************************************************************
*    lcd_setCursor - LCDモジュール画面内のカーソル位置を移動する処理        *
*      col : 横(列)方向のカーソル位置(0-15)                                    *
*      row : 縦(行)方向のカーソル位置(0-1)                                     *
********************************************************************************/
void lcd_setCursor(int col, int row)
{
     int row_offsets[] = { 0x00, 0x40 } ;

     LCD_RS = 0 ;
     lcd_write(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-0FH,40H-4FH
}
/*******************************************************************************
*  lcd_putc - LCDにデータを1バイト出力する処理                             *
*    c : 出力する文字データ                                                    *
*******************************************************************************/
void lcd_putc(char c)
{
     LCD_RS = 1 ;        // RSの制御信号線をセットします
     lcd_write( c ) ;    // LCDにデータの送信
}
/*******************************************************************************
*  lcd_puts - LCDに文字列データを出力する処理(文字列をNULL(0x00)まで繰返し出力)*
*    s : 出力する文字列のデータ                                                *
*******************************************************************************/
void lcd_puts(const char * s)
{
	LCD_RS = 1 ;        // RSの制御信号線をセットします
	while(*s) lcd_write(*s++) ;
}
/*******************************************************************************
*  lcd_init - LCDの初期化処理                                               *
*******************************************************************************/
void lcd_init()
{
     LCD_RS = 0 ;
     LCD_EN = 0 ;

     __delay_ms(15) ;    // 電源ON後15msまで待ってから初期化

     // LCDの立上げ時のチェックデータ(イニシャライズ処理用)を設定
     command(0x03) ;
     __delay_ms(5) ;
     command(0x02) ;
     // LCDにコマンドを発行します
     lcd_write(0x28) ;   // function set   : データ線は4本・表示は2行・フォントは5x8ドット
     lcd_write(0x0c) ;   // display control: 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF
     lcd_clear() ;       // Clear Display  : 画面をクリアし、カーソル位置はcol=0,row=0
     lcd_write(0x06) ;   // entry mode set : 文字を表示した次にカーソルを移動するを指示
}
/*******************************************************************************
*  メインの処理                                                                *
*******************************************************************************/
void main()
{
     int  i ;
     char s[17] ;
     char mes[6]= {0xbd,0xc0,0xb0,0xc4,0x00} ;  // "スタート"文字のカタカナデータ
	
     OSCCON = 0b01110100 ;    // 内部クロックは8MHzとする
     ADCON1 = 0b00000110 ;    // アナログは使用しない、RA0-RA4をデジタルI/Oに割当
     TRISA  = 0b00000000 ;    // 1で入力 0で出力 RA0-RA7全て出力に設定(RA5は入力専用)
     TRISB  = 0b00000000 ;    // RB0-RB7全て出力に設定

     /* LCDの初期化処理を行う */
     lcd_init() ;
     /* 1行目に"スタート"を表示 */
     lcd_puts(mes) ;

     i = 0 ;
     while(1) {
          // 2行目を消す
          lcd_setCursor(0,1) ;
          lcd_puts("                ") ;
          // カーソルを2行目の先頭に移動する
          lcd_setCursor(0,1) ;
          // 整数値を文字列に変換してLCD表示
          itoa(s,i,10) ;
          lcd_puts(s) ;
          i++ ;
          // 1秒間遅延する
          Wait(100) ;
     }
}
---------------------------------------------------------------------
CコンパイルPIC書き込みを実行して下さい。

DPICをブレッドボードに取付けてみて下さい。
 "スタート"文字が表示され、数値が1秒毎にカウントアップしていくと思います。

《やさしく解説》

半固定抵抗について

画面のコントラスト調整用です。
ツマミを右に回すとLCDに表示される文字が濃くなります、左に回すと薄くなります。

抵抗について

LCDの15と16番ピンはバックライト用の電源ですが、4.2V 40mAが仕様の様です。
よって、抵抗値は20〜100Ω辺りを取付ければOKと思います。

プログラムについて

プログラムソースのコメントを読んでもらえば大体何をしているのか分かると思います。

lcd_init()
 LCDを使用する為の初期化を行います。
 初期化時のLCDの動作は関数内に記述しているコメントを読んで下さい。

lcd_clear()
 画面を消去して、カーソルは col=0,row=0 に移動します。

lcd_setCursor(col,row)
 カーソル位置を移動させます、移動後はその位置から文字が表示されます。
  col : 横(列)方向のカーソル位置(0-15)
  row : 縦(行)方向のカーソル位置(0-1)

lcd_putc(c)
 1バイトの文字を表示します。
 表示可能バイトは0x20〜0x7fまでと0xa0〜0xffまでの範囲(下のコード表)です。

lcd_puts(s)
 文字列を表示します。
 文字列はNULL(0x00)まで出力されます。

その他のLCD機能を利用した関数はこちらに纏めてあります、参考にして下さい。

itoa(s,val,base)
 整数値(int)を数値文字に変換します。
 s : 変換した文字列を格納するバッファを指定する
 val : 変換する整数値(-32767〜32767)を指定する
 base: 10を指定すると10進数に変換する 16を指定すると16進数に変換する
 例)itoa(s,255,10)ならs="255" で itoa(s,255,16)ならs="FF" となる
 また、itoa()を使用する場合は#include <stdlib.h>をインクルード(記述)します。
 尚、この関数は340バイトほどプログラムメモリーを消費します。

char mes[6]= {0xbd,0xc0,0xb0,0xc4,0x00} ; // "スタート"文字のカタカナデータ
 LCDにカタカナの”ス”を表示させるには、下記のLCDキャラクタコード表を見て下さい。
 ”ス”のある場所は、縦列の[BO]で横列は[0D]です、でコードは[BD]となりデータを0xbdで指定します。
 また、上の青文字0x00はデータの最後に必ず入れます、でないと文字列の最後が判断できません。

《LCDキャラクタコード表》

00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
00 @ ` α
01 а
02 " β θ
03 ε
04 μ Ω
05 σ ц
06 ρ Σ
07 π
08 x
09 ¬
0A
0B ×
0C , ¢
0D - ÷
0E
0F / _

LCD3
 このキャラクタは、一覧コード表ではなくこの図が正解です。

 また、0x00〜0x0fには5x7ドットのキャラクターを登録できます。

《その他》

今回使用したピン以外の他のピンを使用する場合は下記の表を参照して下さい。
また、4番ピンRA5は入力しか出来ません、出力不可です。
ポートA
ピン番号 16 15 18 17
デジタル入出力ビット名 RA7 RA6 RA5 RA4 RA3 RA2 RA1 RA0

ポートB
ピン番号 13 12 11 10
デジタル入出力ビット名 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
LCDピン名称(番号) D7(14) D6(13) D5(12) D4(11) E(6) RS(4)

Arduino編   :グラフィックLCDに表示する関連記事はこちらを参照下さい。
PIC16F819編 :グラフィックLCDに表示する関連記事はこちらを参照下さい。
PIC16F1938編:グラフィックLCDに表示する関連記事はこちらを参照下さい。 (*1)
PICで”秋月電子I2C接続小型LCDモジュール(AQM0802A)に表示を行う”記事はこちらを参照下さい。 (*2)



一部変更(*4) 2015/10/14
追記(*3) 2014/01/25
追記(*2) 2013/07/25
追記(*1) 2011/12/12


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2015 Shigehiro Kimura All Rights Reserved.