PIC16F1455の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
SPI グラフィックLCD表示の接続(秋月電子)

秋月電子から販売されている超小型グラフィックLCDモジュール(AQM1248A)を接続しました。PICがマスターとなり、SPI MODE II で、データをLCDモジュールに送信します。グラフィックLCDモジュールに文字を表示させるには、PICが文字コードに対応するグラフィックパターンを作成し、LCDモジュールに送信します。 このプログラム例では、プロポーショナルの5x7ドットの文字データはAQM1248A.h に格納してあります。

LCD表示器のプログラム例

文字やアイコンを画面に表示するだけのプログラムです。プログラムは、LCD表示関連関数を呼び出して、文字を表示させます。具体的には、他のLCDと同様な以下の手順でプログラムします。

  1. LCD_int() で表示器を初期化し、
  2. LCD_posyx() で表示位置を指定し、
  3. LCD_dat()、LCD_str()、などの関数で文字を表示

*注意*
PIC16F1455のSPIピンは、ICSPピンと同一です。 PICにプログラムするためPICkit3を接続したままにすると、このピンがPICkit3内部で4.7kΩの抵抗でプルダウンされるため、SPI機能が動作しません。 正常に動作させるには、PICにプログラムを書き込んだ後で、PICkit3を回路から取り外す必要があります。

<プログラム> main.c

//*********************************************************
//  File name: SPI Mode II Grafic LCD
//             秋月 AQM1248A 用
//
//     RC0  SPISCK     idle時:Hi   SCKの立下でデータ変更
//     RC1  SPI_CS     0:有効      1:無効
//     RC2  SPISDO
//     RC3  SPI_RS     0:コマンド  1:データ
//    Language: MPLABX XC8
//    Target: PIC16F1455
// Copyright (c) 2012 iwamoto All Rights Reserved
//*********************************************************
#include <xc.h>
#include "AQM1248A.h"
#define  _XTAL_FREQ 16000000      // delay_ms(x) のための定義

//************* Config  ***********************************
#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = DISABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

//////////// Main //////////////////////////////////
void main(void){
    unsigned char i,ypos,xpos;
    OSCCON = 0b00111100;         // 内部クロック16Mhz
    ANSELC = 0;                  // PortCをデジタルI/Oにする
    mInitLCD_IO ();                 // LCD制御用I/O 設定
    mInitSPI();                     // SPI Mode II 設定
    LCD_int ();                     // Grafic LCD 初期設定
    ypos = 0; xpos = 10;                    // 文字表示位置
    xpos = LCD_ROMstr3x("ABC",ypos,xpos);   // 3倍文字列表示
    ypos = 1;
    xpos = LCD_ROMstr2x("ABC",ypos,xpos);   // 2倍文字列表示
    ypos = 2;
    xpos = LCD_ROMstr1x("ABC",ypos,xpos);   // 通常文字列表示

    LCD_posyx (4,20);                       // 文字表示位置
    LCD_dat('S');                           // 通常文字表示
    LCD_ROMstr("PI LCD AQM1248A");          // 通常文字列表示

    LCD_posyx (5,0);                        // 下段枠表示位置
    for(i=0; i<128 ; i+=2) {                // コラムデータを順に取得
        LCD_ram(0b11101000);                // 下段枠文様
        LCD_ram(0b11010000);
    }
    while(1);
}

AQM1248A.h

/********************************************************************
 FileName:      Grafic LCD  AQM1248A.h 用ライブラリ
 Processor:     PIC16F1455
 Compiler:      Microchip XC8

プロポーショナルな最大5x7dotの文字パターンを提供するとともに
以下の機能も実現する

  mInitLCD_IO()            G_LCDで使用するPICのI/Oピンを初期化する
  mInitSPI()               PICのSPI機能を初期化する

  LCD_int ()               G_LCDを初期化する
  LCD_cmd (cmd)            G_LCDにコマンドデータを送信する
  LCD_dat (chr)            文字コードchrを文字パターンに変換し
                                G_LCDに文字を表示する
  LCD_ram (dat)            G_LCDにグラフィックデータを送信する
  LCD_clr ()               G_LCDの表示RAMを全消去する
  LCD_posyx (ypos, xpos)   G_LCDの表示RAMをアドレスを指定する
  LCD_str(add)             PICのRAM領域にある文字列をG_LCDに表示する
  LCD_ROMstr(r_add)        PICのROM領域にある文字列をG_LCDに表示する

以下は、文字表示した後で、次の表示位置xposを返す
 xpos = LCD_chr1x(chr, ypos, xpos)      通常文字
 xpos = LCD_str1x(add, ypos, xpos)      RAM領域通常文字列
 xpos = LCD_ROMstr1x(add, ypos, xpos)   ROM領域通常文字列

 xpos = LCD_chr2x(chr, ypos, xpos)      2倍拡大文字
 xpos = LCD_str2x(add, ypos, xpos)      RAM領域2倍拡大文字列
 xpos = LCD_ROMstr2x(r_add, ypos, xpos) RAM領域2倍拡大文字列

 xpos = LCD_chr3x(chr, ypos, xpos)      3倍拡大文字
 xpos = LCD_str3x(add, ypos, xpos)      RAM領域3倍拡大文字列
 xpos = LCD_ROMstr3x(r_add, ypos, xpos) RAM領域3倍拡大文字列

引数の意味とデータ型
 cmd   : char型データ G_LCDへのコマンドデータ
 dat   : char型データ G_LCDへのグラフィックデータ
 chr   : char型データ G_LCDに表示する文字のコードデータ
 ypos  : char型データ G_LCDの表示RAMの縦(page)位置
 ypos  : unsigned char型データ G_LCDの表示RAMの横(column)位置
 add   : RAM領域の文字列開始アドレスポインタ
 r_add : ROM領域の文字列開始アドレスポインタ

  Copyright (c) 2014 iwamoto All Rights Reserved
********************************************************************
 File Description:

 Change History:
  Rev   Date         Description
  1.0   20014/1/2   Initial release
********************************************************************/

/******** プロトタイプ *************************/
void LCD_int (void);
void LCD_cmd (char );
void LCD_dat (char );
void LCD_ram (char );
void LCD_clr (void );
void LCD_posyx (char, unsigned char );
void LCD_str(char *);
void LCD_ROMstr(const char *);
unsigned char LCD_chr1x(char, char, unsigned char);
unsigned char LCD_str1x(char *, char, unsigned char);
unsigned char LCD_ROMstr1x(const char *, char, unsigned char);
unsigned char LCD_chr2x(char, char, unsigned char);
unsigned char LCD_str2x(char *, char, unsigned char);
unsigned char LCD_ROMstr2x(const char *, char, unsigned char);
unsigned char LCD_chr3x(char, char, unsigned char);
unsigned char LCD_str3x(char *, char, unsigned char);
unsigned char LCD_ROMstr3x(const char *, char, unsigned char);

/******** クロックの指定 *************************/
#ifndef _XTAL_FREQ
#define _XTAL_FREQ   16000000
#endif

/** Grafic LCD 制御関連I/O *********************************************
     RC3  SPI_RS     LCD データ種別         0:コマンド  1:表示データ
     RC1  SPI_CS     チップセレクト         0:有効      1:無効
************************************************************************/
    #define mInitLCD_IO()   LATC3=1;LATC1=1;TRISC3=0;TRISC1=0;

    #define SPI_RS          LATC3
    #define SPI_CS          LATC1

/******* SSP(SPI) ******************************************************
     SPI機能の設定   マスタモード、クロック = FOSC/4
        バスモード   アイドル時のクロック : Hi
        (MODE_11)    データ送信タイミング : クロックの立下
                     受信データサンプル   : SMPMID (送信だけのため NA)
     RC2/7  SPISDO     データ出力
     RC0/RB6  SPISCK     idle時:Hi   SCKの立下でデータ変更
************************************************************************/

    #define mInitSPI()    {TRISC2=0;TRISC0=0;SSPSTAT=0x00;SSPCON1=0x30;}

/******** キャラクタデータ (ASCII 0x20-0x7F) ************************
5x8 dot キャラクタデータを基本としているが、 
5dotない幅の狭いフォント(!など)は0xFFで終端を示している
*********************************************************************/

const unsigned char chrom[96][5]={
        {0x00,0x00,0xFF,0x00,0x00},     // 0x20, Space
        {0x5F,0xFF               },     // 0x21, ! x
        {0x00,0x07,0x00,0x07,0x00},     // 0x22, " x
        {0x14,0x7F,0x14,0x7F,0x14},     // 0x23, #
        {0x24,0x2A,0x7F,0x2A,0x12},     // 0x24, $
        {0x27,0x15,0x6B,0x54,0x72},     // 0x25, %
        {0x36,0x49,0x56,0x20,0x50},     // 0x26, &
        {0x0B,0x07,0x00,0xFF     },     // 0x27, ' x
        {0x1C,0x22,0x41,0xFF     },     // 0x28, ( x
        {0x41,0x22,0x1C,0xFF     },     // 0x29, ) x
        {0x2A,0x1C,0x7F,0x1C,0x2A},     // 0x2a, *
        {0x08,0x08,0x3E,0x08,0x08},     // 0x2b, + x
        {0x58,0x38,0xFF          },     // 0x2c, , x
        {0x08,0x08,0x08,0x08,0x08},     // 0x2d, -
        {0x60,0x60,0xFF          },     // 0x2e, . x
        {0x20,0x10,0x08,0x04,0x02},     // 0x2f, /
        {0x3E,0x51,0x49,0x45,0x3E},     // 0x30, 0
        {0x42,0x7F,0x40,0xFF     },     // 0x31, 1 x
        {0x72,0x49,0x49,0x49,0x46},     // 0x32, 2
        {0x22,0x41,0x49,0x49,0x36},     // 0x33, 3
        {0x18,0x14,0x12,0x7F,0x10},     // 0x34, 4
        {0x27,0x45,0x45,0x45,0x39},     // 0x35, 5
        {0x3C,0x4A,0x49,0x49,0x30},     // 0x36, 6
        {0x01,0x71,0x09,0x05,0x03},     // 0x37, 7
        {0x36,0x49,0x49,0x49,0x36},     // 0x38, 8
        {0x06,0x49,0x49,0x29,0x1E},     // 0x39, 9
        {0x36,0x36,0xFF,0x00     },     // 0x3a, : x
        {0x5B,0x3B,0xFF,0x00     },     // 0x3b, ; x
        {0x08,0x14,0x22,0x41,0xFF},     // 0x3c, < x
        {0x14,0x14,0x14,0x14,0x14},     // 0x3d, =
        {0x41,0x22,0x14,0x08,0xFF},     // 0x3e, > x
        {0x02,0x01,0x51,0x09,0x06},     // 0x3f, ?
        {0x32,0x49,0x79,0x41,0x3E},     // 0x40, @
        {0x7C,0x12,0x11,0x12,0x7C},     // 0x41, A
        {0x41,0x7F,0x49,0x49,0x36},     // 0x42, B
        {0x3E,0x41,0x41,0x41,0x22},     // 0x43, C
        {0x41,0x7F,0x41,0x41,0x3E},     // 0x44, D
        {0x7F,0x49,0x49,0x41,0x41},     // 0x45, E
        {0x7F,0x09,0x09,0x01,0x01},     // 0x46, F
        {0x3E,0x41,0x49,0x49,0x3A},     // 0x37, G
        {0x7F,0x08,0x08,0x08,0x7F},     // 0x48, H
        {0x41,0x7F,0x41,0xFF     },     // 0x49, I
        {0x20,0x40,0x41,0x3F,0x01},     // 0x4a, J
        {0x7F,0x08,0x14,0x22,0x41},     // 0x4b, K
        {0x7F,0x40,0x40,0x40,0x40},     // 0x4c, L
        {0x7F,0x02,0x0C,0x02,0x7F},     // 0x4d, M
        {0x7F,0x02,0x04,0x08,0x7F},     // 0x4e, N
        {0x3E,0x41,0x41,0x41,0x3E},     // 0x4f, O
        {0x7F,0x09,0x09,0x09,0x06},     // 0x50, P
        {0x3E,0x41,0x51,0x21,0x5E},     // 0x51, Q
        {0x7F,0x09,0x19,0x29,0x46},     // 0x52, R
        {0x26,0x49,0x49,0x49,0x32},     // 0x53, S
        {0x01,0x01,0x7F,0x01,0x01},     // 0x54, T
        {0x3F,0x40,0x40,0x40,0x3F},     // 0x55, U
        {0x07,0x18,0x60,0x18,0x07},     // 0x56, V
        {0x7F,0x20,0x18,0x20,0x7F},     // 0x57, W
        {0x63,0x14,0x08,0x14,0x63},     // 0x58, X
        {0x03,0x04,0x78,0x04,0x03},     // 0x59, Y
        {0x61,0x51,0x49,0x45,0x43},     // 0x5a, Z
        {0x00,0x7F,0x41,0x41,0xFF},     // 0x5b, [ x
        {0x02,0x04,0x08,0x10,0x20},     // 0x5c, ¥
        {0x41,0x41,0x7F,0x00,0xFF},     // 0x5d, ] x
        {0x04,0x02,0x01,0x02,0x04},     // 0x5e, ^
        {0x40,0x40,0x40,0x40,0x40},      // 0x5f, _
        {0x00,0x03,0x04,0xFF,0xFF},     // 0x60, ` x
        {0x20,0x54,0x54,0x54,0x38},     // 0x61, a
        {0x7F,0x28,0x44,0x44,0x38},     // 0x62, b
        {0x38,0x44,0x44,0x44,0xFF},     // 0x63, c x
        {0x38,0x44,0x44,0x28,0x7F},     // 0x64, d
        {0x38,0x54,0x54,0x54,0x18},     // 0x65, e
        {0x08,0x3F,0x09,0x09,0x02},     // 0x66, f
//        {0x08,0x54,0x54,0x54,0x3C},   // 0x67, g
        {0x18,0xA4,0xA4,0x9C,0x78},     // 0x67, g
        {0x7F,0x08,0x04,0x04,0x78},     // 0x68, h
        {0x44,0x7D,0x40,0xFF     },     // 0x69, i x
        {0x20,0x40,0x44,0x3D,0xFF},     // 0x6a, j x
        {0x7F,0x10,0x28,0x44,0xFF},     // 0x6b, k x
        {0x41,0x7F,0x40,0xFF     },     // 0x6c, l x
        {0x7C,0x04,0x78,0x04,0x78},     // 0x6d, m
        {0x7C,0x08,0x04,0x04,0x78},     // 0x6e, n
        {0x38,0x44,0x44,0x44,0x38},     // 0x6f, o
//        {0x7C,0x14,0x14,0x14,0x08},   // 0x70, p
//        {0x08,0x14,0x14,0x14,0x7C},   // 0x71, q
        {0xFC,0x18,0x24,0x24,0x18},     // 0x70, p
        {0x18,0x24,0x24,0x18,0xFC},     // 0x71, q
        {0x7C,0x08,0x04,0x04,0x08},     // 0x72, r
        {0x48,0x54,0x54,0x54,0x24},     // 0x73, s
        {0x04,0x3F,0x44,0x44,0xFF},     // 0x74, t x
        {0x3C,0x40,0x40,0x20,0x7C},     // 0x75, u
        {0x1C,0x20,0x40,0x20,0x1C},     // 0x76, v
        {0x3C,0x40,0x30,0x40,0x3C},     // 0x77, w
        {0x44,0x28,0x10,0x28,0x44},     // 0x78, x
        {0x0C,0x90,0x90,0x90,0x7C},     // 0x79, y
        {0x24,0x64,0x54,0x4C,0x24},     // 0x7a, z
        {0x08,0x36,0x41     ,0xFF},     // 0x7b, x
        {0x00,0x7F,0x00     ,0xFF},     // 0x7c, | x
        {0x41,0x36,0x08     ,0xFF},     // 0x7d, } x
        {0x02,0x01,0x02,0x04,0x02},     // 0x7e, ‾ x
        {0x7F,0x7F,0x7F,0x7F,0x7F},     // 0x7f, DELx
    };

AQM1248A.c

/********************************************************************
 FileName:      Grafic LCD            AQM1248A.c
 Dependencies:  See INCLUDES section
 Processor:     PIC16F1455
 Compiler:      Microchip XC8

  Copyright (c) 2014 iwamoto All Rights Reserved
********************************************************************
 File Description:

 Change History:
  Rev   Date         Description
  1.0   20014/1/2   Initial release
********************************************************************/
#include <xc.h>
#include "AQM1248A.h"

//-------- G-LCDを初期化する --------------------------------------
void LCD_int (void){
    LCD_cmd (0xAE);        // Display = OFF
    LCD_cmd (0xA0);        // ADC = normal
    LCD_cmd (0xC8);        // Common output = revers
    LCD_cmd (0xA3);        // bias = 1/7
                           //--内部レギュレータを順番にON
    LCD_cmd (0x2C);        // power control 1
    __delay_ms(2);         // 2mS遅延
    LCD_cmd (0x2E);        // power control 2
    __delay_ms(2);         // 2mS遅延
    LCD_cmd (0x2F);        // power control 3
                           //--コントラスト設定
    LCD_cmd (0x23);        // Vo voltage resistor ratio set
    LCD_cmd (0x81);        // Electronic volume mode set
    LCD_cmd (0x1C);        // Electronic volume value set
                           //--表示設定
    LCD_cmd (0xA4);        // display all point normal(全点灯しない)
    LCD_cmd (0x40);        // display start line = 0
    LCD_cmd (0xA6);        // Display normal(白黒反転しない)
    LCD_cmd (0xAF);        // Display = ON
    LCD_clr ();            // データRAMを全消去
}

//-------- G-LCDにコマンドを一文字送信する -----------------------
void LCD_cmd (char cmd){
    SPI_CS = 0;                  // チップセレクト有効
    SPI_RS = 0;                  // コマンドデータ指定
    SSPBUF = cmd;                // データの送信を開始
    while(!SSPSTATbits.BF);      // 送信完了を待つ
    cmd = SSPBUF;                // BFをリセットするため空読み
    SPI_CS = 1;                  // チップセレクト無効
}

//-------- G-LCD RAMに一バイト送信する ------------------------
void LCD_ram (char dat){
    SPI_CS = 0;                  // チップセレクト有効
    SPI_RS = 1;                  // 表示データ指定
    SSPBUF = dat;                // データの送信を開始
    while(!SSPSTATbits.BF);      // 送信完了を待つ
    dat = SSPBUF;                // BFをリセットするため空読み
    SPI_CS = 1;                  // チップセレクト無効
}

//-------- G-LCDに一文字表示する --------------------------------
void LCD_dat (char dat){
    char i,chptn;
    dat -= 0x20;                 //配列アドレスを計算
    for(i=0; i<5; i++) {         //コラムデータを順に取得
        chptn = chrom[dat][i];
        if(chptn == 0xFF)break;  //幅狭文字なら抜ける
        LCD_ram(chptn);          //コラムデータを転送
    }
    LCD_ram(0);                  //文字間隔を空ける
}

//-------- G-LCDのデータを全消去する ----------------------------
void LCD_clr (void){
    unsigned char i,j;
    for(j=0; j<8; j++) {         //ページを更新
        LCD_posyx (j,0);         //ページを指定
        for(i=0; i<128; i++) {   //ページ内RAMデータを順に
            LCD_ram (0);         //  クリア
        }
    }
}
//-------- カーソル位置指定 --------------------------------------
void LCD_posyx(char ypos, unsigned char xpos){
    LCD_cmd(0xB0 | ypos);        //ページを指定
    LCD_cmd(0x10 | (xpos >> 4)); //ページ内RAMアドレスを
    LCD_cmd(xpos & 0xF);         //  分割し指定
}

//-------- 文字列出力 --------------------------------------------
void LCD_str(char *str){
    while(*str)                  //文字列終端(00)まで継続
        LCD_dat(*str++);         //文字出力しポインタ+1
}

//-------- Rom 文字列出力 -----------------------------------------
void LCD_ROMstr(const char *str){
    while(*str)                  //文字列終端(00)まで継続
        LCD_dat(*str++);         //文字出力しポインタ+1
}

//-------- 文字表示  ---------------------------------------------
// 文字コード、表示位置(ypos, xpos)を指定する。
// 文字を表示後、次の表示開始位置 xpos を返す
//----------------------------------------------------------------
unsigned char LCD_chr1x(char dat, char ypos, unsigned char xpos){
    char i,chptn;
    dat -= 0x20;                 //配列アドレスを計算
    LCD_posyx( ypos, xpos);      //上半分の表示位置を指定
    for(i=0; i<5; i++) {         //コラムデータを順に取得
        chptn = chrom[dat][i];
        if(chptn == 0xFF)break;  //幅狭文字なら抜ける
        LCD_ram(chptn);          //コラムデータを転送
    }
    LCD_ram(0);                  //文字間隔を空ける
    return i + 1 + xpos;         //次の表示開始位置 xpos を返す
}

//-------- 文字列表示 ----------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// 文字を表示後、次の表示開始位置 xpos を返す
//------------------------------------------------------------
unsigned char LCD_str1x(char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr1x(*str++, ypos, xpos);  //文字出力し
    return xpos;                               //次表示位置を返す
}

//-------- 文字列表示 ROMエリア--------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// 文字を表示後、次の表示開始位置 xpos を返す
//-------------------------------------------------------------------
unsigned char LCD_ROMstr1x(const char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr1x(*str++, ypos, xpos);  //文字出力しポインタ+1
    return xpos;                               //次表示位置を返す
}

//-------- 拡大文字表示 --------------------------------------
// 文字コード、表示位置(ypos, xpos)を指定する。
// x2 サイズで文字を表示後、次の表示開始位置 xpos を返す
//------------------------------------------------------------
unsigned char LCD_chr2x(char dat, char ypos, unsigned char xpos){
    unsigned char wch,fnt,i;
    dat -= 0x20;                 //配列アドレスを計算
    LCD_posyx( ypos, xpos);      //上半分の表示位置を指定
    for(i=0;i<5;i++){            //
        wch = chrom[dat][i];     //キャラクタデータのLSB 4bit
        if(wch == 0xFF)break;    //情報を拡大してLCD RAMに転送
        fnt = 0;
        if(wch & 0b00000001)fnt  = 0b00000011;
        if(wch & 0b00000010)fnt |= 0b00001100;
        if(wch & 0b00000100)fnt |= 0b00110000;
        if(wch & 0b00001000)fnt |= 0b11000000;
        LCD_ram(fnt);  LCD_ram(fnt);
    }
     LCD_ram(0);  LCD_ram(0);

    LCD_posyx( ypos + 1, xpos);  //下半分の表示位置を指定
    for(i=0;i<5;i++){            //
        wch = chrom[dat][i];     //キャラクタデータのMSB 4bit
        if(wch == 0xFF)break;    //情報を拡大してLCD RAMに転送
        fnt = 0;
        if(wch & 0b00010000)fnt  = 0b00000011;
        if(wch & 0b00100000)fnt |= 0b00001100;
        if(wch & 0b01000000)fnt |= 0b00110000;
        if(wch & 0b10000000)fnt |= 0b11000000;
        LCD_ram(fnt);  LCD_ram(fnt);
    }
     LCD_ram(0);  LCD_ram(0);
    return (i + 1) * 2 + xpos;   //次の表示開始位置 xpos を返す
}

//-------- 拡大文字列表示 --------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// x2 サイズで文字を表示後、次の表示開始位置 xpos を返す
//--------------------------------------------------------------
unsigned char LCD_str2x(char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr2x(*str++, ypos, xpos);  //文字出力し
    return xpos;                               //次表示位置を返す
}

//-------- 拡大文字列表示 ROMエリア--------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// x2 サイズで文字を表示後、次の表示開始位置 xpos を返す
//-----------------------------------------------------------------------
unsigned char LCD_ROMstr2x(const char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr2x(*str++, ypos, xpos);  //文字出力しポインタ+1
    return xpos;                               //次表示位置を返す
}

//-------- 3倍拡大文字表示 Tri Font -----------------------------
// 文字コード、表示位置(ypos, xpos)を指定する。
// x3 サイズで文字を表示後、次の表示開始位置 xpos を返す
//---------------------------------------------------------------
unsigned char LCD_chr3x(char dat, char ypos, unsigned char xpos){
    unsigned char wch,fnt,i;
    dat -= 0x20;                 //配列アドレスを計算
    LCD_posyx( ypos, xpos);      //上半分の表示位置を指定
    for(i=0;i<5;i++){            //
        wch = chrom[dat][i];     //キャラクタデータのLSB 4bit
        if(wch == 0xFF)break;    //情報を拡大してLCD RAMに転送
        fnt = 0;
        if(wch & 0b00000001)fnt  = 0b00000111;
        if(wch & 0b00000010)fnt |= 0b00111000;
        if(wch & 0b00000100)fnt |= 0b11000000;
        LCD_ram(fnt);  LCD_ram(fnt);  LCD_ram(fnt);
    }

    LCD_posyx( ypos + 1, xpos);  //下半分の表示位置を指定
    for(i=0;i<5;i++){            //
        wch = chrom[dat][i];     //キャラクタデータのMSB 4bit
        if(wch == 0xFF)break;    //情報を拡大してLCD RAMに転送
        fnt = 0;
        if(wch & 0b00000100)fnt |= 0b00000001;
        if(wch & 0b00001000)fnt |= 0b00001110;
        if(wch & 0b00010000)fnt |= 0b01110000;
        if(wch & 0b00100000)fnt |= 0b10000000;
        LCD_ram(fnt);  LCD_ram(fnt);  LCD_ram(fnt);
    }

    LCD_posyx( ypos + 2, xpos);  //下半分の表示位置を指定
    for(i=0;i<5;i++){            //
        wch = chrom[dat][i];     //キャラクタデータのMSB 4bit
        if(wch == 0xFF)break;    //情報を拡大してLCD RAMに転送
        fnt = 0;
        if(wch & 0b00100000)fnt |= 0b00000011;
        if(wch & 0b01000000)fnt |= 0b00011100;
        if(wch & 0b10000000)fnt |= 0b11100000;
        LCD_ram(fnt);  LCD_ram(fnt);  LCD_ram(fnt);
    }
     LCD_ram(0);  LCD_ram(0);  LCD_ram(0);
    return (i + 1) * 3 + xpos;   //次の表示開始位置 xpos を返す
}

//-------- 3倍拡大文字列表示 --------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// x3 サイズで文字を表示後、次の表示開始位置 xpos を返す
//-----------------------------------------------------------------
unsigned char LCD_str3x(char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr3x(*str++, ypos, xpos);  //文字出力し
    return xpos;                               //次表示位置を返す
}

//-------- 3倍拡大文字列表示 ROMエリア--------------------------------------
// 文字列アドレス、表示位置(ypos, xpos)を指定する。
// x3 サイズで文字を表示後、次の表示開始位置 xpos を返す
//------------------------------------------------------------
unsigned char LCD_ROMstr3x(const char *str, char ypos, unsigned char xpos){
    while(*str)                                //文字列終端(00)まで継続
        xpos = LCD_chr3x(*str++, ypos, xpos);  //文字出力しポインタ+1
    return xpos;                               //次表示位置を返す
}