LCD4ビットインターフェースサンプル

(Mini-c 関数の作成)

 このファイルは、LCDのキャラクターディスプレーで、1行または2行表示で桁数が 16,24,40桁等の物が、ジャンクとして安く売られているものをディスプレーとして 使用するための関数が書いて有ります。ただし、コントロールに日立製のHD44780を 使用している物に限ります。
 HD44780は68系のため、Z80とインターフィスを取ることが少々面倒ですが、 CPUとLCDコントローラの接続は、バスラインに直結をやめI/Oポートに4ビット インターフェースにし簡単につなげるようしてあります、この関数を使う場合は回路図に 合わせる必要があります。 また、バスライン直結の回路で作ったソースファイルはインクルードしているファイルを lcd_drv.h から lcd_drv4.h に変更するだけでそのまま動作します。




 次に、各関数の説明を行います。"

"void lcd_reset(int line)"

この関数は、LCDの初期化を行います。引数は、表示行数で "1"または、"2"のみのどちらかとなります。


"void lcd_clear( )"

この関数は、表示をクリアーします。


"void lcd_data_dsp(int dsp_dat)"

この関数は、LCDに1文字表示を行います。ただし、LCDコントロラーの表示メモリーがLCDの桁数に関係無く一定のため、桁数を越えた部分は表示しません。とくに、2行表示のLCDの場合、1行目と2行目で表示がつながら無くなります。ちなみに2行目の最初の桁のカーソルアドレスは、40hとなっています。


"void lcd_str_dsp(char *str)"

この関数は、LCDに文字列を表示します。これも上記の関数と同じ桁数を越えると表示しない事に、注意が必要です。


"void cursor_home( )"

この関数は、カーソルをホームポジションに戻します。

目次に戻る



/*======================================================================*/
/*									*/
/*		HD44780使用LCDユニット用			*/
/*		ドライブ ライブラリー Vr1.00			*/
/*		(クロック8MHz PIO4bit接続)			*/
/*									*/
/*	lcd_drv4.h  Ver1.00		Tomcat works	2000/02/09	*/
/*									*/
/*	pio_bd0	--- lcd RS						*/
/*	pio_bd1	--- lcd R/W						*/
/*	pio_bd2	--- lcd E						*/
/*	pio_bd3	--- nc  (使用禁止、出力モード 必ずオープンにする事!)	*/
/*	pio_bd4	--- lcd DB4						*/
/*	pio_bd5 --- lcd DB5						*/
/*	pio_bd6 --- lcd DB6						*/
/*	pio_bd7	--- lcd DB7						*/
/*									*/
/*	void	lcd_reset(int line)	line = 1 or 2			*/
/*	void	lcd_clear( )						*/
/*	void	lcd_data_dsp(int dsp_dat)				*/
/*	void	lcd_str_dsp(char *str)					*/
/*	void	cursor_home( )						*/
/*	void	cursor_adr_w(int c_adr)					*/
/*	int	cursor_adr_r( )						*/
/*	void	display_on( )						*/
/*	void	cursor_on( )						*/
/*	void	brnk_on( )						*/
/*	void	cursor_brnk_on( )					*/
/*	void	display_off( )						*/
/*									*/
/*======================================================================*/
#asm

;	LCD_BUSY	*** LCDビジーチェック ***

LCD_BUSY:	PUSH	AF
		PUSH	BC

		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,0F0H
		OUT	(IO_PIO_BC),A

LCD_BUSY_1:	LD	A,02H
		OUT	(IO_PIO_BD),A	;R/W high
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	B,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		BIT	7,B
		JR	NZ,LCD_BUSY_1
		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,00H
		OUT	(IO_PIO_BC),A

		POP	BC
		POP	AF
		RET


;	LCD_INST	*** インストラクションデータ出力 ***  (A reg)

LCD_INST:	PUSH	AF
		PUSH	BC

		LD	C,A
		AND	0FH
		RLCA
		RLCA
		RLCA
		RLCA
		LD	B,A
		LD	A,C
		AND	0F0H
		CALL	LCD_BUSY
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW
		LD	A,B
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW

		POP	BC
		POP	AF
		RET


;	LCD_ADDR	*** LCDアドレスリード( AF Reg in) ***

LCD_ADDR:	PUSH	BC

		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,0F0H
		OUT	(IO_PIO_BC),A

LCD_ADDR_1:	LD	A,02H
		OUT	(IO_PIO_BD),A	;R/W high
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	B,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	C,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		BIT	7,B
		JR	NZ,LCD_ADDR_1
		SRL	C
		SRL	C
		SRL	C
		SRL	C
		LD	A,B
		AND	70H
		OR	C
		LD	B,A

		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,00H
		OUT	(IO_PIO_BC),A

		LD	A,B
		POP	BC
		RET


;	LCD_DATA	*** データ出力(A reg out) ***

LCD_DATA:	PUSH	AF
		PUSH	BC

		LD	C,A
		AND	0FH
		RLCA
		RLCA
		RLCA
		RLCA
		LD	B,A
		LD	A,C
		AND	0F0H
		SET	0,A
		CALL	LCD_BUSY
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW
		LD	A,B
		SET	0,A
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW

		POP	BC
		POP	AF
		RET


;	LCD_DATA_IN	*** LCDデータリード( AF Reg in) ***

LCD_DATA_IN:	PUSH	BC

		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,0F0H
		OUT	(IO_PIO_BC),A

LCD_DATA_IN1:	LD	A,02H
		OUT	(IO_PIO_BD),A	;R/W high
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	B,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		BIT	7,B
		JR	NZ,LCD_DATA_IN1

		LD	A,03H
		OUT	(IO_PIO_BD),A	;R/W high
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	B,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		SET	2,A
		OUT	(IO_PIO_BD),A	;E high
		IN	A,(IO_PIO_BD)
		LD	C,A
		RES	2,A
		OUT	(IO_PIO_BD),A	;E low
		SRL	C
		SRL	C
		SRL	C
		SRL	C
		LD	A,B
		AND	0F0H
		OR	C
		LD	B,A

		LD	A,0CFH
		OUT	(IO_PIO_BC),A
		LD	A,00H
		OUT	(IO_PIO_BC),A

		LD	A,B
		POP	BC
		RET


;	LCD_CRLF	*** キャッジリターン ***

LCD_CRLF:	PUSH	AF
		LD	A,0C0H
		CALL	LCD_INST
		POP	AF
		RET


;	LCD_FUNCTION	*** LCDファンクションセット ***

LCD_FUNCTION:	PUSH	AF		;リセット後3回のみ

		LD	A,30H		;8bit I/F
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW

		POP	AF
		RET


;	LCD_FUNC_B	*** LCDファンクションセットB ***

LCD_FUNC_B:	PUSH	AF		;一回のみ
		PUSH	BC

		BIT	1,A
		JR	NZ,LCD_FUNC_B1
		LD	B,00H		;1 Line
		JR	LCD_FUNC_B2
LCD_FUNC_B1:	LD	B,80H		;2 Line
LCD_FUNC_B2:	LD	A,20H		;4 bit I/F
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW
		LD	A,B
		OUT	(IO_PIO_BD),A
		SET	2,A
		OUT	(IO_PIO_BD),A	;E = HIGH
		RES	2,A
		OUT	(IO_PIO_BD),A	;E = LOW

		POP	BC
		POP	AF
		RET



;		*** 表示用タイマー ***

WAIT_SHORT:	PUSH	AF		;4MHzの場合316μs
		PUSH	BC		;6MHzの場合210μs

		LD	B,93		;8MHzの場合158μs
WAIT_SHORT_1:	DJNZ	WAIT_SHORT_1

		POP	BC
		POP	AF
		RET



WAIT_LONG:	PUSH	AF		;4MHzの場合1.63ms
		PUSH	BC

		LD	B,103		;8MHzの場合103
WAIT_LONG_1:	CALL	WAIT_SHORT
		DJNZ	WAIT_LONG_1

		POP	BC
		POP	AF
		RET



#endasm


/*		*** 電源オンリセット ***	*/
/*			line = 1 or 2			*/

void	lcd_reset(int line)
{
#asm

	ld	a,0cfh
	out	(IO_PIO_BC),a
	ld	a,00h
	out	(IO_PIO_BC),a
	ld	b,10
lcd_reset1:
	call	wait_long
	djnz	lcd_reset1
	call	lcd_function
	ld	b,3
lcd_reset2:
	call	wait_long
	djnz	lcd_reset2
	call	lcd_function
	call	wait_short
	call	lcd_function
	call	wait_short
	ld	hl, 2		; 引き数の取り出し
	add	hl, sp
	ld	a, (hl)
	call	lcd_func_b
	ld	a,06h
	call	lcd_inst
	ld	a,01h
	call	lcd_inst
	ld	a,0ch
	call	lcd_inst
#endasm
}

/*	*** LCD1文字表示データ出力 ***	*/

void	lcd_data_dsp(int dsp_dat)
{
#asm
	ld	hl, 2
	add	hl, sp
	ld	a, (hl)
	call	lcd_data
#endasm
}

/*	*** LCD文字列表示データ出力 ***	*/

void	lcd_str_dsp(char *str)

{
#asm
	ld	hl, 2
	add	hl, sp
	ld	a,(hl)
	inc	hl
	ld	h,(hl)
	ld	l,a
print_to_null:
	ld	a,(hl)
	inc	hl
	or	a
	jr	z,print_to_null_1
	call	lcd_data
	jr	print_to_null
print_to_null_1:

#endasm
}

/*	*** LCD全桁表示消去 ***	*/

void	lcd_clear( )
{
#asm
	ld	a,01h
	call	lcd_inst
#endasm
}

/*	*** カーソルをホームポジションへ ***	*/

void	cursor_home( )
{
#asm
	ld	a,02h
	call	lcd_inst
#endasm
}

/*	*** カーソルを指定位置に ***	*/

void	cursor_adr_w(int c_adr)
{
#asm
	ld	hl, 2
	add	hl, sp
	ld	a, (hl)
	or	80h
	call	lcd_inst
#endasm
}

/*	*** カーソル位置リード ***	*/

int	cursor_adr_r( )
{
#asm
	call	lcd_addr
	ld	l, a
	ld	h, 0
#endasm
}

/*	*** 表示ON ***	*/

void	display_on( )
{
#asm
	ld	a,0ch
	call	lcd_inst
#endasm
}

/*	*** カーソル ON ***	*/

void	cursor_on( )
{
#asm
	ld	a,0eh
	call	lcd_inst
#endasm
}

/*	*** ブリンク ON ***	*/

void	brnk_on( )
{
#asm
	ld	a,0dh
	call	lcd_inst
#endasm
}

/*	*** カーソル、ブリンク ON ***	*/

void	cursor_brnk_on( )
{
#asm
	ld	a,0fh
	call	lcd_inst
#endasm
}


/*	*** 表示OFF ***	*/

void	display_off( )
{
#asm
	ld	a,08h
	call	lcd_inst
#endasm
}




目次に戻る