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

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

秋月電子から販売されているSPI 超小型グラフィックCLCDモジュール(AQM1248A) を接続しました。 AQM1248Aは、128x48ドットの表示エリアがあり、LCDに内蔵された表示データRAMにSPI通信で、グラフィックパターンを書き込めば、対応したLCDドットがON/OFFし、画面表示されます。PICから送信するタイミングは、アイドル時のクロックは、「Hi」、クロックのの立下でデータを変更する Mode II のSPIです。

プログラム

画面ほぼ中央に「こんにちは!」と表示するだけのプログラムです。「こんにちは!」は、縦16bitの高さがあるため、上下2分割し、上半分は表示RAMのPage2に、下半分はPage3に、8bitのグラフィックパターンを送信しています。
グラフィック表示の大まかな手順は以下の通りです。

  1. LCD_int() で表示器を初期化し、
  2. LCD_posyx() で表示位置を指定し、
  3. LCD_ram()でグラフィックパターンをLCDの表示データRAMに書き込みます

実用的なプログラム例は、ライブラリ "AQM1248A.h" を参照してください。このライブラリでは、文字を3倍に拡大して見やすく表示するためのプログラム関数も準備してあります。

<プログラム>

// **************************************************************
//  File name: SPI グラフィックLCDに「こんにちは!」と表示
//
//     RC4  SPI_RS     0:コマンド  1:データ
//     RC5  SPI_CS     0:有効      1:無効
//     RC7  SPISDO
//     RB6  SPISCK     idle時:Hi   SCKの立下でデータ変更
//  Language: MPLABX XC8
//  Target: PIC18F14K50
//  Copyright (c) 2014 iwamoto All Rights Reserved
// **************************************************************

#include <xc.h>
#define _XTAL_FREQ 16000000      // delay_ms(x) のための定義

#define SPI_RS   LATCbits.LATC4
#define SPI_CS   LATCbits.LATC5

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

// プロトタイプ ------------------------------------------------------
void LCD_int (void);
void LCD_cmd (char );
void LCD_ram (char );
void LCD_clr (void );
void LCD_posyx (char, unsigned char );

// 表示データ「こんにちは!」のビットパターン ------------------------
const char PatUp[]={
        0x00,0x0C,0x1C,0x78,0x78,0x38,0x3C,0x1C,0x00,0x00,    // "こ"上半分
        0x00,0x00,0x80,0xF0,0xFE,0x3E,0x0C,0x00,0x00,0x00,    // "ん"
        0xE0,0xFE,0x1E,0x00,0x30,0x38,0x78,0x78,0x30,0x00,    // "に"
        0x30,0x70,0xF2,0xFF,0x3E,0xB0,0xB8,0x38,0x18,0x00,    // "ち"
        0xE0,0xFE,0x1E,0xC0,0xE0,0xE2,0xFE,0xFE,0x70,0x30,    // "は"
        0x00,0x00,0x00,0x00,0xE0,0xFE,0xFE,0x0E,0x00,0x00     // "!"
        };
const char PatLo[]={
        0x1C,0x3E,0x70,0x70,0x70,0x70,0x70,0x78,0x38,0x00,    // "こ"下半分
        0xF0,0xFE,0x1F,0x07,0x3F,0xFF,0xE0,0xF0,0x78,0x00,    // "ん"
        0x3F,0x7F,0x30,0x00,0x38,0x38,0x70,0x70,0x38,0x18,    // "に"
        0x00,0x1C,0x1F,0x9F,0xC7,0xC3,0x63,0x7F,0x3E,0x00,    // "ち"
        0x7F,0xFF,0x30,0x00,0x78,0xEC,0xFF,0x7F,0x38,0x70,    // "は"
        0x00,0x00,0x00,0x00,0x6F,0x6F,0x00,0x00,0x00,0x00     // "!"
        };

void main(void){
    char i;
    OSCCON = 0b01110010;       // 内部クロック16Mhz

    SSPSTAT = 0b00000000;      //  SPI機能の設定
    SSPCON1 = 0b00110000;      //  FOSC_4, MODE_11, SMPMID

    ANSEL  = 0b00000000;       // I/O端子をすべてデジタル
    ANSELH = 0b00000000;
    LATC   = 0;                // PortCのすべてのビットを「0」
    SPI_CS = 1;                // SPI_CSを「1」にする
    TRISCbits.TRISC4 = 0;      // SPI_RSを出力に設定
    TRISCbits.TRISC5 = 0;      // SPI_CSを出力に設定
    TRISCbits.TRISC7 = 0;      // SPISDOを出力に設定
    TRISBbits.TRISB6 = 0;      // SPISCKを出力に設定

    LCD_int ();                // LCDを初期化
    LCD_clr ();                // データを全消去
    LCD_cmd (0x40);            // Start address を 0

    // ------------------------------------------------------------
    // 「こんにちは!」表示パターンを LCD 表示データRAMMに転送
    // ------------------------------------------------------------
    LCD_posyx (2, 30);         // LCD 表示データRAMMのアドレス指定
    for(i=0; i<60; i++) {      // 表示データをLCD RAMに書き込む
        LCD_ram (PatUp[i]);
    }
    LCD_posyx (3, 30);         // LCD 表示データRAMMのアドレス指定
    for(i=0; i<60; i++) {      // 表示データをLCD RAMに書き込む
        LCD_ram (PatLo[i]);
    }
    while(1);
}

// --------------------------------------------------------------
// 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/revers = normal(白黒反転しない)
    LCD_cmd (0xAF);        // Display = ON
}

// --------------------------------------------------------------
// 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の表示データRAMMにデータを一バイト送信する
// --------------------------------------------------------------
void LCD_ram (char dat){
    SPI_CS = 0;
    SPI_RS = 1;                    // 表示RAMを指定
    SSPBUF = dat;                  // データの送信を開始
    while(!SSPSTATbits.BF);        // 送信完了を待つ
    dat = SSPBUF;                  // BFをリセットするため空読み
    SPI_CS = 1;
}
// --------------------------------------------------------------
// G-LCDの表示データRAMMを全消去する
// --------------------------------------------------------------
void LCD_clr (void){
    char i,j;
    for(j=0; j<8; j++) {        // RAMMのPage 0 - 7 を順に消去
    LCD_posyx (j, 0);              // LCD 表示データRAMMのアドレス指定
        for(i=0; i<128; i++) {
            LCD_ram (0);           // 全カラムを消去
        }
    }
}
// --------------------------------------------------------------
// 表示データRAMアドレス指定
// --------------------------------------------------------------
void LCD_posyx(char ypos, unsigned char xpos){
    LCD_cmd(0xB0 | ypos);           //ページを指定
    LCD_cmd(0x10 | (xpos >> 4));    //ページ内RAMアドレスを
    LCD_cmd(xpos & 0xF);            //  分割し指定
}