;==========================================================
;
; LCD (HD44780) library 
; 4-bit interface
; 
; (C) HELIUM  
; http://helium.webz.cz/
;
; compiled with MetaLink 8051 Cross-Assembler, Version 1.2k
;==========================================================

$MOD51

;XTAL	EQU	11		; XTAL 11.0592 MHz, zakomentovat !!!

RS	EQU	P1.2
EN	EQU	P1.3
DB4	EQU	P1.4
DB5	EQU	P1.5
DB6	EQU	P1.6
DB7	EQU	P1.7
LCD	EQU	P1

;==========================================================
; organizace dat  [Lo - Hi] 
	DSEG AT 028h
wait:	DS	2		; 2 bytes na cekaci smycky
LCD_pos:DS	1		; 1 byte, aktualni pozice, adresa

	CSEG
;==========================================================
; makro cekani count milisekund
; 60 (120) ms max.
DELAY	MACRO	count		;
IF XTAL=24
	mov	wait+1, #(count*4);
	mov	wait+0, #0	;	
ELSE
	mov	wait+1, #(count*2);
	mov	wait+0, #0	;
ENDIF
	djnz	wait+0, $	; 0.512ms pro XTAL 12Mhz
	djnz	wait+1, $-3	;	
ENDM				;
	
;==========================================================	
; inicializace displeje
;	
LCD_init:push	ACC		;
	clr	RS		;
	clr	EN		;
	DELAY	20		; cekam na zapnuti 20 ms
	mov	A, #00110000B	;
	call	LCD_wr		;
	DELAY	5		;  cekam po zapisu 5 ms 
;	
	mov	A, #00110000B	;
	call	LCD_wr		;
	call	LCD_wait	;
	call	LCD_wait	; cekam po zapisu 0.1 ms 
	mov	A, #00110000B	;
	call	LCD_wr		;
	DELAY	5		;  cekam po zapisu 5 ms 
;
	mov	A, #00100000B	; nastav 4 bit interface
	call	LCD_wr		;
	call	LCD_wait	;
; 4 bit	interface now !
	mov	A, #00101000B	; 2 lines, font 5x7, 4 data bits
	call	LCD_wr2		;
	mov	A, #00001100B	; Displey On, Cursor Off, Blink Of
	call	LCD_wr2		;

	mov	A, #00000110B	; increment adres, shift off
	call	LCD_wr2		;
	call	LCD_clr		; Clear
;
	pop	ACC		;
	RET

;==========================================================	
; vymazani displeje
;
LCD_clr:push	ACC		;
	clr	RS		;
	mov	A, #00000001B	; Clear
	call	LCD_wr2		;
	mov	LCD_pos, #0	;
	DELAY	2		;
	POP	ACC		;
	RET			;

;==========================================================	
; zapis ZNAKU z ACC do LCD displeje
;
LCD_wrT:push	ACC		;
	setb	RS		;
	call	LCD_wr2		;
	pop	ACC		;
	inc	LCD_pos		; inkrementace adresy
	RET			;

;==========================================================	
; nastaveni kurzoru displeje na adresu v ACC
;
LCD_at:	push	ACC		;
	clr	RS		;
	mov	LCD_pos, A	;
	orl	A, #10000000B	;
	call	LCD_wr2		;
	pop	ACC		;
	RET			;
	
;==========================================================	
; zapis bytu do LCD displeje
; nici obsah ACC
;
LCD_wr:	orl	LCD, #0F0h	; horni nible 1111xxxx
	orl	A, #00Fh		;
	anl	LCD, A		; horni nible DDDDxxxx
	nop
	nop
	setb	EN		;
	nop
	nop
	clr	EN		; zapisova hrana EN 1->0
	RET			;
	
;==========================================================	
; zapis 2x 4 bitu z ACC do LCD displeje
; nici obsah ACC
;
LCD_wr2:push	ACC		;
	call	LCD_wr		; horni nible
	pop	ACC		;
	swap	A		;
	call	LCD_wr		; dolni nible
	call	LCD_wait	;
	RET			;
	
;==========================================================	
; cekani 50us (doba trvani po zapisu do displeje)
;
LCD_wait:
IF XTAL=24
	mov	wait, #50	;
ELSE
	mov	wait, #25	;
ENDIF
	djnz	wait, $		;
	RET			;
	
;==========================================================	
; zapis R2 DAT od adresy DPTR do CG/DD-RAM
;
LCD_ld:	push	ACC		;
LCD_ld0:clr	A		;
	movc	A, @A+DPTR	; tabulka v kodu programu
	call	LCD_wr2		;
	inc	DPTR		;
	djnz	R2, LCD_ld0	;
	pop	ACC		;
	RET

;==========================================================	
; nastaveni vlastnich znaku na pozicich 0-7 CG-RAM
; uziva registr R2
;
LCD_ldF:push	ACC		;
	mov	R2, #(8*8)	;
	clr	RS		;
	mov	A, #01000000B	;
	call	LCD_wr2		;
	setb	RS
	mov	DPTR, #char_tab	; 
	call	LCD_ld		;
	pop	ACC		;
	RET

;==========================================================
; Tabulky dat
;
;----------------------------------------------------------
; users char for CG-RAM, DD-RAM position 0-7
;
; active matrix for font 5x7 pixels
; char_x:    DB	xxx10001b
;            DB	xxx10001b
;            DB	xxx01010b
;            DB	xxx00100b
;            DB	xxx01010b
;            DB	xxx10001b
;            DB	xxx10001b
;            DB	xxxxxxxxb
;
char_tab:            
char_0:     DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	0h
;
char_1:     DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	0h
;
char_2:     DB	00011111b
            DB	00010001b
            DB	00010001b
            DB	00010001b
            DB	00010001b
            DB	00010001b
            DB	00011111b
            DB	0h
;
char_3:     DB	00010001b
            DB	00010001b
            DB	00001010b
            DB	00000100b
            DB	00001010b
            DB	00010001b
            DB	00010001b
            DB	0h
;
char_4:     DB	00000001b
            DB	00000011b
            DB	00000111b
            DB	00001110b
            DB	00011100b
            DB	00011000b
            DB	00010000b
            DB	0h
;
char_5:     DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	0h
;
char_6:     DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	0h
;
char_7:     DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	00011111b
            DB	0h
		
;==========================================================
; Data pro LCD modul
;
tab1:	DB	'Hello LCD world!'
tab2:	DB	' Helium library '
;==========================================================

;	END