#include <reg51.h>
// 型の略称を定義
#define uchar unsigned char
#define uint unsigned int
// データポートを定義
#define DATAPORT P1
// 制御ピンを定義
sbit halt = P2^7;
sbit fs1 = P2^6;
sbit md2 = P2^5;
sbit rst = P2^4;
sbit ce = P2^3;
sbit cd = P2^2;
sbit rd = P2^1;
sbit wr = P2^0;
// フォント
// 取得方法: https://www.zhetao.com/fontarray.html
// パラメータ:
// バイト幅: 8ビット
// フォントの高さ: 16
// 列: 2
// フォント: 宋体abc, サイズ: 0(自動)
unsigned char code font[][16] = {
/*-- 0 --*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,},
/*-- 1 --*/
{0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,},
/*-- 2 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,},
/*-- 3 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00,},
/*-- 4 --*/
{0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00,},
/*-- 5 --*/
{0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00,},
/*-- 6 --*/
{0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00,},
/*-- 7 --*/
{0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00,},
/*-- 8 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,},
/*-- 9 --*/
{0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00,},
/*-- スペース --*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
};
// 遅延関数
void delay_lcd(uchar t) {
for (; t != 0; t--);
}
// lcdディスプレイにデータを書き込む
void write_data(uchar dat) {
// C/DピンのDは低レベルで使用可能なので、CD = 0;
cd = 0;
// CE (チップイネーブル) ピンは低レベルで使用可能なので、CE = 0;
ce = 0;
// WR (書き込み) ピンは低レベルで使用可能なので、WR = 0;
wr = 0;
// データポートにdatのデータを送信する;
DATAPORT = dat;
delay_lcd(1);
// 書き込み終了。
wr = 1; ce = 1;
}
// lcdディスプレイにコマンドを書き込む
void write_cmd(uchar cmd) {
// C/DピンのCは高レベルで使用可能なので、CD = 1;
cd = 1;
// CE (チップイネーブル) ピンは低レベルで使用可能なので、CE = 0;
ce = 0;
// WR (書き込み) ピンは低レベルで使用可能なので、WR = 0;
wr = 0;
// コマンドデータcmdをデータポートに送信する;
DATAPORT = cmd;
delay_lcd(1);
// 書き込み終了。
wr = 1; ce = 1;
}
// 半角文字を表示する
// x: 行位置
// y: 列位置
// flag: 色を反転して表示するかどうか
// ch: フォントインデックスポインタ(配列)
// count: 文字数
void display_hw(uchar x, uchar y, int flag, uchar ch, int count) {
unsigned int place, i = 0, k;
// 文字配列を繰り返す
for (i = 0; i < count; i++) {
// 1文字8ビット幅、1行240ビット、合計30文字
// y: 垂直オフセット
place = x * 30 + y;
// 半角文字は16行の8ビットドットマトリックスを含む
for (k = 0; k <= 15; k++) {
// 高位アドレスを書き込む
write_data(place & 0xff);
// 低位アドレスを書き込む
write_data(place >> 8);
// アドレスを設定する
write_cmd(0x24);
// 連続読み書きを設定する
write_cmd(0xb0);
// フォント配列の要素インデックスに基づいて、対応する文字のドットマトリックスデータを検索する
write_data(flag ? font[ch[i]][k] : ~font[ch[i]][k]);
place += 30;
}
// 30文字以上の行は折り返す必要がある
if (y > 30) {
// 1文字の高さは16ビット
x += 16;
y = 0;
} else {
// 書き込みを続ける
y += 2;
}
}
}
// lcdディスプレイの初期化
void lcd_initial() {
// FS1が低レベルの場合、フォントは8*8です。そのため、fs1 = 0;
fs1 = 0;
// グラフィック領域を設定する
write_data(30);
write_data(0);
write_cmd(0x43);
// テキスト表示をオフにし、グラフィック表示をオンにする
write_cmd(0x98);
}