//----------------------------------------------------
//  液晶表示器制御ライブラリ LCD.h
//  
//  LCD_init()								LCD初期化
//  LCD_data(char asci)						１文字表示
//  LCD_cmd(char cmd)						LCD制御コマンド発行
//  LCD_clear()								LCDクリア
//  LCD_print(char *str)					文字列表示
//  LCD_locate(char x, char y)				指定位置にカーソル移動(数字は１から）
//  LCD_cursol(char c_mode)					LCDカーソルモード指定
//  LCD_move_cursol_right()					カーソルを右に一つ移動
//  LCD_move_cursol_left()	　				カーソルを左に一つ移動
//  LCD_lineprint(char x, char y,char *str) 指定位置に文字列を表示
//  
//  Delay_ms(unsigned long msec)			ディレイ関数　msec単位
//  Delay_us(long usec)						ディレイ関数 1usec単位
//  
//  トラ技 2005年2月号 R8C/Tinyマイコン入門　第4回　参考にしH8用に改良
//  by T.AZAMI  2007/9/15
//
//----------------------------------------------------

#define	LCD_PCR		IO.PCR5
#define	LCD_port	IO.PDR5.BYTE
#define	LCD_RS		IO.PDR5.BIT.B4
#define	LCD_E		IO.PDR5.BIT.B5

//  ディレイ関数　msec単位
void Delay_ms(unsigned long msec) {
	unsigned int  i;
	unsigned long j;
	for( j=0; j<msec; j++){
		for( i=0; i<2000; i++);
	}
}	

//  ディレイ関数 1usec単位
void Delay_us(long usec){
	usec = (usec * 20000) / 45000;
	while(usec--){}
}

// データ出力サブ関数
void LCD_out(char code, char flag){
	LCD_port = code & 0x0f;		//出力データ下位４ビット
	if (flag == 0){				//表示データかコマンドか
		LCD_RS = 1;				//表示データの場合RS=1
	}else{
		LCD_RS = 0;				//コマンドデータの場合RS=0
	}
	{
	#pragma asm
		NOP						//NOP　スキュー確保	
	#pragma endasm
	}
	LCD_E = 1;					//STB ON
	{
	#pragma asm					//パルス幅確保230nsec以
		NOP
		NOP
		NOP
		NOP
	#pragma endasm
	}
	LCD_E = 0;					//STB OFF
}

//  １文字表示関数
void LCD_data(char asci){
	LCD_out(asci>>4, 0);		//上位４ビット出力
	LCD_out(asci, 0);			//下位４ビット出力
	Delay_us(50);				//50μsec待ち
}

//  コマンド出力関数
void LCD_cmd(char cmd){
	LCD_out(cmd>>4, 1);			//上位４ビット出力
	LCD_out(cmd, 1);			//下位４ビット出力
	if((cmd == 0x01) || (cmd == 0x02))
		Delay_ms(2);			//2msec待ち
	else
		Delay_us(50);			//50usec待ち
}

//  LCD初期化関数
void LCD_init(){
	LCD_PCR = 0x3F;				//bit0-bit5を出力ポートとする
	Delay_ms(20);				//20msec wait
	LCD_out(0x03, 1);			//8bit mode set
	Delay_ms(5);				//5msec wait
	LCD_out(0x03, 1);			//8bit mode set
	Delay_ms(1);
	LCD_out(0x03, 1);			//8bit mode set
	Delay_ms(1);
	LCD_out(0x02, 1);			//4bit mode set
	Delay_ms(1);
	LCD_cmd(0x2C);				//DL=0 4bit mode
	LCD_cmd(0x08);				//display off C=D=B=0
	LCD_cmd(0x0E);				//display on D=B=1 C=0
	LCD_cmd(0x06);				//entry I/D=1 S=0
	LCD_cmd(0x01);				//all clear
}

//  全消去関数
void LCD_clear(){
	LCD_cmd(0x01);				//初期化コマンド出力
}

//  文字列出力関数
void LCD_print(char *str){
	while(*str != 0x00)			//文字列の終わり判定
	{
		LCD_data(*str);			//文字列１文字出力
		str++;					//ポインタ＋１
	}
}

//  カーソル位置に移動
void LCD_locate(char x, char y){
	char i;
	if (y == 1){
		LCD_cmd(0x02);
		x--;
		while ( x ){
			LCD_cmd(0x14);
			x--;
		}
	}else if (y == 2){
		LCD_cmd(0x02);
		x--;
		for (i=1;i<=40;i++){
			LCD_cmd(0x14);
		}
		while ( x ){
			LCD_cmd(0x14);
			x--;
		}
	}
}
 
//  カーソル表示制御
void LCD_cursol(char c_mode){
	switch ( c_mode){
	case 1:				// 1.カーソルOFF、ブリンクOFF
		LCD_cmd(0x0c);
		break;
	case 2:				// 2.カーソルOFF、ブリンクON
		LCD_cmd(0x0d);
		break;
	case 3:				// 3.カーソルON、ブリンクOFF
		LCD_cmd(0x0e);
		break;
	case 4:				// 4.カーソルON、ブリンクON
		LCD_cmd(0x0f);
		break;
	}	
}

//　カーソル移動
void LCD_move_cursol_right(){
	LCD_cmd(0x04);
}

void LCD_move_cursol_left(){
	LCD_cmd(0x10);
}

//  文字列出力関数(位置指定)
void LCD_lineprint(char x, char y,char *str){
	LCD_locate(x,y);
	while(*str != 0x00)			//文字列の終わり判定
	{
		LCD_data(*str);			//文字列１文字出力
		str++;					//ポインタ＋１
	}
}