<LCD自作定義文字の表示>
LCDの文字表示は、文字コードとパターンの対応表に記載されている文字を使っています。
SC2004Cの資料からの文字コードとパターンは次のようになっている(一部抜粋)
------------------------------------------------
I 0000 I 0001 I 0010 I 0011 I 0100 I 0101
------------------------------------------------
0000 ICGRAM1I I I 0 I @ I P
------------------------------------------------
0001 ICGRAM2I I ! I 1 I A I Q
------------------------------------------------
0002 ICGRAM3I I I 2 I B I R
しかし、文字コードとパターンの対応表に記載されていない↑などの文字はどうやって表示するのか?
調査したところ、表示方法が分かりましたので紹介します。
<使用PIC、LCD、LCDとPICの接続>
PIC:PIC16F688、LCD:SC2004C
LCDとPICの接続
LCD側ピン PIC側ピン(PIC16F688)
1.VSS(GND) GND(14)
2.VDD(+5V) +5V(1)
3.VLC(コントラスト) VRを接続して調整できる
4.RS レジスタ選択信号(H or L)----→ RC5(5)
5.R/W 読・書信号(GND接続) GND(14)
6.E イネーブル信号(H or L) ----→ RC4(6)
7.DB0 -下位4ビットデータバス
8.DB1 -
9.DB2 -
10.DB3 -
11.DB4 上位4ビットデータバス ----→ RC0(10)
12.DB5 - ----→ RC1(9)
13.DB6 - ----→ RC2(8)
14.DB7 - ----→ RC3(7)
まずは、次のプログラムをビルドしてPICに書き込んで下さい、↑が表示されたと思います。
(このプログラムは文字コード0x03に↑を作成しています。)
プログラム中の<は半角に修正してください
----------------------------------------------------------------------------------------------------
#include <htc.h>
__CONFIG(FCMDIS & IESODIS & BORDIS & UNPROTECT & MCLREN & PWRTEN & WDTDIS & INTIO);
__IDLOC(0001);
#define _XTAL_FREQ 8000000 //8MHz
#define E RC4
#define RS RC5
#define DB4 RC0
#define DB5 RC1
#define DB6 RC2
#define DB7 RC3
ioport();
lcd_init();
main()
{
OSCCON=0x70; //8MHz
ioport();
lcd_init(); //LCDを初期化する
//自作文字の文字コード0x03
// m_b75643210
PORTC=0b00000101; //文字コード(0x00-0x07)は、m_b10とl_b3の計3ビットで設定する
__delay_us(800); //0x00:m_b00000100 l_b00000000 0x04:m_b00000110 l_b00000000
E=1; //0x01:m_b00000100 l_b00001000 0x05:m_b00000110 l_b00001000
__delay_us(800); //0x02:m_b00000101 l_b00000000 0x06:m_b00000111 l_b00000000
// l_b75643210 //0x03:m_b00000101 l_b00001000 0x07:m_b00000111 l_b00001000
PORTC=0b00001000;
__delay_us(800);
E=1;
__delay_us(800);
//ライン0書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100100;
__delay_us(800);
E=1;
__delay_us(800);
//ライン1書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00101110;
__delay_us(800);
E=1;
__delay_us(800);
//ライン2書込み
PORTC=0b00100001;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00101111;
__delay_us(800);
E=1;
__delay_us(800);
//ライン3書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100100;
__delay_us(800);
E=1;
__delay_us(800);
////ライン4書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
PORTC=0b00100100;
__delay_us(800);
E=1;
__delay_us(800);
////ライン5書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100100;
__delay_us(800);
E=1;
__delay_us(800);
////ライン6書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100100;
__delay_us(800);
E=1;
__delay_us(800);
////ライン7書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
//LCDの表示位置アドレス設定0x00
PORTC=0b00001000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00000000; //0x00
__delay_us(800);
E=1;
__delay_us(800);
//文字コード0x03の書込み
PORTC=0b00100000;
__delay_us(800);
E=1;
__delay_us(800);
PORTC=0b00100011; //0x03
__delay_us(800);
E=1;
__delay_us(800);
E=0;
while(1);
}//main
ioport()
{
TRISC=0x00;
ANSEL=0x00;
CMCON0=0x07;
}
lcd_init() // LCDモジュール初期化
{
E=0;
__delay_ms(15);
PORTC=0b00000011; //1
E=1;
__delay_us(500);
E=0;
__delay_ms(5);
PORTC=0b00000011;//2
E=1;
__delay_us(500);
E=0;
__delay_us(200);
PORTC=0b00000011; //3
E=1;
__delay_us(500);
E=0;
PORTC=0b00000010; //4
E=1;
__delay_us(500);
E=0;
PORTC=0b00000010; //5
E=1;
__delay_us(500);
E=0;
PORTC=0b00001000; //6
E=1;
__delay_us(500);
E=0;
PORTC=0b00000000; //7
E=1;
__delay_us(500);
E=0;
PORTC=0b00001100; //8
E=1;
__delay_us(500);
E=0;
PORTC=0b00000000; //9
E=1;
__delay_us(500);
E=0;
PORTC=0b00000001; //10
E=1;
__delay_us(500);
E=0;
PORTC=0b00000000; //11
E=1;
__delay_us(500);
E=0;
PORTC=0b00000110; //12
E=1;
__delay_us(500);
E=0;
}
----------------------------------------------------------------------------------------------------
例えば、Aを表示するには、LCDの何行の何桁目に表示するかのアドレスを設定して、文字コードとパターンの
文字コード0x41(A)を書き込みます。
↑を表示するには、この↑を文字コードのCGRAM1(0x00)に作成します。(文字コードは0x00-0x07が使用出来ます)
作成出来ればLCDの何行の何桁目に表示するかのアドレスを設定して文字コード0x00(↑)を書き込めば表示出来ます。
CGRAMのアドレスセット
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 1 b5 b4 b3 b2 b1 b0
b5-b3が文字コード b2-b0がラインdataのアドレス
<ビットパターン>(↑の例 横0-4の5bit縦0-7の8bit)
43210
ライン0 -
ライン1 ---
ライン2 -----
ライン3 -
ライン4 -
ライン5 -
ライン6 -
ライン7 ここは空けておく
文字コード0x00に文字(↑)を書くイメージは次のような感じ
CG RAMアドレス(文字コード)に0x00をセットしてライン0からライン7のデータを書き込む
(↑の例)文字コード0x00
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
CGRAM Address 0 0 0 1 0 0 0 0 0 0 文字コード(DB5-DB3 0x00)のラインdata0アドレス
writeラインdata0 1 0 0 0 0 0 0 1 0 0
writeラインdata1 1 0 0 0 0 0 1 1 1 0
writeラインdata2 1 0 0 0 0 1 1 1 1 1
writeラインdata3 1 0 0 0 0 0 0 1 0 0
writeラインdata4 1 0 0 0 0 0 0 1 0 0
writeラインdata5 1 0 0 0 0 0 0 1 0 0
writeラインdata6 1 0 0 0 0 0 0 1 0 0
writeラインdata7 1 0 0 0 0 0 0 0 0 0
(↓の例)文字コード0x05
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
CGRAM Address 0 0 0 1 1 0 1 0 0 0 文字コード(DB5-DB3 0x05)のラインdata0アドレス
writeラインdata0 1 0 0 0 0 0 0 1 0 0
writeラインdata1 1 0 0 0 0 0 0 1 0 0
writeラインdata2 1 0 0 0 0 0 0 1 0 0
writeラインdata3 1 0 0 0 0 0 0 1 0 0
writeラインdata4 1 0 0 0 0 1 1 1 1 1
writeラインdata5 1 0 0 0 0 0 1 1 1 0
writeラインdata6 1 0 0 0 0 0 0 1 0 0
writeラインdata7 1 0 0 0 0 0 0 0 0 0
*ライン0-7のアドレスはインクリメントするのでライン毎に設定しない、最初のDB2-DB0の000だけでいい。
(LCDの初期化でエントリーモードセットでI/D:1にしている)
プログラムの基本は、次の@−Cの手順で行います。
@CG RAMアドレスに0x00(文字コード)にセット(abcの3bitで設定、0x05ならa:1 b:0 c:1)
c
PORTC=0b00000100; //CGRAM AddsetはDB6:1(RC2) E:0(RC4)1 RS:0(RC5)
E=1;
ba
PORTC=0b00000000;
E=1;
Aライン0-7の書込み(例↑)
//ライン0書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100100;
//ライン1書込み
PORTC=0b00100000;
E=1;
PORTC=0b00101110;
//ライン2書込み
PORTC=0b00100001;
E=1;
PORTC=0b00101111;
//ライン3書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100100;
//ライン4書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100100;
//ライン5書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100100;
//ライン6書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100100;
//ライン7書込み
PORTC=0b00100000;
E=1;
PORTC=0b00100000;
BLCDの表示位置アドレス設定0x00
PORTC=0b00001000; //アドレス設定するときはDB7:1(RC3) RS:0(RC5)にする
E=1; //1回目の書き込み
PORTC=0b00000000; //0x00
CCGRAMアドレス(文字コード)0x00に作成した文字書込みRS:1(RC5)
PORTC=0b00100000;
E=1;
PORTC=0b00000000;
以上ですが、@ーCをそれぞれ関数にすれば、次のような表示も出来て応用が広がると思います。