///////////////////////////////////////////////////////////////////////////////////////////////////
//	Title	LCD制御
//	Ver		00.00
//	Name	120
//	Date	2011.02.01
//
//	PIC		PIC16F886
//	CLK		10MHz
//
//	LCD		PORTC	7	6	5	4	3	2	1	0
//	LCD		symbol	-	E	RS	R/W	DB7	DB6	DB5	DB4
///////////////////////////////////////////////////////////////////////////////////////////////////

#include <htc.h>//[htc.h]をインクルードすると、プロジェクト作成時に選択したPICに必要なヘッダファイルを辿って読込む

#define _XTAL_FREQ	10000000//delay向け動作クロック定義

__CONFIG(HS & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & DUNPROTECT & 
BORDIS & IESODIS & FCMDIS & LVPDIS & DEBUGDIS);
/*
CONFIG1		定義語は各ヘッダファイル参照

発振器選択
EXTCLK		外部RC発振		出力有り
EXTIO		外部RC発振		出力無し
INTCLK		内部発振器　		出力有り
INTIO		内部発振器　		出力無し
LP			外部水晶			低速発振子（200KHz以下）
XT			外部水晶/セラミック	標準発振子（4MHz以下）
HS			外部水晶/セラミック	高速発振子（4MHz〜20MHz）
EC			外部発振器

有効			無効
WDTEN		WDTDIS		ウォッチドッグ
PWRTEN		PWRTDIS		パワーアップタイマ（OST=オシレータスタートアップタイマ：起動から発振器が安定するまで時間稼ぎにリセットする）
MCLREN		MCLRDIS		外部リセット端子（MCLR/RE3）
CP			UNPROTECT	コードプロテクト
CPD			DUNPROTECT	データプロテクト
BOREN		BORDIS		いみふ^q^（電源電圧低下時自動リセットの有効/無効が選択できるかも？）
IESOEN		IESODIS		いみふ^q^（内/外部発振器選択の有効/無効が選択できるかも？）
FCMEN		FCMDIS		フェールセーフクロックモニタ（外部発振器の調子が悪い時に内部発振器に切り替えて動作する機能）
LVPEN		LVPDIS		低電圧書込み（PGM/RB3）
DEBUGEN		DEBUGDIS	インサーキットデバッガ（ICSPCLK ICSPDAT/RB6 RB7）

CONFIG2		面倒だから無視するお！^q^
*/

///////////////////////////////////////////////////////////////////////////////////////////////////
//	LCD_send
//		LCDのEをH/L切り替えてデータを送信、PICのCLKが10MHz以下の場合はNOPが不要
///////////////////////////////////////////////////////////////////////////////////////////////////
LCD_send()
{
	PORTC |= 0x40;
	NOP();
	PORTC &= ~0x40;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	LCD_write(送信データ, 0:命令送信/1:文字送信)
//		遅い命令のClearDisplayとReturnHomeの処理時間が1.53msなので、コレに合わせて余裕持ちで2ms待機してから送信
///////////////////////////////////////////////////////////////////////////////////////////////////
LCD_write(char data, char rs)
{
	__delay_ms(2);

	PORTC = rs << 5;
	PORTC |= (data & 0xF0) >> 4;	//Hi-4bit
	LCD_send();

	PORTC = rs << 5;
	PORTC |= (data & 0x0F);			//Lo-4bit
	LCD_send();
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	LCD_init
//		LCDは起動時8bitModeで、初期命令を3回試しに送りながら待って、4bitModeへ移行してから初期設定系命令を送信
///////////////////////////////////////////////////////////////////////////////////////////////////
LCD_init()
{
	TRISC = 0x00;//PIC<->LCD
	PORTC = 0x03;

	__delay_ms(15);
	LCD_send();
	__delay_ms(5);
	LCD_send();
	__delay_us(100);
	LCD_send();
	PORTC = 0x02;
	LCD_send();

	LCD_write(0x28, 0);//4bit 2Line 5*8dots
	LCD_write(0x0F, 0);//DisplayON CursorON BlinkON
	LCD_write(0x01, 0);//Clear Display
	LCD_write(0x06, 0);//Increment NoShift
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	LCD_puts("文字列")
///////////////////////////////////////////////////////////////////////////////////////////////////
LCD_puts(char* str)
{
	while(*str)
		LCD_write(*str++, 1);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	main
///////////////////////////////////////////////////////////////////////////////////////////////////
main()
{
	ANSEL  = 0x00;//デジタルI/Oで利用
	ANSELH = 0x00;//デジタルI/Oで利用

	LCD_init();

	LCD_puts("xelloss120");
	LCD_write(0xC4, 0);//表示位置を2列目5文字目へ
	LCD_puts("@hotmail.com");

	while(1);
}
