LCDモジュール(SC1602) 4bitモードライブラリー

icon 項目のみ表示/展開表示の切り替え

概要

主にSC1602(秋月電子通称のページに移動します)向けのLCD液晶表示用のライブラリである。
液晶モジュールと接続するポートはマクロで変更可能である。
busyフラグはチェックせずソフトウェアディレイで対応しているためクロック周波数が変更された場合はディレイの調整が必要
ユーザー定義キャラクタに対応しています。
使用する場合はlcd.hをインクルードしlcd.cをプロジェクトに追加してください
lcd_initをコールする前に以下のポートを出力にしてください。(GNDを除く)

;   接続方法
;   PIC18F14K50  SC1602
;       RC7 ----> DB7
;       RC6 ----> DB6
;       RC5 ----> DB5
;       RC4 ----> DB4
;       RC3 ----> E
;       RC2 ----> RS
;       GND       R/W

プログラムの説明

ソースファイル

以下のファイルで構成されている
lcd.c   ・・・ LCD表示用ライブラリ Version 1.00
lcd.h   ・・・ LCD表示用インクルードファイル Version 1.00

サブルーチン

以下のサブルーチンをサポート

lcd_init

液晶モジュールの初期化

lcd_clear

液晶表示をクリア

lcd_en

液晶表示設定 ブリンク カーソル制御

lcd_puts

カレントアドレスに文字列を書き込む

lcd_putc

カレントアドレスに文字を書き込む

lcd_ddram

カレントアドレスを設定

lcd_ddramxy

カレントアドレスを列行で設定

lcd_cgram

ユーザー定義キャラクタを設定。アドレスは8byte単位で指定

lcd_disp

液晶の先頭から文字列を表示。改行コード及び行数をオーバーした場合自動的に次の行に表示可能

ソースコード

lcd.h

/*
 * LCDモジュール(SC1602) 4bitモードライブラリー  Version 1.00
 * File:        lcd.c
 * Target:      PIC18F14K50 48Mhz
 * コンパイラ:   Microchip MPLAB XC8 C Compiler V1.20
 * 書き込み:     PICKit 3
 * リリース:     2013/09/29 15:00
 *
*/

#ifndef LCD_H
#define LCD_H

//  制御信号アドレス設定

#define LCD_E       PORTCbits.RC3
#define LCD_RS      PORTCbits.RC2
#define LCD_E_MASK  0b0001000
#define LCD_RS_MASK 0b0000100
#define LCD_ADS     PORTC

#define LCD_CMAX    16 //   液晶横方向文字数
#define LCD_RMAX     2 //   液晶表示行数

#define LCD_CLEAR   0b00000001
#define LCD_CURHOME 0b00000010
#define LCD_ENTRYM  0b00000100
    #define LCD_INC       0b10
    #define LCD_DEC       0b00
    #define LCD_SHIFT      0b1
    #define LCD_NONSHIFT   0b0
#define LCD_DISPM   0b00001000
    #define LCD_DISPON   0b100
    #define LCD_DISPOFF  0b000
    #define LCD_CURON     0b10
    #define LCD_CUROFF    0b00
    #define LCD_BLINKON    0b1
    #define LCD_BLINKOFF   0x0
#define LCD_SHIFTM  0b00010000
#define LCD_FUNCM   0b00100000
    #define LCD_8BIT   0b10000
    #define LCD_4BIT   0b00000
#define LCD_CGADS   0b01000000
#define LCD_DDADS   0b10000000

void lcd_init(void); //  LCD液晶を初期化
void lcd_disp(const unsigned char* buf); //  ホーム位置から文字列を液晶に表示 \nによる複数行および折り返し表示サポート
void lcd_clear(); //  液晶クリア
void lcd_puts(const char* buf); //  カレントアドレスに文字列を書き込む
void lcd_putc(char buf); //  カレントアドレスに1文字書き込む
void lcd_en(unsigned char d); //  液晶表示設定(ブリンク、カーソル制御)
void lcd_ddramxy(unsigned char x,unsigned char y); //  表示用メモリアドレス設定 列と行で指定
void lcd_ddram(unsigned char ads); //  表示用メモリアドレス設定
void lcd_cgram(unsigned char ads,unsigned char* buf); //  ユーザー定義キャラクタを設定
void lcd_out4(unsigned char data); //  4bit出力
void lcd_out8(unsigned char data); //  8bitを4bitに分割して出力

#endif  /* LCD_H */


lcd.c

/*
 * LCDモジュール(SC1602) 4bitモードライブラリー  Version 1.00
 * File:        lcd.c
 * Target:      PIC18F14K50 48Mhz
 * コンパイラ:   Microchip MPLAB XC8 C Compiler V1.20
 * 書き込み:     PICKit 3
 * リリース:     2013/09/29 15:00
 *
*/

#include <p18f14k50.h>
#include <plib\delays.h>
#include "lcd.h"

//  LCD液晶を初期化

void lcd_init(void){
    Delay1KTCYx(180);  //  15ms*(48MHz/4)=180,000

    LCD_RS=0;
    lcd_out4( LCD_FUNCM | LCD_8BIT ); //  8bit
    Delay1KTCYx( 60);  //   5ms*(48MHz/4)= 60,000

    lcd_out4( LCD_FUNCM | LCD_8BIT ); //  8bit
    Delay1KTCYx( 48);  //   4ms*(48MHz/4)= 48,000

    lcd_out4(  LCD_FUNCM | LCD_8BIT ); //  8bit
    Delay1KTCYx( 48);  //   4ms*(48MHz/4)= 48,000

    lcd_out4( LCD_FUNCM | LCD_4BIT); //  4bit
    Delay1KTCYx( 48);  //   4ms*(48MHz/4)= 48,000

    lcd_out8( LCD_FUNCM | LCD_4BIT | 0b1000 ); //  動作モード 4bit 1/Duty 5*7dot
    Delay1KTCYx( 48);  //   4ms*(48MHz/4)= 48,000

    lcd_out8( LCD_DISPM | LCD_DISPON | LCD_CURON | LCD_BLINKOFF ); // 表示on
    Delay1KTCYx( 2);  //  0.167ms*(48MHz/4)=  2,000 6th

    lcd_out8( LCD_ENTRYM | LCD_INC | LCD_NONSHIFT); // エントリーモード
    Delay1KTCYx( 2);  //  0.167ms*(48MHz/4)=  2,000

    lcd_clear();
}

//  液晶クリア

void lcd_clear(void){
    LCD_RS=0;
    lcd_out8( LCD_CLEAR );
    Delay1KTCYx(24);  //  2ms*(48MHz/4)=  24,000
}

//  液晶表示設定(ブリンク、カーソル制御)

void lcd_en(unsigned char d){
    LCD_RS=0;
    lcd_out8( LCD_DISPM | d);
    Delay10TCYx(48);  //  40μs*(48MHz/4)=  480
}

//  カレントアドレスに文字列を書き込む

void lcd_puts(const char* buf){
    LCD_RS=1;
    while(*buf){
        lcd_out8(*buf);
        Delay10TCYx(60);  //  50μs*(48MHz/4)=  600
        ++buf;
    }
}

//  カレントアドレスに1文字書き込む

void lcd_putc(unsigned char c){
    LCD_RS=1;
    lcd_out8(c);
    Delay10TCYx(60);  //  50μs*(48MHz/4)=  600
}

//  表示用メモリアドレス設定

void lcd_ddram(unsigned char ads){
    LCD_RS=0;
    lcd_out8( LCD_DDADS | ads );
    Delay10TCYx(48);  //  40μs*(48MHz/4)=  480
}

//  表示用メモリアドレス設定 列と行で指定

void lcd_ddramxy(unsigned char x,unsigned char y){
    unsigned char ads = 0x40*y - (2<=y ? (0x40*2-0x14) : 0)+x;
    lcd_ddram(ads);
}

//  ユーザー定義キャラクタを設定
//  adsはキャラクターコード*8で設定する

void lcd_cgram(unsigned char ads,unsigned char* buf){
    LCD_RS=0;
    lcd_out8( LCD_CGADS | ads );
    Delay1TCYx(480);  //  40μs*(48MHz/4)=  480
    LCD_RS=1;
    for(int n=0;n<8;n++){
       lcd_out8( buf[n] );
        Delay10TCYx(48);  //  40μs*(48MHz/4)=  480
    }
}

//  ホーム位置から文字列を液晶に表示 \nによる複数行および折り返し表示サポート

void lcd_disp(const unsigned char* buf){
    const unsigned char* p=buf;
    unsigned char x=0;    //  列位置
    unsigned char y=0;    //  行位置
    LCD_RS=0;
    lcd_out8( LCD_CURHOME );
    Delay1KTCYx( 24);  //  2ms*(48MHz/4)=  24,000

    LCD_RS=1;
    while(*p){
        if(x==LCD_CMAX || *p=='\n'){
            ++y;
            lcd_ddramxy(0,y);
            Delay10TCYx(60);  //  50μs*(48MHz/4)=  600
            LCD_RS=1;
            x=0;
        }
        if(*p!='\n'){
            lcd_out8(*p);
            Delay10TCYx(60);  //  50μs*(48MHz/4)=  600
            ++x;
        }
        ++p;
   }
}

//  4bit出力

void lcd_out4(unsigned char data){
    unsigned char t1;
    LCD_ADS=(LCD_ADS & 0x0f) | (data & 0xf0);
    LCD_E=1;
    Delay1TCY();
    Delay1TCY();
    Delay1TCY();
    LCD_E=0;
}

//  8bitを4bitに分割して出力

void lcd_out8(unsigned char data){
    lcd_out4(data);
    lcd_out4(data<<4);
}