
;                               LCD_CXX.INC
;
;                       Autor: Mikel Etxebarria
;                    (c) Microsystems Engineering (Bilbao)
;						
;
;El conjunto de rutinas que se presentan a continuación permiten realizar las tareas básicas 
;de control del módulo de visualización LCD. Este fichero se debe incluir en los futuros
;programas fuente mediante la directiva INCLUDE
;
;Permiten adaptarse a los nuevos tiempos de las nuevas pantallas LCD de Winteck
;
;Las rutinas están adaptadas a las velocidades más lentas de los nuevos módulo de winteck, en las
;cuales el tiempo de activación (Tc) de la señal ENABLE es de 40 uS.

#define ENABLE       bsf PORTE,2        ;Activa señal E
#define DISABLE      bcf PORTE,2        ;Desactiva señal E
#define LEER         bsf PORTE,1        ;Pone LCD en Modo RD
#define ESCRIBIR     bcf PORTE,1        ;Pone LCD en Modo WR
#define OFF_COMANDO  bcf PORTE,0        ;Desactiva RS (modo comando)
#define ON_COMANDO   bsf PORTE,0        ;Activa RS (modo dato

		CBLOCK	Lcd_var		;Inicio de las variables. Será la primera						
		Lcd_Temp_1		;direccón libre disponible
		Lcd_Temp_2
		ENDC											

;*************************************************************************
;UP_LCD: Configuración PIC para el LCD.
;
UP_LCD          bsf     STATUS,RP0      ;Banco 1
				bcf		STATUS,RP1
                clrf    PORTD           ;RD <0-7> salidas digitales
                clrf	PORTE	      	;Puerta E salidas
                bcf     STATUS,RP0      ;Banco 0
                OFF_COMANDO             ;RS=0
                DISABLE                 ;E=0
                return
;
;**************************************************************************
;LCD_BUSY: Lectura del Flag Busy y la dirección.
;
LCD_BUSY        LEER                    ;Pone el LCD en Modo RD
                bsf     STATUS,RP0           
                movlw   H'FF'
                movwf   PORTD           ;Puerta D como entrada
                bcf     STATUS,RP0      ;Selecciona el banco 0
                ENABLE                  ;Activa el LCD
                nop

LCD_BUSY_1	btfsc   PORTD,7         ;Chequea bit de Busy
                goto    LCD_BUSY_1		;
                DISABLE                 ;Desactiva LCD
                bsf     STATUS,RP0                               
                clrf    PORTD           ;Puerta D salida
                bcf     STATUS,RP0                              
                ESCRIBIR                ;Pone LCD en modo WR
                return

;**************************************************************************
;LCD_E: Pulso de Enable. En los nuevos LCD's esta señal debe estar a "0" unos 40uS antes de
;volver a activarse a "1".
;
LCD_E           ENABLE                  ;Activa E
		nop
                DISABLE                 ;Desactiva E
		movlw	.14
		movwf	Lcd_Temp_1
LCD_E_1		decfsz	Lcd_Temp_1,F	;Pierde unos 40 uS para la constante de tiempo Tc
		goto	LCD_E_1		;de los nuevos módulos LCD de winteck
		return
;
;**************************************************************************
;LCD_DATO: Escritura de datos en DDRAM o CGRAM. Envía el dato presente en el W
;
LCD_DATO        OFF_COMANDO             ;Desactiva RS (modo comando)
                movwf   PORTD           ;Valor ASCII a sacar por portd
                call    LCD_BUSY        ;Espera a que se libere el LCD
                ON_COMANDO              ;Activa RS (modo dato).
                goto    LCD_E           ;Genera pulso de E

;**************************************************************************
;LCD_REG: Escritura de comandos en el LCD. Envía el comando presente en el W

LCD_REG         OFF_COMANDO             ;Desactiva RS (modo comando)
                movwf   PORTD           ;Código de comando.
                call    LCD_BUSY        ;LCD libre?.
                goto    LCD_E           ;SI.Genera pulso de E.

;***************************************************************************
;LCD_INI: inicialización del LCD enviando el comando "Function Set" 3 veces consecutivas
;con un intervalo de unos 5 mS. El LCD queda borrado y el cursor en la primera posición

LCD_INI		movlw	b'00111000'
		call	LCD_REG		;Código de instrucción
		call	LCD_DELAY	;Temporiza
		movlw	b'00111000'
		call	LCD_REG		;Código de instrucción
		call	LCD_DELAY	;Temporiza
		movlw	b'00111000'
		call	LCD_REG		;Código de instrucción
		call	LCD_DELAY	;Temporiza
		movlw   b'00000001'     ;Borra LCD y Home.
                call    LCD_REG
                return

;*****************************************************************************
;LCD_DELAY: Rutina de temporización de unos 5 mS. Se emplean las variables Lcd_Temp_1
;y LCD_Temp_2 en lugar del TMR0. Este queda libre para las aplicaciones del usuario

LCD_DELAY:	clrwdt
                movlw	.10
                movwf	Lcd_Temp_1
                clrf	Lcd_Temp_2
LCD_DELAY_1:	decfsz	Lcd_Temp_2,F
		goto	LCD_DELAY_1
		decfsz	Lcd_Temp_1,F
		goto	LCD_DELAY_1
		return
            
