Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Pregunta sobre LCD y libreria
#1
Bueno comentar que a quien no lo sepa estoy leyendo el libro "Microcontrolador PIC 16F84 Desarroyo de proyectos", algo anticuado pero sinceramente muy bien explicado, el caso es que estoy en tema 13 que es el del LCD y en este tema hay algo que no me gusta y es que te da a entender que uses su libreria y no te compliques la vida, la verdad es que estamos en agosto y si en algun momento tengo tiempo de complicarme es ahora :dale2: , asi que ni corto ni perezoso Datasheet en mano y libro para observar como lo hacia me he hecho mi programita para manejar el LCD si bien se parece mucho, no es igual ya que conforme he ido entendiendo lo que tenia que ir haciendo lo he hecho y lo que he visto que no me era necesario pues no lo he hecho, pero me ha surgido una duda, este mi codigo.

Código:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC        ;Configuración para el grabador
        LIST    P=16F84A    ;Procesador
        INCLUDE <P16F84A.INC> ;Definicion de los operandos utilizados
        CBLOCK    0x0C
        LCD_Dato
        LCD_GuardaDato
        Retardo
        Contador_ms
        Contador_Bucle
        ENDC
#DEFINE        Pin_RS    PORTA,0    ;Poner a 1 para modo de datos, a 0 para modo comando
#DEFINE        Pin_RW    PORTA,1    ;1 LCD habilitado, 0 no hablitado
#DEFINE        Pin_E    PORTA,2    ;este es el Pin enable
#DEFINE        LCD_BUS    PORTB

;Usaremos solo el nibble alto para enviar los datos al LCD, no por ahorrar pines sino por la dificultad que conlleva

        org 0
Inicio        bsf    STATUS,RP0
        movlw    b'00001111'
        movwf    PORTB        ;Configuramos salidas y entradas puerto B
        movlw    b'00011000'
        movwf    PORTA        ;Configuramos salidas y entradas puerto A
        bcf    STATUS,RP0
        
Principal    call    Inicializa_LCD
        movlw    'H'
        call    Envio_Dato
        movlw    'o'
        call    Envio_Dato
        movlw    'l'
        call    Envio_Dato
        movlw    'a'
        call    Envio_Dato
        sleep

;=======================================================================================================================
;    La informacion para inicializar el LCD esta en el datasheet del mismo
;=======================================================================================================================
Inicializa_LCD    bcf    Pin_E
        bcf    Pin_RS
        bcf    Pin_RW
        movlw    d'16'
        call     Retardo_XXms    ;Retardo de 16ms el Datasheet indica un retardo >15ms al inicio
        movlw    b'00110000'
        call    Escribe_LCD    ;Enviamos el primer comando
        movlw    d'5'
        call     Retardo_XXms    ;Retardo de 5ms
        movlw    b'00110000'
        call    Escribe_LCD    ;Enviamos el segundo comando
        call     Retardo_2ms    ;Retardo de 2ms indica que debe ser mayor de 100us pero en este
        movlw    b'00110000'    ;momento no he creado una rutina de micro segundos
        call    Escribe_LCD    ;Enviamos el tercer comando        
        call     Retardo_2ms
        movlw    b'00100000'    ;momento no he creado una rutina de micro segundos
        call    Escribe_LCD    ;Enviamos el cuarto comando que es el que indica que trabajaremos con 4 bits
        call    Retardo_2ms
        call    LCD_2Lineas
        call    Borrar_LCD
        call    Cursor_OFF
        call    Cursor_INC
        return

;=======================================================================================================================
;    Subrutinas de comando del LCD
;=======================================================================================================================
LCD_2Lineas    movlw    b'00101000'    
        call    Envio_Comando    
        return
Borrar_LCD    movlw    b'00000001'    
        call    Envio_Comando    
        return    
Cursor_OFF    movlw    b'00001100'    
        call    Envio_Comando
        return    
Cursor_ON    movlw    b'00001110'    
        call    Envio_Comando
        return
Cursor_INC    movlw    b'00000110'    
        call    Envio_Comando        
        return    
                
;=======================================================================================================================
;                                         Envio_comando y Envia_caracter
;basicamente en estas subrutinas se hace el swap de nibble para enviar los 8 bits al LCD y se cambia el valor de Pin_RS
;dependiendo de si se va enviar un comando se pone a 0 y si se va a enviar undato se pone a 1
;=======================================================================================================================
Envio_Comando    bcf    Pin_RS
        goto    Envia
Envio_Dato    bsf    Pin_RS
Envia        movwf    LCD_GuardaDato
        call    Escribe_LCD
        swapf    LCD_GuardaDato,W
        call    Escribe_LCD
        call    Retardo_2ms    ;para comando deberian ser 2ms y para caracter unos 40us
        return
;=======================================================================================================================
;                                                Escribe LCD
;=======================================================================================================================


Escribe_LCD
        andlw    b'11110000'    ;solo nos quedamos con el nible alto del mensaje que enviamos que es el que usaremos
        movwf    LCD_Dato    ;Lo guardamos para enviar
        movf    LCD_BUS,W    ;Almacenamos lo que actualmete tiene el PORTB entero solo nos interesa el nibble bajo
        andlw    b'00001111'
        iorwf    LCD_Dato,F    ;Ahora unimos el nible alto de lo que queremos mandar con el nible bajo de lo que habia en el PORTB    
        
        movf    LCD_Dato,W    ;Colocamos lo que queremos enviar en W
        movwf    LCD_BUS        ;Y lo enviamos al BUS del LCD recordemos que el nibble bajo se ha mantenido solo a cambiado el nible alto
        bsf    Pin_E        ;activamos el lcd
        bcf    Pin_E        ;desactivamos el lcd    
            return


;=======================================================================================================================
;    Esta subrutina esta pensada para crear un retardo de XXX milisegundos exactos que se le pasaran por W
;    se han tenido en cuenta tanto el ciclo de asignacion de milisegundos de W como el de la llamada Retardo_XXms
;    el maximo aceptado es 255 ms si se realizan 4 asignaciones de W y 4 llamadas a Retardo_XXms se puede comprobar
;    que obtenemos 1 segundo exacto, todo ello para cristal de 4Mhz.
;                Diseñada por mi XD 08/08/14
;=======================================================================================================================
Retardo_XXms    movwf    Contador_ms    ;1 ciclo
Bucle_XXms    decfsz    Contador_ms    ;(ms)*1 ciclo + 2 al saltar
        goto    Retardo_1ms    ;(ms)*2 ciclos
        call    Ajuste_ciclos    ;2 ciclos al saltar
        return            ;2 ciclos al saltar
Retardo_1ms                ;2 ciclos viene del salto de llamada call o goto Retardo_1ms
        nop            ;1 ciclo
        nop            ;1 ciclo
        movlw    d'248'        ;1 ciclo establecemos el valor de K
        movwf    Retardo        ;1 ciclo
Bucle_1ms    nop            ;(K)*1 cilo
        decfsz    Retardo        ;(K)*1 ciclo + 2 al saltar
        goto    Bucle_1ms    ;(K)*2 ciclos
        goto     Bucle_XXms    ;2 ciclos al saltar
Ajuste_ciclos    
Retardo_Ajuste                ;2 ciclos viene del salto de llamada call
        nop            ;1 ciclo
        nop            ;1 ciclo
        nop            ;1 ciclo
        movlw    d'246'        ;1 ciclo establecemos el valor de K
        movwf    Retardo        ;1 ciclo
Bucle_Ajuste    nop            ;(K)*1 cilo
        decfsz    Retardo        ;(K)*1 ciclo + 2 al saltar
        goto    Bucle_Ajuste    ;(K)*2 ciclos
        return            ;2 ciclos al saltar
;==================================================================================================
;==================================================================================================
Retardo_2ms    movlw    d'2'
        call    Retardo_XXms
        return
        END



Bueno el caso es que en la lbreria que se usa en el libro hace una cosa tal que asi en este apartado, os he marcadolo que si esta en esta libreria,por lo que yo entiendo si no me equivoco es que guarda la configuracion de los puertos donde esta conectado el LCD, pero bajo mi punto de vista no deberia ya que no van a ser modificados, entiendo que quiere decir que es por si esos puertos se estuvieran usando para otra cosa distinta del LCD, si durante el codigo se modificaran lo entenderia pero tal cual, la verdad es que no.

Bueno la pregunta de todo esto seria, ¿tal vez sea que se pueden usar los puertos donde esta el LCD para otros fines mientras estan sin uso?

Código:
;=======================================================================================================================
;                                                Escribe LCD
;=======================================================================================================================


Escribe_LCD
        andlw    b'11110000'    ;solo nos quedamos con el nible alto del mensaje que enviamos que es el que usaremos
        movwf    LCD_Dato    ;Lo guardamos para enviar
        movf    LCD_BUS,W    ;Almacenamos lo que actualmete tiene el PORTB entero solo nos interesa el nibble bajo
        andlw    b'00001111'
        iorwf    LCD_Dato,F    ;Ahora unimos el nible alto de lo que queremos mandar con el nible bajo de lo que habia en el PORTB    

                ;========================================================================de aqui hacia abajo
    
        bsf    STATUS,RP0
        movf    PORTB,W
        movwf    LCD_GuardaB
        movlw    b'00001111'
        andwf    PORTB,F
        bcf    STATUS,RP0
   ;========================================================================hasta aqui
        movf    LCD_Dato,W    ;Colocamos lo que queremos enviar en W
        movwf    LCD_BUS        ;Y lo enviamos al BUS del LCD recordemos que el nibble bajo se ha mantenido solo a cambiado el nible alto
        bsf    Pin_E        ;activamos el lcd
        bcf    Pin_E        ;desactivamos el lcd    
   ;========================================================================    de aqui hacia abajo    
    bsf    STATUS,RP0
        movf    LCD_GuardaB,W
        movwf    PORTB
        bcf    STATUS,RP0    
   ;======================================================================== hasta aqui
        return
Citar
#2
El LCD si no lo usas lo puedes "apagar" y usar las patillas para otra cosa. Hoy en dia puedes conectar los lcds por i2c, lo que te ahorra usar muchas lineas y tambien facilita la conexion de varios dispositivos de forma mas sencilla.

Esta muy bien que te aventures a crear librerias aunque te queden similares, asi se aprende para otro dia cuando tengas un componente desconocido.
Citar
#3
Yo tengo ese libro, pero ahora no lo tengo a mano. Lo que si recuerdo es que en un proyecto usaba los 4 pines de datos del lcd para también poder manejar un teclado matricial. En ese ejemplo mostraba que cuando el pin E del LCD estaba en alto mandabas el comando o el dato al LCD por los 4 pines de datos (DB4-DB7), pero cuando estaba bajo el LCD no tomaba en cuenta esos pines de datos y por tanto podías usarlos para hacer el proceso secuencial de lectura del teclado matricial (o cualquier otra cosa).

Una pena que con la excusa de la piratería los autores no hayan editado el libro con un microcontrolador más moderno como el 16F88 que es la evolución natural del 16F84 (entre ambos está el 16F628)
Citar
#4
Gracias a ambos, la verdad es que me resultaba raro ese cambio si no era para reutilizar los puertos. Mola
Citar