	list p=16F84
;
	include "p16f84.inc"
;
;	semplici routine di gestione di un LCD via bus dati @ 4 bit
;	Autore:	Stefano Tomasella .ste
;	Data:	08/12/2005
;	Stato:	funzionante
;	clock frequency = 4Mhz
;
LCD_RS		equ	2
;LCD_RW		connesso a massa (write to LCD)
LCD_E		equ	3
LCD_DB4		equ	4
LCD_DB5		equ	5
LCD_DB6		equ	6
LCD_DB7		equ	7
;
		org	0x20
tmpLCD		res	2
msDelayCounter	res	2
;
;
		org	0		;reset vector
start
		bsf	STATUS, RP0	;bank1
		movlw	b'00011111'
		movwf	TRISA
		movlw	b'00000011'
		movwf	TRISB
		bcf	STATUS, RP0	;bank0
;
		call	LCDinit
;
loop
		call	LCDclear
		movlw	0x10		;seconda riga prima colonna
		call	LCDlocate
		movlw	'z'
		call	LCDsendData
		movlw	'i'
		call	LCDsendData
		movlw	'a'
		call	LCDsendData
		movlw	'o'
		call	LCDsendData
		movlw	'!'
		call	LCDsendData
		movlw	0x03		;prima riga quarta colonna
		call	LCDlocate
		movlw	'.'
		call	LCDsendData
		movlw	's'
		call	LCDsendData
		movlw	't'
		call	LCDsendData
		movlw	'e'
		call	LCDsendData
		movlw	0xff
		call	msDelay
;loop
		goto	loop
;
msDelay		
		movwf	msDelayCounter+1
		clrf	msDelayCounter
msDelayLoop
		nop
		decfsz	msDelayCounter, f
		goto	msDelayLoop
		nop
		decfsz	msDelayCounter+1, f
		goto	msDelayLoop
		return
;
LCDinit
		movlw	30
		call	msDelay
		bcf	PORTB, LCD_RS	;LCD command mode
		bsf	PORTB, LCD_DB4
		bsf	PORTB, LCD_DB5
		bcf	PORTB, LCD_DB6
		bcf	PORTB, LCD_DB7
		bsf	PORTB, LCD_E
		movlw	5
		call	msDelay
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bsf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bsf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_DB4	;set 4 bit data bus
		bsf	PORTB, LCD_DB5
		bcf	PORTB, LCD_DB6
		bcf	PORTB, LCD_DB7
		bsf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		movlw	0x28		; 4 bit / 2 lines / 5x7 dot matrix
		call	LCDsendCommand
		movlw	0x06		; increment one / no shift
		call	LCDsendCommand
		movlw	0x0C		; dislay ON / cursor OFF (0x0E=ON) / blink OFF
		call	LCDsendCommand
		call	LCDclear
		return
;
LCDclear
		movlw	0x01
		call	LCDsendCommand
		movlw	2
		call	msDelay
		movlw	0x80		;primo carattere, prima riga
		call	LCDsendCommand
		return
;
LCDlocate
		movwf	tmpLCD
		movlw	0x80
		movwf	tmpLCD+1
		movf	tmpLCD, 	w
		andlw	0x0F
		iorwf	tmpLCD+1,	f
		btfsc	tmpLCD,		4
		bsf	tmpLCD+1,	6
		btfsc	tmpLCD,		5
		bsf	tmpLCD+1,	4
		movf	tmpLCD+1,	w
		call	LCDsendCommand
		return
;
LCDsendData
		bsf	PORTB, LCD_RS
		call	LCDsendByte
		return
;
LCDsendCommand
		bcf	PORTB, LCD_RS
		call	LCDsendByte
		return
;
LCDsendByte
		movwf	tmpLCD
		bcf	PORTB, LCD_DB4
		bcf	PORTB, LCD_DB5
		bcf	PORTB, LCD_DB6
		bcf	PORTB, LCD_DB7
		btfsc	tmpLCD, 4	; higher nibble
		bsf	PORTB, LCD_DB4
		btfsc	tmpLCD, 5
		bsf	PORTB, LCD_DB5
		btfsc	tmpLCD, 6
		bsf	PORTB, LCD_DB6
		btfsc	tmpLCD, 7
		bsf	PORTB, LCD_DB7
		bsf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		bcf	PORTB, LCD_DB4
		bcf	PORTB, LCD_DB5
		bcf	PORTB, LCD_DB6
		bcf	PORTB, LCD_DB7
		btfsc	tmpLCD, 0	; lower nibble
		bsf	PORTB, LCD_DB4
		btfsc	tmpLCD, 1
		bsf	PORTB, LCD_DB5
		btfsc	tmpLCD, 2
		bsf	PORTB, LCD_DB6
		btfsc	tmpLCD, 3
		bsf	PORTB, LCD_DB7
		bsf	PORTB, LCD_E
		goto	$+1
		bcf	PORTB, LCD_E
		movlw	1
		call	msDelay
		return
;
;
	end























