株式会社ジーテック

制御機器を小ロット多品種で設計製作

グラフィックLCDモジュール(LM320240CFW)を使ってみる

TOPWAYのLM320240CFWというグラフィックLCDが入手できたので試してみたいと思います。なかなかの解像度があり、バックライトもついていて視認性も悪くないです。

※注意:マイコンボードは3.3Vを使用して下さい。

OLYMPUS DIGITAL CAMERA
OLYMPUS DIGITAL CAMERA
使用機器

使用機器は下記のとおり。他、パソコンや電源、PICKIT2又はPICKIT3も当然ながら必要です。使い方はいたってシンプル。
lm320240cfw.cをmain.cの頭でインクルードし、起動時にlcd_ini()で初期化します。

テキストを表示する場合は、
lm320240cfw_line = 0;で、表示する行位置を指定し、
lm320240cfw_cursor = 0; で、横位置を指定し、
printf(lcd_char,”27| AN0 = %04lumV , RA1 = %u “,analog_value,port1_ra1);で、テキストデータをバッファに展開し、
lcd_buffer_set(lm320240cfw_line);で、バッファデータをポートから出力します。

イメージを表示させる場合は、
lm320240cfw_line = 0;で、表示する行位置を指定し、
lcd_bufferを直接修正するか set_dot関数を使ってイメージデータを作り、
lcd_buffer_set(lm320240cfw_line);で、バッファデータをポートから出力します。

LCDのデータシートLM320240CFW.zip
マイコンボード(PIC16F1947搭載)ZEATEC co.,ltd. ZT-PIC16F194701(3.3V仕様)

プロジェクトファイルも含めたサンプル zt-16f194701_lm320240cfw.zip
接続ハーネスの図面 
Harness_LM320240CFW.zip Harness_LM320240CFW LCD.pdf
開発環境:MPLAB_IDE_8_92 + CCS-C PCMコンパイラVer.4.132

lm320240cfw.cの中身
/*******************************************************************************
グラフィックLCDモジュール(TOPWAY LM320240CFW)用ライブラリ 2017/08/04作成

□提供元
ZEATEC co.,ltd. 

□ご利用について
転載・無断使用可です。このライブラリを使用した上での不具合等に関しては、いかなる内容におい
ても一切の責任を追わないものとします。

□使用方法
lcd_ini()をスタートアップに入れ、用途に合わせて出力処理を定期的(0.1sec単位ぐらい)に実行す
る。出力処理についてはすべてのデータを出力するとリフレッシュに時間がかかるため必要な部分の
みの出力としたほうがいい。
フォントのデータはfont_data.cを修正することで記号なども追加できます。
テキストの場合は行番号を指定してからテキストを送信。
lm320240cfw_line = 0;
lm320240cfw_cursor = 0; 
printf(lcd_char,"27|                          AN0 = %04lumV , RA1 = %u  ",analog_value,port1_ra1);
lcd_buffer_set(lm320240cfw_line);
イメージの場合はset_dot()関数を使用するかlcd_bufferを直接更新してください。


□接続方法
RE0 = DB0
RE1 = DB1
RE2 = DB2
RE3 = DB3
RE4 = DB4
RE5 = DB5
RE6 = DB6
RE7 = DB7
RF0 = /WR
    0:Write enable input
RF1 = A0
    1: command write, display data or cursor add read 
    0: status flag read, display data or parameter write    
RF2 = /RES 1:Run 0:ini

上記以外の配線はLCDモジュール上またはハーネスによってVDDおよびVSSと接続する。
BLA = VDD
VSS to VOUT:VR47kohm V0:adjust
*******************************************************************************/
//ポート設定
#define _WR PIN_F0
//#define _RD PIN_F1
//#define _CS PIN_F2
#define A0 PIN_F1
#define _RES PIN_F2
//#define A0 PIN_F3
//#define _RES PIN_F4

void lcd_ini();
void lcd_cmd(int cmd);
void lcd_data(int dat);
void lcd_write();
void set_dot(long x,int y,int value);

long lm320240cfw_cursor = 0;
int lm320240cfw_line = 0;

int lcd_buffer[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //40byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //80byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //120byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //160byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //200byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //240byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //280byt
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//320byt

//表示位置を指定して表示する
void lcd_buffer_set(int line){
    int tmp1 = 0;
    int x = 0;
    long y = line * 8;
    int width = 40;
    int high = 8;

    int i,j;
    long addr = 0;
    long tmp2 = 0;

    addr = y * 40;
    for(i=0;i<high;i++){
        lcd_cmd(0x46);
        lcd_data(addr);
        lcd_data(addr>>8);
        lcd_cmd(0x4c);
        lcd_cmd(0x42);
        for(j=0;j<width;j++){
            tmp1 = lcd_buffer[tmp2];
            lcd_data(tmp1);
            tmp2=tmp2+1;
        }
        addr = addr + 0x28;
    }
}

//指定位置にドット描画します。
//x:0~319
//y:0~7
void set_dot(long x,int y,int value){
    long tmp_x = x + (y * 320);
    int tmp_value = value;

    long tmp_bit = 0;
    int tmp1 = 0;
    long tmp_index = 0;

    if(tmp_x >= 8){

        tmp_bit = tmp_x % 8;
        tmp_index = (tmp_x - tmp_bit) / 8;
    }else{
        tmp_bit = tmp_x;
    }
    
 //反転
    if(tmp_bit == 7){      tmp_bit = 0;
    }else if(tmp_bit == 6){ tmp_bit = 1;
    }else if(tmp_bit == 5){ tmp_bit = 2;
    }else if(tmp_bit == 4){ tmp_bit = 3;
    }else if(tmp_bit == 3){ tmp_bit = 4;
    }else if(tmp_bit == 2){ tmp_bit = 5;
    }else if(tmp_bit == 1){ tmp_bit = 6;
    }else if(tmp_bit == 0){ tmp_bit = 7;}

    if(tmp_value == 0){
        bit_clear(lcd_buffer[tmp_index],tmp_bit);
    }else{
        bit_set(lcd_buffer[tmp_index],tmp_bit);
    }
}

//テキストを表示する
void lcd_char(char c){

    int tmp1 = 0;
    
    for(tmp1 = 0;tmp1<5;tmp1++){
        set_dot(lm320240cfw_cursor+tmp1,0,bit_test(font[c-0x20][tmp1],0));  
        set_dot(lm320240cfw_cursor+tmp1,1,bit_test(font[c-0x20][tmp1],1));
        set_dot(lm320240cfw_cursor+tmp1,2,bit_test(font[c-0x20][tmp1],2));
        set_dot(lm320240cfw_cursor+tmp1,3,bit_test(font[c-0x20][tmp1],3));
        set_dot(lm320240cfw_cursor+tmp1,4,bit_test(font[c-0x20][tmp1],4));
        set_dot(lm320240cfw_cursor+tmp1,5,bit_test(font[c-0x20][tmp1],5));
        set_dot(lm320240cfw_cursor+tmp1,6,bit_test(font[c-0x20][tmp1],6));
        set_dot(lm320240cfw_cursor+tmp1,7,bit_test(font[c-0x20][tmp1],7));
    }

 //文字と文字の間に空白を入れる
    set_dot(lm320240cfw_cursor+5,0,0);  
    set_dot(lm320240cfw_cursor+5,1,0);
    set_dot(lm320240cfw_cursor+5,2,0);
    set_dot(lm320240cfw_cursor+5,3,0);
    set_dot(lm320240cfw_cursor+5,4,0);
    set_dot(lm320240cfw_cursor+5,5,0);
    set_dot(lm320240cfw_cursor+5,6,0);
    set_dot(lm320240cfw_cursor+5,7,0);

 //1文字分カーソル位置を残す
    lm320240cfw_cursor = lm320240cfw_cursor + 6;
}

//LCDにコマンド送信
void lcd_cmd(int cmd){
    output_bit(_WR,1); // init all control signal
 //output_bit(_RD,1);//省略
    output_bit(A0,1);// for command
    output_e(cmd);//LCDBUS = Command;
 //output_bit(_CS,0);// enable the access 省略
    output_bit(_WR,0);//_WR = 0;
    output_bit(_WR,1);//_WR = 1;
 //output_bit(_CS,1);// disable the access 省略
}

//LCDにデータ送信
void lcd_data(int dat){
    output_bit(_WR,1);//_WR = 1;                // init all control signal
 //output_bit(_RD,1);//省略
    output_bit(A0,0);//A0  = 0;                // for diaplay data
    output_e(dat);//LCDBUS = DData;
 //output_bit(_CS,0);//enable the access 省略
    output_bit(_WR,0);//_WR = 0;
    output_bit(_WR,1);//_WR = 1;
 //output_bit(_CS,1);// disable the access 省略
}

//LCDを初期化
void lcd_ini(){

 //ポート初期値
    output_bit(_RES,1);//_RES   = 1;
 //output_bit(_CS,0);//_CS     = 1;
 //output_bit(_RD,1);//_RD     = 1;
    output_bit(_WR,1);//_WR     = 1;
    output_bit(A0,1);//A0      = 1;

    output_e(0xff);//LCDBUS  = 0xff;         // pull up data bus
    
 //LCD初期化処理
    output_bit(_RES,1);//_RES    = 1;    // reset pin
    output_bit(_RES,0);//_RES    = 0;
    delay_ms(5);
    output_bit(_RES,1);//_RES    = 1;
    delay_ms(10);

    lcd_cmd(0x40); //System set (8 byte parameter)
    delay_ms(1);
    lcd_data(0x30);// IV=1(no line comp),ws=0(single drv),M2=0(8bit char height),M0=0(int CGROM), D4=1(by default)                    
    lcd_data(0x07);// MOD=1 two frame AC drv, HorChar Size=8
    lcd_data(0x07);// VerChar Size=8
    lcd_data(0x28);// (320/8=40) char per line
    lcd_data(0x47);// 23+blanking (frame freq = 66Hz (clk ratio=1/4  @ 10MHz)
    lcd_data(0xf6);// (240-1=239) line per screen
    lcd_data(0x28);// Virtual screen width LSB
    lcd_data(0x00);// Virtual screen width MSB
    
    lcd_cmd(0x59); // Display ON/OFF(1 byte parameter)
    lcd_data(0x04);// SAD1=on, cursor=off
        
    lcd_cmd(0x44); //Scroll (10 byte parmeter)
    lcd_data(0x00);// SAD1 start ADD LSB
    lcd_data(0x00);// SAD1 start ADD MSB
    lcd_data(0xEF);// SAD1 block size(no.of line-1)
    lcd_data(0x00);// SAD2 start ADD LSB 
    lcd_data(0x00);// SAD2 start ADD MSB
    lcd_data(0xEF);// SAD2 block size(no.of line-1)
    lcd_data(0x00);// SAD3 start ADD LSB
    lcd_data(0x00);// SAD3 start ADD MSB
    lcd_data(0x00);// SAD4 start ADD LSB
    lcd_data(0x00);// SAD4 start ADD MSB
    
    lcd_cmd(0x5D); //CSRFORM (2 byte parmeter)
    lcd_data(0x07);// cursor width = 8
    lcd_data(0x17);// CM=1, for graphic mode, cursor height = 8        
    
    lcd_cmd(0x4C); // CSRDIR (0 byte parmeter) to the right side

    lcd_cmd(0x5B); // OVLAY (1 byte parmeter)
    lcd_data(0x05);// 0v=0(2layer),DM1=0(blk3 for text),DM0=1(blk1 for graphic),layers combine=01(XOR) 

    lcd_cmd(0x5A); // HDOT SCR (1 byte parmeter)
    lcd_data(0x00);// no scroll

    lcd_cmd(0x60); // GRAYSCALE (1 byte parmeter)
    lcd_data(0x00);// 1bpp
}

void lcd_clear(){
    int tmp1 = 0;
    int tmp_pat = 0xaa;
    int x = 0;
    long y = 0;// * 8;
    int width = 40;
    int high = 8;

    int i,j;
    long addr = 0;
    long tmp2 = 0;

    for(tmp1 = 0;tmp1<30;tmp1++){
        y = tmp1 * 8;

        addr = y * 40;
        for(i=0;i<high;i++){
            lcd_cmd(0x46);
            lcd_data(addr);
            lcd_data(addr>>8);
            lcd_cmd(0x4c);
            lcd_cmd(0x42);
            for(j=0;j<width;j++){
             //tmp1 = lcd_buffer[tmp2];
                lcd_data(tmp_pat);
                tmp2=tmp2+1;
            }
            addr = addr + 0x28;
        }
    }
}

©ZEATEC co.,ltd.