martes, 28 de septiembre de 2010

LCD PROTEUS PIC 16F84A

AQUÍ LES DEJO EL CÓDIGO LISTO PARA ENSAMBLAR EN MPLAB Y GENERAR EL .HEX,
NO HAY NECESIDAD DE LIBRERÍAS ADICIONALES PORQUE YA LAS CARGUE N EL MISMO CÓDIGO.
SALUDOS, ESPERO LO DISFRUTEN, CAMBIEN EL MENSAJE QUE SE DESPLEGARÁ EN PANTALLA.
SOLO COPIEN Y PEGUEN EL CODIGO EN EL BLOC DE NOTAS.
EL AUTOR NO SE RESPONSABILIZA DEL MAL USO DE ESTOS MATERIALES.
POR FAVOR SI QUIERE ESTA INFORMACIÓN CITE LA FUENTE Y EL AUTOR.

EL VÍDEO SE ENCUENTRA EN:

http://www.youtube.com/watch?v=llCTVCrwCRk


















;************************************ Mensaje*******************************************
;
; El módulo LCD visualiza un mensaje largo (más de 16 caracteres) que se desplaza a lo largo
; de la pantalla. Se utiliza la subrutina LCD_MensajeMovimiento de la librería LCD_MENS.INC.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE       
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    ENDC

; ZONA DE CÓDIGOS ********************************************************************

    ORG    0
Inicio
    call    LCD_Inicializa            ; Prepara la pantalla.
Principal
    movlw    Mensaje0                ; Apunta al mensaje.
    call    LCD_MensajeMovimiento
    goto    Principal                ; Repite la visualización.

; "Mensajes" ----------------------------------------------------------------------------
;
Mensajes
    addwf    PCL,F
Mensaje0                            ; Posición inicial del mensaje.
    DT "           "                ; Espacios en blanco al principio para mejor
    DT "HOLA MUY BUENOS DIAS  "
    DT "UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA UNAD  "    ; visualización.
       DT "TECNOLOGIA EN ELECTRONICA  "
    DT "FRANCISCO JAVIER HILARON NOVOA. "
    DT "                ", 0x0        ; Espacios en blanco al final.

   
   
   



;-----------------------LIBRERÍAS--------------------------------------------------

;**************************** Librería "LCD_4BIT.INC" ***********************************

; ZONA DE DATOS *********************************************************************

    CBLOCK
    LCD_Dato
    LCD_GuardaDato
    LCD_GuardaTRISB
    LCD_Auxiliar1
    LCD_Auxiliar2
    ENDC

LCD_CaracteresPorLinea    EQU    .16            ; Número de caracteres por línea de la pantalla.

#DEFINE  LCD_PinRS    PORTA,0
#DEFINE  LCD_PinRW    PORTA,1
#DEFINE  LCD_PinEnable    PORTA,2
#DEFINE  LCD_BusDatos    PORTB

; Subrutina "LCD_Inicializa" ------------------------------------------------------------
;
; Inicialización del módulo LCD: Configura funciones del LCD, produce reset por software,
; borra memoria y enciende pantalla. El fabricante especifica que para garantizar la
; configuración inicial hay que hacerla como sigue:
;
LCD_Inicializa
    bsf        STATUS,RP0                ; Configura las líneas conectadas al pines RS,
    bcf        LCD_PinRS                ; R/W y E.
    bcf        LCD_PinEnable
    bcf        LCD_PinRW
    bcf        STATUS,RP0
    bcf        LCD_PinRW                ; En caso de que esté conectado le indica
                                    ; que se va a escribir en el LCD.
    bcf        LCD_PinEnable            ; Impide funcionamiento del LCD poniendo E=0.
    bcf     LCD_PinRS                ; Activa el Modo Comando poniendo RS=0.
    call    Retardo_20ms
    movlw    b'00110000'   
    call    LCD_EscribeLCD            ; Escribe el dato en el LCD.
    call    Retardo_5ms   
    movlw    b'00110000'   
    call    LCD_EscribeLCD
    call    Retardo_200micros
    movlw    b'00110000'   
    call    LCD_EscribeLCD
    call    Retardo_20micros        ; Este retardo es necesario para simular en PROTEUS.
    movlw    b'00100000'                ; Interface de 4 bits.
    call    LCD_EscribeLCD
    call    Retardo_20micros        ; Este retardo es necesario para simular en PROTEUS.
   
; Ahora configura el resto de los parámetros:

    call    LCD_2Lineas4Bits5x7        ; LCD de 2 líneas y caracteres de 5x7 puntos.
    call    LCD_Borra                ; Pantalla encendida y limpia. Cursor al principio
    call    LCD_CursorOFF            ; de la línea 1. Cursor apagado.
    call    LCD_CursorIncr            ; Cursor en modo incrementar.
    return

; Subrutina "LCD_EscribeLCD" -----------------------------------------------------------
;
; Envía el dato del registro de trabajo W al bus de dato y produce un pequeño pulso en el pin
; Enable del LCD. Para no alterar el contenido de las líneas de la parte baja del Puerto B que
; no son utilizadas para el LCD (pines RB3:RB0), primero se lee estas líneas y después se
; vuelve a enviar este dato sin cambiarlo.

LCD_EscribeLCD
    andlw    b'11110000'                ; Se queda con el nibble alto del dato que es el
    movwf    LCD_Dato                ; que hay que enviar y lo guarda.
    movf    LCD_BusDatos,W            ; Lee la información actual de la parte baja
    andlw    b'00001111'                ; del Puerto B, que no se debe alterar.
    iorwf    LCD_Dato,F                ; Enviará la parte alta del dato de entrada
                                    ; y en la parte baja lo que había antes.
    bsf        STATUS,RP0                ; Acceso al Banco 1.
    movf    TRISB,W                    ; Guarda la configuración que tenía antes TRISB.
    movwf    LCD_GuardaTRISB
    movlw    b'00001111'                ; Las 4 líneas inferiores del Puerto B se dejan
    andwf    PORTB,F                    ; como estaban y las 4 superiores como salida.
    bcf        STATUS,RP0                ; Acceso al Banco 0.
;
    movf    LCD_Dato,W                ; Recupera el dato a enviar.
    movwf    LCD_BusDatos            ; Envía el dato al módulo LCD.
    bsf        LCD_PinEnable            ; Permite funcionamiento del LCD mediante un pequeño
    bcf        LCD_PinEnable            ; pulso y termina impidiendo el funcionamiento del LCD.
    bsf        STATUS,RP0                ; Acceso al Banco 1. Restaura el antiguo valor en
    movf    LCD_GuardaTRISB,W        ; la configuración del Puerto B.
    movwf    TRISB
    bcf        STATUS,RP0                ; Acceso al Banco 0.
    return

; Subrutinas variadas para el control del módulo LCD -----------------------------------------
;
;Los comandos que pueden ser ejecutados son:
;
LCD_CursorIncr                        ; Cursor en modo incrementar.
    movlw    b'00000110'
    goto    LCD_EnviaComando

LCD_CursorOFF                        ; Pantalla encendida y cursor apagado.
    movlw    b'00001100'
    goto    LCD_EnviaComando

LCD_Borra                            ; Borra toda la pantalla, memoria DDRAM y pone el
    movlw    b'00000001'                ; cursor a principio de la línea 1.
    goto    LCD_EnviaComando
LCD_2Lineas4Bits5x7                    ; Define la pantalla de 2 líneas, con caracteres
    movlw    b'00101000'                ; de 5x7 puntos y conexión al PIC mediante bus de
;    goto    LCD_EnviaComando        ; 4 bits.

; Subrutinas "LCD_EnviaComando" y "LCD_Caracter" ------------------------------------
;
; "LCD_EnviaComando". Escribe un comando en el registro del módulo LCD. La palabra de
; comando ha sido entregada a través del registro W.  Trabaja en Modo Comando.
; "LCD_Caracter". Escribe en la memoria DDRAM del LCD el carácter ASCII introducido a
; a través del registro W. Trabaja en Modo Dato.
;
LCD_EnviaComando
    bcf        LCD_PinRS                ; Activa el Modo Comando, poniendo RS=0.
    goto    LCD_Envia

LCD_Caracter
    bsf        LCD_PinRS                ; Activa el "Modo Dato", poniendo RS=1.
    call    LCD_CodigoCGROM            ; Obtiene el código para correcta visualización.

LCD_Envia
    movwf    LCD_GuardaDato            ; Guarda el dato a enviar.
    call    LCD_EscribeLCD            ; Primero envía el nibble alto.
    swapf    LCD_GuardaDato,W        ; Ahora envía el nibble bajo. Para ello pasa el
                                    ; nibble bajo del dato a enviar a parte alta del byte.
    call    LCD_EscribeLCD            ; Se envía al visualizador LCD.
    btfss    LCD_PinRS                ; Debe garantizar una correcta escritura manteniendo
    call    Retardo_2ms                ; 2 ms en modo comando y 50 µs en modo cáracter.
    call    Retardo_50micros
    return   

; Subrutina "LCD_CodigoCGROM" -----------------------------------------------------------
;
; A partir del carácter ASCII número 127 los códigos de los caracteres definidos en la
; tabla CGROM del LM016L no coinciden con los códigos ASCII. Así por ejemplo, el código
; ASCII de la "Ñ" en la tabla CGRAM del LM016L es EEh.
;
; Esta subrutina convierte los códigos ASCII de la "Ñ", "º" y otros, a códigos CGROM para que
; que puedan ser visualizado en el módulo LM016L.
;
; Entrada:    En (W) el código ASCII del carácter que se desea visualizar.
; Salida:    En (W) el código definido en la tabla CGROM.

LCD_CodigoCGROM
    movwf    LCD_Dato                ; Guarda el valor del carácter y comprueba si es
LCD_EnheMinuscula                    ; un carácter especial.
    sublw    'ñ'                     ; ¿Es la "ñ"?
    btfss    STATUS,Z
    goto    LCD_EnheMayuscula        ; No es "ñ".
    movlw    b'11101110'                ; Código CGROM de la "ñ".
    movwf    LCD_Dato
    goto    LCD_FinCGROM
LCD_EnheMayuscula
    movf    LCD_Dato,W                ; Recupera el código ASCII de entrada.
    sublw    'Ñ'                     ; ¿Es la "Ñ"?
    btfss    STATUS,Z
    goto    LCD_Grado                ; No es "Ñ".
    movlw    b'11101110'                ; Código CGROM de la "ñ". (No hay símbolo para
    movwf    LCD_Dato                ; la "Ñ" mayúscula en la CGROM).
    goto    LCD_FinCGROM   
LCD_Grado
    movf    LCD_Dato,W                ; Recupera el código ASCII de entrada.
    sublw    'º'                     ; ¿Es el símbolo "º"?
    btfss    STATUS,Z
    goto    LCD_FinCGROM            ; No es "º".
    movlw    b'11011111'                ; Código CGROM del símbolo "º".
    movwf    LCD_Dato
LCD_FinCGROM
    movf    LCD_Dato,W                ; En (W) el código buscado.
    return





;**************************** Librería "LCD_MENS.INC" ********************************


    CBLOCK
    LCD_ApuntaCaracter                ; Indica la posición del carácter a visualizar
                                    ; respecto del comienzo de todos los mensajes,
                                    ; (posición de la etiqueta "Mensajes").
    LCD_ValorCaracter                ; Código ASCII del carácter a
    ENDC                            ; visualizar.

; Los mensajes tienen que estar situados dentro de las 256 primeras posiciones de la
; memoria de programa, es decir, no pueden superar la dirección 0FFh.

                    ; Vuelve al programa principal.

; Subrutina "LCD_MensajeMovimiento" -----------------------------------------------------
;
; Visualiza un mensaje de mayor longitud que los 16 caracteres que pueden representarse
; en una línea, por tanto se desplaza a través de la pantalla.
;
; En el mensaje debe dejarse 16 espacios en blanco, al principio y al final para
; conseguir que el desplazamiento del mensaje sea lo más legible posible.
;
    CBLOCK   
    LCD_CursorPosicion                ; Contabiliza la posición del cursor dentro de la
    ENDC                            ; pantalla LCD

LCD_MensajeMovimiento
    movwf    LCD_ApuntaCaracter        ; Posición del primer carácter del mensaje.
    movlw    Mensajes                ; Halla la posición relativa del primer carácter
    subwf    LCD_ApuntaCaracter,F    ; del mensaje respecto de la etiqueta "Mensajes".
    decf    LCD_ApuntaCaracter,F    ; Compensa la posición que ocupa "addwf PCL,F".
LCD_PrimeraPosicion
    clrf    LCD_CursorPosicion        ; El cursor en la posición 0 de la línea.
    call    LCD_Borra                ; Se sitúa en la primera posición de la línea 1 y
LCD_VisualizaCaracter                ; borra la pantalla.
    movlw    LCD_CaracteresPorLinea    ; ¿Ha llegado a final de línea?
    subwf    LCD_CursorPosicion,W
    btfss    STATUS,Z
    goto    LCD_NoEsFinalLinea
LCD_EsFinalLinea
    call    Retardo_200ms            ; Lo mantiene visualizado durante este tiempo.
    call    Retardo_200ms
    movlw    LCD_CaracteresPorLinea-1; Apunta a la posición del segundo carácter visualizado
    subwf    LCD_ApuntaCaracter,F    ; en pantalla, que será el primero en la siguiente
    goto    LCD_PrimeraPosicion         ; visualización de línea, para producir el efecto
LCD_NoEsFinalLinea                    ; de desplazamiento hacia la izquierda.
    movf    LCD_ApuntaCaracter,W
    call    Mensajes                ; Obtiene el ASCII del carácter apuntado.
    movwf    LCD_ValorCaracter        ; Guarda el valor de carácter.
    movf    LCD_ValorCaracter,F        ; Lo único que hace es posicionar flag Z. En caso
    btfsc    STATUS,Z                ; que sea "0x00", que es código indicador final   
    goto    LCD_FinMovimiento        ; de mensaje, sale fuera.
LCD_NoUltimoCaracter2
    call    LCD_Caracter            ; Visualiza el carácter ASCII leído.
    incf    LCD_CursorPosicion,F    ; Contabiliza el incremento de posición del
                                    ; cursor en la pantalla.
    incf    LCD_ApuntaCaracter,F    ; Apunta a la siguiente posición por visualizar.
    goto    LCD_VisualizaCaracter    ; Vuelve a visualizar el siguiente carácter
LCD_FinMovimiento                    ; de la línea.
    return                            ; Vuelve al programa principal.
   

;**************************** Librería "RETARDOS.INC" *********************************

; ZONA DE DATOS *********************************************************************

    CBLOCK
    R_ContA                        ; Contadores para los retardos.
    R_ContB
    R_ContC
    ENDC

; RETARDOS de 20 hasta 500 microsegundos ------------------------------------------------

Retardo_200micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    movlw    d'64'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.

Retardo_50micros                ; La llamada "call" aporta 2 ciclos máquina.
    nop                            ; Aporta 1 ciclo máquina.
    movlw    d'14'                ; Aporta 1 ciclo máquina. Este es el valor de "K".
    goto    RetardoMicros        ; Aporta 2 ciclos máquina.

Retardo_20micros                ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'5'                ; Aporta 1 ciclo máquina. Este es el valor de "K".

RetardoMicros
    movwf    R_ContA                ; Aporta 1 ciclo máquina.
Rmicros_Bucle
    decfsz    R_ContA,F            ; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto    Rmicros_Bucle        ; Aporta (K-1)x2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.

; RETARDOS de 1 ms hasta 200 ms. --------------------------------------------------------
;
Retardo_200ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'200'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.

Retardo_20ms                    ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'20'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.

Retardo_5ms                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'5'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.

Retardo_2ms                        ; La llamada "call" aporta 2 ciclos máquina.
    movlw    d'2'                ; Aporta 1 ciclo máquina. Este es el valor de "M".
    goto    Retardos_ms            ; Aporta 2 ciclos máquina.

Retardos_ms
    movwf    R_ContB                ; Aporta 1 ciclo máquina.
R1ms_BucleExterno
    movlw    d'249'                ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
    movwf    R_ContA                ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
    nop                            ; Aporta KxMx1 ciclos máquina.
    decfsz    R_ContA,F            ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
    goto    R1ms_BucleInterno    ; Aporta (K-1)xMx2 ciclos máquina.
    decfsz    R_ContB,F            ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto    R1ms_BucleExterno     ; Aporta (M-1)x2 ciclos máquina.
    return                        ; El salto del retorno aporta 2 ciclos máquina.






END                                ; Fin del programa.

8 comentarios:

  1. COMPÀÑERO ME PODRIA DECIR LA LISTA DE MATERIALES Y EL PLANO DEL CIRCUITO??? ES QUE SOY NUEVO EN ESTO... =)

    ResponderEliminar
  2. Hola que tal!
    Te agradezco por tu post.
    Ya lo compile en MPLAB y genera muchos
    errores:
    ": Symbol not previously defined (PORTA)", "Symbol not previously defined " y asi
    con la mayoria de instrucciones.
    No se si puedas ayudarme con esto, gracias.

    ResponderEliminar
  3. hola me podrias ayudar estoy armando un teclado utilisando una memoria ram 6116 unos circuitos y un display LCD C61602L, no se como armar el display, cuales son los pines que van a la energia y a los pines para la memoria podrias ayyudarme con un diagrama mosjauregui@hotmail.com

    ResponderEliminar
  4. Genera errores por que falta incluir la libreria del 16f84a

    ResponderEliminar
  5. hola lo compile y esta bn pero m podrias pasar xfavor la lista d materiales y el diagrama xfa

    ResponderEliminar
  6. Esos ejemplos estan en el libro:

    Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
    ; E. Palacios, F. Remiro y L. López. www.pic16f84a.com
    ; Editorial Ra-Ma. www.ra-ma.es

    ResponderEliminar
  7. puedes compartir tu codigo gracias


    kyle.milera7@gmail.com

    ResponderEliminar
  8. Hola, yo lo compilo y me sale un error y no me aparece el codigo en formato .hex

    ResponderEliminar