;LCD_DB4.INC
;-----------------------------------------------------------------
;Rutinas para el manejo de una pantalla LCD 2x16 con 4 bits de 
;datos (DB4 a DB7) y dos de control (EN y RS). 
;Las lineas del LCD deben conectarse de la siguiente forma: 	
;
;		RW = masa (siempre escritura)
;		EN = RB2 (pulso para enable)	
;		RS = RB3 (0=comando 1=caracter)
;		DB4 a DB7 = RB4 a RB7 (bus de datos de 4 bits)  
;
;IMPORTANTE Requisitos en el programa principal:
;
;	1) Configurar RB2 a RB7 como salidas. (RB0 y RB1 quedan libres para
;	otros usos) 
;	Puede llamarse a la subrutina LCD_UP aquí incluida la cual configura
;	el PORTB todo salidas.
;
;	2) En el programa principal deben declararse los siguientes
;	registros: 
;			CONT0
;			CONT1
;			LCD_TEMP		
;-----------------------------------------------------------------


;subrutina LCD_UP, configura TRISB todo salidas

LCD_UP
	bcf	STATUS,RP1
	bsf	STATUS,RP0
	movlw	b'00000011'
	movwf	TRISB
	bcf	STATUS,RP0
	return	

;Subrutina LCD_INI, inicia el LCD y configuraciones por
;defecto. Debe llamarse una vez al principio del programa.

LCD_INI
	call	DELAY_LCD_1	;delay para el inicio del LCD 
	movlw	b'0011000'	;EN y RS a 0 y dato "3" al lcd
	movwf	PORTB		
	bsf	PORTB,2		;pulso a ENABLE
	nop
	nop
	bcf	PORTB,2
	call	DELAY_LCD_1	;delay para el inicio del LCD		
	movlw	b'00101000'	;4 bits de datos, 2lin, carac.5x7
	call	LCD_REG
	movlw	b'00000110'	;desplaza cursor a dcha.
	call	LCD_REG
	movlw	b'00001111'	;LCD ON cursor BLINK
	call	LCD_REG
	movlw	b'00000001'	;borra y home
	call	LCD_REG
	return

;Subrutina LCD_REG, envia en dos cargas de 4 bits el 
;dato presente en W al LCD en modo comando/configuración

LCD_REG
	movwf	LCD_TEMP
	andlw	0xF0	
	movwf	PORTB		;enviamos nible alto
	bcf	PORTB,3		;RS=0 modo comando
	bsf	PORTB,2		;EN=1 pulso a ENABLE
	nop
	nop
	bcf	PORTB,2		;EN=0
	swapf	LCD_TEMP,0
	andlw	0xF0
	movwf	PORTB		;enviamos nible bajo
	bcf	PORTB,3		;RS=0 modo comando
	bsf	PORTB,2		;pulso a ENABLE
	nop
	nop
	bcf	PORTB,2		;EN=0
	call	DELAY_LCD_2	;tiempo para que quede libre LCD
	return			

;Subrutina LCD_DATO, envia en dos cargas (nibble a nibble) el 
;dato/caracter presente en W al LCD en modo dato/caracter ASCII	

LCD_DATO
	movwf	LCD_TEMP
	andlw	0xF0
	movwf	PORTB		;envia nible alto
	bsf	PORTB,3		;RS=1 modo dato
	bsf	PORTB,2		;EN=1 pulso a ENABLE
	nop
	nop
	bcf	PORTB,2		;EN=0
	swapf	LCD_TEMP,0
	andlw	0xF0
	movwf	PORTB		;enviamos nible bajo
	bsf	PORTB,3		;RS=1 modo dato
	bsf	PORTB,2		;pulso a ENABLE
	nop
	nop
	bcf	PORTB,2		;EN=0
	bcf	PORTB,3		;RS=0
	call	DELAY_LCD_2	;tiempo para que quede libre LCD
	return			
	
;Subrutina DELAY_LCD_1 de unos 196ms 

DELAY_LCD_1
	decfsz	CONT0,1
	goto	DELAY_LCD_1
	decfsz	CONT1,1
	goto	DELAY_LCD_1
	return

;Subrutina DELAY_LCD_2 de unos 3ms
	
DELAY_LCD_2
	movlw	.4
	movwf	CONT1
DEL_LCD_2_1
	decfsz	CONT0,1
	goto	DEL_LCD_2_1
	decfsz	CONT1,1
	goto	DEL_LCD_2_1
	return	
		
			