;-----------------------------------------------;
;   RUTINAS DE MANEJO PARA MODULO LCD CON		;
;    CONTROLADOR KS0066 (O EQUIVALENTE)			;
;		PARA USAR EN MODO DE 4 BITS.			;
;	 POR JUAN MARTIN FERRARI, AŅO 2009.			;
;	LAS RUTINAS DE RETARDO FUERON GENERADAS		;
;			CON EL PROGRAMA PDEL.				;
;-----------------------------------------------;
;
; LA FRECUENCIA DEL CRISTAL, RESONADOR O FUENTE
; EXTERNA DE OSCILACION DEBE SER DE 4 MHZ. CASO
; CONTRARIO, AJUSTAR TANTO LAS RUTINAS DE RETARDO
; COMO LAS DEMORAS NECESARIAS EN LOS CICLOS DE
; LECTURA Y ESCRITURA (VER HOJA DE DATOS KS0066).
;
; EL LCD DEBE ESTAR CONECTADO A LOS PINES <4:7> DEL
; PUERTO B (DEBEN SER CONFIGURADOS COMO SALIDA 
; PREVIAMENTE) DE LA FORMA:
; DB4 -> PORTB,4
; DB5 -> PORTB,5
; DB6 -> PORTB,6
; DB7 -> PORTB,7
;
; LAS LINEAS E, RS Y RW DEBERAN CONECTARSE A ALGUN 
; PIN DEL PUERTO A, PREVIAMENTE CONFIGURADOS COMO SALIDA.
;
; LOS PINES CONECTADOS A RW Y E DEBEN INICIALIZARSE
; EN CERO LOGICO.
;
; NECESARIO:
; - DECLARACION DE: RS, E Y RW.
; - CBLOCK QUE INDIQUE LA DIRECCION DE R_E_T_1, R_E_T_2
;   Y LCD_AUX.
; - INCLUSION DEL ARCHIVO P16F84A.INC (O DEL PIC USADO).
;------------------------------------------------

	CBLOCK
R_E_T_1
R_E_T_2
LCD_AUX
	ENDC

;------------------------------------------------
; RETARDO DE 50 MILISEGUNDOS.

retardo50ms
	MOVLW	D'55'
	MOVWF	R_E_T_1
	MOVLW	D'181'
	MOVWF	R_E_T_2
	CLRWDT
	CLRWDT
	DECFSZ	R_E_T_2,F
	GOTO	$-3
	DECFSZ	R_E_T_1,F
	GOTO	$-7
	RETURN

;------------------------------------------------
; RETARDO DE 2 MILISEGUNDOS.

retardo2ms
	MOVLW	D'249'
	MOVWF	R_E_T_1
	CLRWDT
	GOTO	$+1
	GOTO	$+1
	DECFSZ	R_E_T_1,F
	GOTO	$-4
	GOTO	$+1
	CLRWDT
	RETURN

;------------------------------------------------
; RETARDO DE 45 MICROSEGUNDOS.

retardo45us
	MOVLW	D'10'
	MOVWF	R_E_T_1
	CLRWDT
	DECFSZ	R_E_T_1,F
	GOTO	$-2
	RETURN

;------------------------------------------------
; ENVIA UNA INSTRUCCION O UN CARACTER AL LCD.
; EL BYTE A ENVIAR DEBE ESTAR GUARDADO EN W.

instruccion
	BCF		PORTA,RS
	GOTO	$+2

caracter
	BSF		PORTA,RS

	MOVWF	LCD_AUX
	MOVLW	0x0F		; PREPARO EL PUERTO B
	ANDWF	PORTB,F
	BSF		PORTA,E
	MOVLW	0xF0		; PREPARO LCD_AUX
	ANDWF	LCD_AUX,W
	IORWF	PORTB,F		; ENVIO AL PUERTO B
	NOP
	BCF		PORTA,E

	CALL	retardo45us

	MOVLW	0x0F		; PREPARO EL PUERTO B
	ANDWF	PORTB,F
	BSF		PORTA,E
	SWAPF	LCD_AUX,F	; PREPARO LCD_AUX
	MOVLW	0xF0
	ANDWF	LCD_AUX,W
	IORWF	PORTB,F		; ENVIO AL PUERTO B
	NOP
	BCF		PORTA,E

	RETURN

;------------------------------------------------
; ESPERA A QUE EL BUSY FLAG ESTE EN BAJO.

busy_flag
	BSF		STATUS,RP0
	MOVLW	0xF0
	IORWF	TRISB,F
	BCF		STATUS,RP0

	BCF		PORTA,RS
	BSF		PORTA,RW
	NOP
	BSF		PORTA,E
	NOP
	BTFSC	PORTB,7
	GOTO	$-1
	NOP
	BCF		PORTA,E

	NOP
	BSF		PORTA,E
	NOP
	NOP
	BCF		PORTA,E
	NOP
	BCF		PORTA,RW

	BSF		STATUS,RP0
	MOVLW	0x0F
	ANDWF	TRISB,F
	BCF		STATUS,RP0
	RETURN

;------------------------------------------------
; INICIALIZA EL LCD PARA 4 BITS:
; ARG1 -> 0010NFxx
; ARG2 -> 00001DCB
; ARG3 -> 000001(I/D)(SH)
; (x: PUEDE SER CUALQUIERA)
;
; EJEMPLO: 
; lcd_4bits		B'00100000', B'00001111', B'00000110'

lcd_4bits	MACRO	ARG1, ARG2, ARG3

	CALL	retardo50ms

	BCF		PORTA,RS
	MOVLW	0x0F		; PREPARO EL PUERTO B
	ANDWF	PORTB,F
	BSF		PORTA,E
	MOVLW	B'00100000'
	IORWF	PORTB,F		; ENVIO AL PUERTO B
	NOP
	BCF		PORTA,E
	CALL	retardo45us

	MOVLW	ARG1
	CALL	instruccion
	CALL	retardo45us

	MOVLW	ARG2
	CALL	instruccion
	CALL	retardo45us

	MOVLW	0x01
	CALL	instruccion
	CALL	retardo2ms

	MOVLW	ARG3
	CALL	instruccion
	CALL	retardo45us

	ENDM