TOPMPLAB XC8編(PIC16F887)> 液晶ディスプレイを使う(PIC16F887 XC8)> ソース

液晶ディスプレイ(LCD)を使う(ソース)
(PIC16F887 XC8)
更新日2012.5.20
作成日2009.4.11


以下のソースを取り込んで、コンパイル→PIC書き込み→実行して下さい。

// ========================== ここから ==============================
// ファイル名	LCD_887.c
// 作成日		2009.3.14
// 更新日		2012.5.12
// 作成者		mit.ueno
// 機種			PIC16F887
// コンパイラ	MPLAB XC8
// CLOCK		8MHz(INTIO)
// 概要
//	LCDのテスト
//I/Oポート
//	RA0:LED(パイロットランプ)
//   LCD
//	RD2:LCD_RS
//	RD3:LCD_E
//	RD4:LCD_DB4
//	RD5:LCD_DB5
//	RD6:LCD_DB6
//	RD7:LCD_DB7
//
//	LCD_R/W  : GND
//	LCD_V0   : 5KΩVRでGND
//	LCD_DB0-3: open
//


#include "pic.h"

#define LCD_E  RD3
#define LCD_RS RD2


//XC8	__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & BORDIS & IESODIS & LVPDIS);
__CONFIG(FOSC_INTRC_NOCLKOUT & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & IESO_OFF & LVP_OFF);


static void pic_init();
static void wait_50us();
static void wait_1ms();
static void wait_ms(unsigned char);
static void LCD_send4(unsigned char);
static void LCD_cmd(unsigned char);
static void LCD_data(unsigned char);
static void LCD_init();

// ==================== メイン処理 ===========================
main()	{
	unsigned char i;
	unsigned char c;

	pic_init();			// PICの初期化
	LCD_init();			// LCDの初期化

	while(1) {
		LCD_cmd(0x01);	// Clear Display
		wait_ms(2);
		for	(i=0 ; i<16 ; i++) {	// 1行目に0〜?を表示
			c = 0x30 | i;
			LCD_data(c);
			wait_ms(250);
			wait_ms(250);
			PORTA ^= 0x01;		// DEBUG
		}
		LCD_cmd(0xA8);	// LCDアドレス(2行目)
		for	(i=0 ; i<16 ; i++) {	// 2行目に@〜Oを表示
			c = 0x40 | i;
			LCD_data(c);
			wait_ms(250);
			wait_ms(250);
			PORTA ^= 0x01;		// DEBUG
		}
	}
}

// ==================== PICの初期化 ===========================
static void pic_init() {
	OSCCON = 0x71;		// INTOSC 8MHz
	ANSEL  = 0x00;		// AN未使用
	ANSELH = 0x00;		// AN未使用
	TRISA = 0xFE;		// RA0:out
	TRISD = 0x03;		// RD2-7:out
	PORTA = 0x00;
	PORTD = 0x00;

	return;
}

// ====================== LCD 送信(4bit) ======================
static void LCD_send4(unsigned char c) {
	PORTD = (PORTD & 0x0F) | c;
	LCD_E = 1;
	NOP();
	LCD_E = 0;

	return;
}

// ==================== LCDコマンドWRITE =================
static void LCD_cmd(unsigned char cmd) {
	LCD_RS = 0;
	PORTD = (PORTD & 0x0F) | (cmd & 0xF0);
	LCD_E = 1;			// 上位4ビット書き込み
	NOP();
	LCD_E = 0;

	PORTD = (PORTD & 0x0F) | ((cmd <<4) & 0xF0);
	LCD_E = 1;			// 下位4ビット書き込み
	NOP();
	LCD_E = 0;

	wait_50us();

	return;
}

// ==================== LCDデータWRITE =================
static void LCD_data(unsigned char cmd) {
	LCD_RS = 1;
	PORTD = (PORTD & 0x0F) | (cmd & 0xF0);
	LCD_E = 1;			// 上位4ビット書き込み
	NOP();
	LCD_E = 0;

	PORTD = (PORTD & 0x0F) | ((cmd <<4) & 0xF0);
	LCD_E = 1;			// 下位4ビット書き込み
	NOP();
	LCD_E = 0;

	wait_50us();

	return;
}

// ==================== LCDの初期化 ===========================
static void LCD_init() {
	wait_ms(15);
	LCD_E = 0;
	LCD_RS = 0;

	LCD_send4(0x30);	// DB4-7に'3'を出力(8bitモードに)@
	wait_ms(5);
	LCD_send4(0x30);	// DB4-7に'3'を出力(8bitモードに)A
	wait_ms(1);
	LCD_send4(0x30);	// DB4-7に'3'を出力(8bitモードに)B
	wait_ms(1);
	LCD_send4(0x20);	// DB4-7に'2'を出力(4bitモードに)
	wait_ms(1);

	// ここからは4bitモードで、Busyフラグが使える
	LCD_cmd(0x28);	// DL=0:4bit ,N=1:2lines ,F=0:5*7dot
	LCD_cmd(0x08);	// Display off
	LCD_cmd(0x0C);	// Display on ,cursor on ,no blink
	LCD_cmd(0x06);	// Entry mode (Inc ,No Shift)
	LCD_cmd(0x01);	// Clear Display
	wait_ms(2);

	return;
}


// ==================== 50μSウェイトルーチン ================
static void wait_50us() {
	unsigned char i;

	for	(i=32 ; i>0 ; i--) {}
	return;
}

// ==================== 1mSウェイトルーチン ================
static void wait_1ms() {
	unsigned char i;

	for	(i=250 ; i>0 ; i--) {
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();
	}
	return;
}

// ==================== 1mS×ms ウェイトルーチン ===========
static void wait_ms(unsigned char ms) {
	unsigned char c;
	for (c=ms ; c>0 ; c--) {
		wait_1ms();
	}
	return;
}
// ========================== ここまで ==============================