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

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
I2C接続LCD表示器(ストロベリーリナックス社製)

I2Cで超小型16文字x2行のLCD表示器を接続しました。MSSPをI2C マスターモードで利用します。
パラレル接続の場合は、6本の信号線、コントラスト調整線、電源の計9本の配線が必要ですが、I2C接続すれば、信号線は2本で済み、リセットと電源を含めても5本の配線です。 
パラレル接続のLCD表示器との共通性を持たせています。

プログラム

文字やアイコンを画面に表示するだけのプログラムです。
プログラムは、メインプログラム(main.c)とLCD表示ライブラリ(L_i2cLCD.h、L_i2cLCD.c)から構成されています。
  L_i2cLCD.c にLCD表示する手順が記載されており、
  L_i2cLCD.h には、クロックを変更した場合に手直しをするべき、遅延定数と電圧を変更したときに指定する画面コンスタント定数が定義されています。メインプログラムは、これらライブラリに登録されている関数を呼び出して、文字やアイコンを表示させます。
具体的には、以下の手順で表示します。

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

登録されている関数は、パラレル接続のLCDライブラリと共通性を持っています。

<プログラム>
main.c

//***************************************************************
//    ストロベリーリナックス社I2C LCD表示器への書き込みテスト
//    「LCD Disp Test」と液晶表示する。
//     1)Define I/O PORT
//         PORTB(4)pin13    :  SDA
//         PORTB(6)pin11    :  SCL
//     2)OSC
//         内部クロック  4MHz
//    Language: MPLABX XC8
//    Target: PIC18F14K50
// Copyright (c) 2012 iwamoto All Rights Reserved
//***************************************************************/

#include <xc.h>
#include "L_i2cLCD.h"    //I2C接続LCD関数

//-------------- コンフィグレーション ------------------------
#pragma config FOSC = IRC        //  内部クロック
#pragma config USBDIV = OFF, CPUDIV = NOCLKDIV
#pragma config IESO  = OFF, FCMEN = OFF, PLLEN  = ON
#pragma config BORV  = 30,  BOREN = OFF, PWRTEN = OFF
#pragma config WDTPS = 32768, WDTEN = OFF
#pragma config MCLRE = OFF, HFOFST = OFF, XINST  = OFF
#pragma config BBSIZ = OFF, LVP    = OFF, STVREN = ON
#pragma config CP1  = OFF, CP0  = OFF, CPD  = OFF, CPB  = OFF
#pragma config WRT1 = OFF, WRT0 = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR1 = OFF, EBTR0 = OFF, EBTRB  = OFF
//

//****** メイン関数   ************************
void main(void){
    char msgStart[] ="LCD Disp Test";

    OSCCON = 0b01010010;   //  内部クロック4Mhz
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    TRISA = 0b11111111;   //PortA すべて入力
    TRISB = 0b11111111;   //PortB すべて入力
    TRISC = 0b11111111;   //PortC すべて入力
    ANSEL  = 0b00000000;  //すべてデジタル
    ANSELH = 0b00000000;

    LCD_int();                 // LCDを初期化
    LCD_str(msgStart);         // LCD上段に"LCD Disp Test"

    LCD_posyx(1,1);            // 下段にカーソル移動
    LCD_dat('I');              // 下段に"I2C  "表示
    LCD_dat('2');
    LCD_dat('C');
    LCD_dat(' ');
    LCD_ROMstr("interface");   // 下段に"interface"追記
    LCD_icon_clr();            // 全アイコン消去
    LCD_icon_on(i_Ant);        // アイコン点灯  アンテナ
    LCD_icon_on(i_Lock);       //                 鍵
    LCD_icon_on(i_BatFUL);     //                 バッテリー満
    LCD_icon_on(i_Circle);     //                 三重丸
    while(1);
}

L_LCD.h

//*************************************************************
// I2C LCD ライブラリ PIC18  Ver 2.0 20130512
// 以下の機能を提供する
//
//    LCD_int()     ----- 初期化(I2C初期化を含む)
//    LCD_cmd(cmd)  ----- コマンド出力
//    LCD_dat(chr)  ----- 1文字表示
//    LCD_str(*str) ----- 文字列表示
//    LCD_ROMstr(*str) -- ROM文字列表示
//    LCD_hex(char);
//    LCD_posyx(y,x) ---- カーソル位置指定、行 y、横位置 x
//    LCD_clr()     ----- 全消去
//    LCD_icon_on(icn); -- 指定アイコン ON
//    LCD_icon_off(icn);-- 指定アイコン OFF
//    LCD_icon_clr();----- 全アイコン OFF
//
//液晶表示器とPICはI2Cにより接続される
//     1)Define I/O PORT
//         PORTB(4)pin13    :  SDA
//         PORTB(6)pin11    :  SCL
//     2)OSC
//         内部クロック 4MHz
//
// Copyright (c) 2012-2013 iwamoto All Rights Reserved
//************* Delay *******************************************
// 必要とするディレイ時間をクロック周波数から計算し、
// 指定するために、クロック周波数を指定する。
//***************************************************************
#define _XTAL_FREQ 4000000

//
//*************** Delay Define for 4MHz Clock*********
#define  Delay_50uS   __delay_us(50)
#define  Delay_2mS    __delay_ms(2)
#define  Delay_100mS  __delay_ms(100)
//********************************
//  調整用定数
//*********************************
#define CONTRAST  0x2D          // for 3.3V
// #define CONTRAST  0x18               // for 5.0V

//********************************
//  ボーレート定数
//********************************
// --------- for  4MHz ------------
#define SlewCont   SLEW_OFF    // Slew Rate 100K
#define BaudConst  0x09        // BRG Value for 4MHz

// --------- for  48MHz ------------
//#define SlewCont   SLEW_ON     // Slew Rate 400K
//#define BaudConst  0x1D        // BRG Value for 48MHz

//********************************
//  アイコン定数
//*********************************
#define i_Ant  0x4010           // アンテナ
#define i_Tel  0x4210           // 電話
#define i_Aud  0x4410           // 音声
#define i_Pulg  0x4610          // 接続
#define i_Up  0x4710            // Up
#define i_Dn  0x4708            // Down
#define i_UpDn  0x4718          // Down
#define i_Lock  0x4910          // 鍵
#define i_XFlag  0x4B10         // X旗
#define i_BatEMP  0x4D02        // バッテリー空
#define i_BatLOW  0x4D12        // バッテリー小
#define i_BatMID  0x4D1A        // バッテリー中
#define i_BatFUL  0x4D1E        // バッテリー満
#define i_Circle  0x4F10        // 三重丸

//******************* 提供機能 *******************************
void LCD_dat(char chr);
void LCD_cmd(char cmd);
void LCD_clr(void);
void LCD_int(void);
void LCD_str(char *str);
void LCD_posyx(char ypos,char xpos);
void LCD_icon_on(int icn);
void LCD_icon_off(int icn);
void LCD_icon_clr(void);
void LCD_ROMstr(const char *);
void LCD_hex(char);

L_LCD.c

////////////////////////////////////////////////////////////
// I2C LCD ライブラリ PIC18  Ver 2.0 20130512
//  ストロベリーリナックス液晶表示ライブラリ
//  以下の機能を提供
//    LCD_int()     ----- 初期化
//    LCD_cmd(cmd)  ----- コマンド出力
//    LCD_dat(chr)  ----- 1文字表示
//    LCD_str(*str) ---- 文字列表示
//    LCD_ROMstr(*str) -- ROM文字列表示
//    LCD_hex(char);
//    LCD_posyx(y,x) ---- カーソル位置指定、行 y、横位置 x
//    LCD_clr()      ----- 全消去
//    LCD_icon_on(icn);--- 指定アイコンON
//    LCD_icon_off(icn);-- 指定アイコンOFF
//    LCD_icon_clrf();---- 全アイコンOFF
//液晶表示器とPICはI2Cにより接続される
//     1)Define I/O PORT
//         PORTB(4)pin13    :  SDA
//         PORTB(6)pin11    :  SCL
//     2)OSC
//         内部クロック 4MHz
//
// Copyright (c) 2012-2013 iwamoto All Rights Reserved
////////////////////////////////////////////////////////////

#include <xc.h>
#include "L_i2cLCD.h"

void _EEByteWrite(char, char, char);
void _i2cTx(char);

void _EEByteWrite(char addr, char cont, char data){
    SSPCON2bits.SEN = 1;     // Start condition 開始
    while(SSPCON2bits.SEN);  // Start condition 確認
    _i2cTx(addr);            // アドレス送信
    _i2cTx(cont);            // 制御コード送信
    _i2cTx(data);            // データ送信
    PIR1bits.SSPIF = 0;      // 終了フラグクリア
    SSPCON2bits.PEN = 1;     // Stop condition 開始
    while(SSPCON2bits.PEN);  // Stop condition 確認
}

void _i2cTx(char data){
    PIR1bits.SSPIF = 0;      // 終了フラグクリア
    SSPBUF = data;           // データセット
    while(!PIR1bits.SSPIF);  // 送信終了待ち
}

//-------- 1文字表示
void LCD_dat(char chr){
    _EEByteWrite(0x7C, 0x40, chr);
    Delay_50uS;              // 50μsec
}
//-------- コマンド出力
void LCD_cmd(char cmd){
    _EEByteWrite(0x7C, 0x00, cmd);
    if(cmd & 0xFC)           // 上位6ビットに1がある命令
        Delay_50uS;          // 50usec
    else
        Delay_2mS;           // 2msec ClearおよびHomeコマンド
}
//-------- 全消去
void LCD_clr(void){
    LCD_cmd(0x01);           //Clearコマンド出力
}
//-------- カーソル位置指定
void LCD_posyx(char ypos, char xpos){
    unsigned char pcode;
    switch(ypos & 0x03){
        case 0:    pcode=0x80;break;
        case 1:    pcode=0xC0;break;
        case 2:    pcode=0x94;break;
        case 3:    pcode=0xD4;break;
    }
    LCD_cmd(pcode += xpos);
}
//-------- 文字列出力
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
}
//-------- 16進文字変換表示
void LCD_hex(char c){
    const char hexch[] ="0123456789ABCDEF";
    LCD_dat(hexch[c >> 4]);
    LCD_dat(hexch[c & 0xF]);
}

//-------- 初期化
void LCD_int(void){
    SSPCON1 = 0x28;          //I2Cマスターモード指定
    SSPSTAT = 0x00;
    SSPADD = BaudConst;      //Board Rate
    Delay_100mS;
    LCD_cmd(0x38);           // 8bit 2行 表示命令モード
    LCD_cmd(0x39);           // 8bit 2行 拡張命令モード
    LCD_cmd(0x14);           // OSC  BIAS 設定1/5
                             // コントラスト設定
    LCD_cmd(0x70 + (CONTRAST & 0x0F));
    LCD_cmd(0x5C + (CONTRAST >> 4));
    LCD_cmd(0x6B);           // Ffollwer
    Delay_100mS;
    Delay_100mS;
    LCD_cmd(0x38);           // 表示命令モード
    LCD_cmd(0x0C);           // Display On
    LCD_cmd(0x01);           // Clear Display
}
//-- 指定アイコン ON
void LCD_icon_on(int icn){
    LCD_cmd(0x39);            // 拡張命令モード
    LCD_cmd(icn >> 8);        // Icon アドレス
    LCD_dat(icn & 0xFF);      // Icon ビット <ON>
    LCD_cmd(0x38);            // 表示命令モード
}
//-- 指定アイコン OFF
void LCD_icon_off(int icn){
    LCD_cmd(0x39);            // 拡張命令モード
    LCD_cmd(icn >> 8);        // Icon アドレス
    LCD_dat(0x00);            // Icon ビット <OFF>
    LCD_cmd(0x38);            // 表示命令モード
}
//-- 全アイコン OFF
void LCD_icon_clr(void){
    unsigned char icn = 0x40;
    LCD_cmd(0x39);            // 拡張命令モード
    while(icn <= 0x4F){
        LCD_cmd(icn++);       // Icon アドレス
        LCD_dat(0x00);        // Icon ビット <OFF>
    }
    LCD_cmd(0x38);            // 表示命令モード
}