# Problema con control de Display LCD en PIC16F628A



## xMaxy93x (Sep 18, 2011)

Bueno les cuento que estuve tratando de inicializar el Display con el PIC 16F628A y al parecer inicializa bien (abajo la captura) pero al momento de enviarle una letra, no me la toma... Simule el programa con el Proteus y los datos son enviados pero nose porque no escribe :S
Espero puedan ayudarme, gracias ^^

Aca las descripcion de pines y la imagen

RB0-RB7  ----> D0-D7
RA1  --------> enable
RA2  --------> RS
RA3  --------> RW

Imagen:






Bueno aca abajo les dejo el program para ver si me pueden dar una mano :S


```
#INCLUDE <P16F628A.INC>  ;Declaracion del Micro

D1        EQU    20H                ;Variables
D2        EQU    21H
D3        EQU    22H

D4        EQU 24H
D5        EQU 25H
D6        EQU 26H
D7        EQU 27H
CONT    EQU 28H

    ORG    00H
    NOP                                ; le da tiempo al micro para estabilizarse
    NOP
    GOTO    INICIO

INICIO        
    BSF            STATUS,RP0                
    MOVLW    B'00000000'             ;Dirección para configurar el puerto A
    MOVWF    TRISA
    MOVLW    B'00000000'                ;Direccion para configurar el puerto B
    MOVWF    TRISB
    MOVLW    B'10000000'
    MOVWF    OPTION_REG
    BCF        STATUS,5    
    MOVLW    B'00000111'
    MOVWF    CMCON        
    CLRF        PORTA
    CLRF            PORTB
    NOP                                ;le da tiempo al micro para estabilizarse
    NOP
; Configuracion de los puertos del Micro

DISPLAY    
    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00000000'                      ;
    MOVWF    PORTA            ;
    MOVLW    B'00000001'                ; Clear Display
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL      TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00111100'                ; Function Set
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00111100'                ; Function Set
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00001111'                ; Display Control
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00000111'                 ; Entry Mode Set
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00000010'                ; Cursor Home 
    MOVWF    PORTB             ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            TEMPO            ;

    BSF        PORTA,1            ; act ENABLE
    MOVLW    B'00011100'                 ; Cursor/Display Shift
    MOVWF    PORTB            ;
    BCF        PORTA,1            ; desact ENABLE
    CALL            DELAY            ;
    NOP    
    NOP
    NOP
    
CLOCK

    BSF        PORTA,1            ; act ENABLE
    BSF        PORTA,2            ; RS en 1
    BCF        PORTA,3            ; RW en 0
    MOVLW    B'01001000'                ; H
    MOVWF    PORTB            ; H -> PORTB
    CALL            DELAY            ; Delay 1 segundo
    BCF        PORTA,1            ; desact ENABLE
    CALL            DELAY            ; Delay 1 segundo

BUCLE    
    GOTO      BUCLE            ;

;---------------------------------------------------------------------
;Subrutinas

DELAY
    MOVLW    0x07
    MOVWF    D1
    MOVLW    0x2F
    MOVWF    D2
    MOVLW    0x03
    MOVWF    D3

DELAY_0
    DECFSZ    D1,F
    GOTO    $+2
    DECFSZ    D2,F
    GOTO    $+2
    DECFSZ    D3,F
    GOTO    DELAY_0
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP

    RETURN

TEMPO
    MOVLW    0x0D
    MOVWF    CONT
CICLO
    NOP
    DECFSZ    CONT,1
    GOTO    CICLO
    
    RETURN

    END
```

Y les dejo por las dudas el archivo adjunto:


----------



## Gudino Roberto duberlin (Sep 18, 2011)

xMaxy93x dijo:


> Bueno les cuento que estuve tratando de inicializar el Display con el PIC 16F628A y al parecer inicializa bien (abajo la captura) pero al momento de enviarle una letra, no me la toma... Simule el programa con el Proteus y los datos son enviados pero nose porque no escribe :S
> Espero puedan ayudarme, gracias ^^
> 
> Aca las descripcion de pines y la imagen
> ...



Hola amigo, bien bueno el pin llamado VEE del LCD controla el contraste del mismo, debes colocar un preset.-


----------



## xMaxy93x (Sep 21, 2011)

Gudino Roberto duberlin   Ya coloque el preset pero sigo teniendo el mismo problema :S, es por eso que pienso que hay algo mal en el programa pero no logro averiguar que :S....


----------



## D@rkbytes (Sep 22, 2011)

Gudino Roberto duberlin dijo:


> Hola amigo, bien bueno el pin llamado VEE del LCD controla el contraste del mismo, debes colocar un preset.-


En la simulación con PROTEUS no hace falta ponerlo.
Ni siquiera los pines de alimentación. En la practica si son necesarios.

Este código lo programe en PICBASIC por lo sencillo de manipular con pocas instrucciones
funciones complejas como la de los LCD.
En PBP solo use estas pocas líneas de código para mostrar el clásico HOLA MUNDO


```
DEFINE LCD_DREG PORTB       'Puerto de datos del LCD
DEFINE LCD_DBIT     4       'Iniciar los datos del LCD en el Bit 4
DEFINE LCD_RSREG PORTB      'Puerto del LCD (Register Select)
DEFINE LCD_RSBIT    1       'Bit del LCD RB1 (Register Select)
DEFINE LCD_EREG PORTB       'Puerto del LCD (Enable)
DEFINE LCD_EBIT     3       'Bit del LCD RB3 (Enable)
DEFINE LCD_RWREG PORTB      'Puerto del LCD (RW)
DEFINE LCD_RWBIT    2       'Bit del LCD RB2 (RW)
DEFINE LCD_BITS     4       'Tamaño del BUS del LCD
DEFINE LCD_LINES    2       'Número de líneas del LCD
DEFINE LCD_COMMANDUS 2000   'Comando del retardo en Us.
DEFINE LCD_DATAUS   50      'Retardo del tiempo de datos en Us.
DEFINE OSC 4

CMCON = 7
MyDato VAR WORD
MyDato = 666
TRISB = %00000000

PAUSE   500
LCDOUT  $FE,1
LCDOUT  $FE,1,"HOLA MUNDO"
LCDOUT  $FE,$C0,"D@RKBYTES ",#MyDato
END
```

La selección del registro de pines yo lo configure así por comodidad
al acomodar los pines del LCD con los pines del 16F628 pero se pueden cambiar los DEFINES.
Los pines de datos no usados van a tierra.
Pero en la simulación tampoco es necesaria su conexión. 
Miren esta foto adjunta para ver como funciona la simulación sin estos pines.



xMaxy93x dijo:


> Bueno les cuento que estuve tratando de inicializar el Display con el PIC 16F628A y al parecer inicializa bien (abajo la captura) pero al momento de enviarle una letra, no me la toma... Simule el programa con el Proteus y los datos son enviados pero no sé porque no escribe :S
> Espero puedan ayudarme, gracias ^^


Pues revisando tu código, no encontré la función donde mandas letras al display.
Por ahí puede estar el error, escribe tu función para revisarla.


----------



## xMaxy93x (Sep 22, 2011)

Darkbytes... Que tipo de funcion para enviar una letra al display? 
El año pasado en el colegio trabajamos motorola (HC08QY4A) y enviabamos la inicializacion al micro y luego con habilitar Rs ya podiamos enviar caracteres. Este año usamos PIC y pense que podria ser lo mismo...

Aca esta el codigo, donde habilite Rs y envia una H al display

CLOCK

BSF PORTA,1 ; act ENABLE
BSF PORTA,2 ; RS en 1
BCF PORTA,3 ; RW en 0
MOVLW B'01001000' ; H
MOVWF PORTB ; H -> PORTB
CALL DELAY ; Delay 1 segundo
BCF PORTA,1 ; desact ENABLE
CALL DELAY ; Delay 1 segundo

Aclaro que lo que estoy haciendo ahora no es algo de la escuela, es algo que estoy intentando hacer yo.


----------



## D@rkbytes (Sep 23, 2011)

Saludos. 
Ok. Te mando este ejemplo para PIC16F84 es viejito pero te puedes dar una idea
de como mandar caracteres al LCD. Se trata de un frecuencimetro con LCD 1X16
Si lo quieres compilar usa un MPLAB viejito tambien, porque este código usa
unas instrucciones que ahora ya son obsoletas como OPTION y TRIS
En fin, solo dale una mirada al código ASM  y puede ser que saques tu propia rutina.
PD: Mando tambien el proyecto de simulación en PROTEUS falla,
pero sirve para ver las conexiones entre el PIC y el LCD que se uso en ese proyecto.
Y aparte si se puede ver en la simulación lo que se manda al LCD
Pero al terminar la presentación, ya que empieza a contar, manda overflow
con solo 1Khz de entrada...
BYE4NOW


----------



## D@rkbytes (Sep 23, 2011)

Mira, por aca hay algo que esta mas sencillo de implementar gracias al amigo MaMu
https://www.forosdeelectronica.com/f24/control-display-lcd-microcontrolador-pic-201/


```
;****************************************** http://www.x-robotics.com *******
; PROGRAMA : hola.asm
; Funcion  : Programa de ejemplo de utilizacion de rutinas para control de
;    	     LCD Hitachi 44780 o compatible.
;  Revision : 1.0                            Programa para : PIC16F84
; CPU Clock : 4 MHz                      Reloj instruccion : 1 us
;       WDT : Deshabilitado                  Tipo de reloj : XT  
; Code Prot : OFF            
;****************************************** http://www.x-robotics.com *******
;
;
;****************************** Igualdades **********************************
;                           
           list p=16c84      ;Procesador PIC16c84  
           list c=132        ;Listado a 132 caracteres

TIMER0     equ 01            ;Registro del TIMER0
OPCION     equ 0x1           ;Registro de opciones,p gina 1
PCL        equ 0x2           ;Registro PC
PCLATH     equ 0xa           ;Registro alto del PC
STATUS     equ 03            ;Registro de estado
RA         equ 05            ;Puerta A
RB         equ 06            ;Puerta B
PORTA      equ 05            ;Puerta A
PORTB      equ 06            ;Puerta B
TRISA      equ 0x5           ;Reg. de programaci¢n de la puerta A, p gina 1
TRISB      equ 0x6           ;Reg. de programaci¢n de la puerta B, p gina 1 
INTCON     equ 0xb           ;Registro de control de interrupciones
DATO_A     equ 0xc           ;Registro del dato A
DATO_B     equ 0xd           ;Registro del dato B
RESUL      equ 0xe           ;Registro de resultados
TEMPO1     equ 0xf           ;Registro temporal 1
TEMPO2     equ 0x10          ;Registro temporal 2
OFFSET     equ 0x11          ;Variable de desplazamientos de mensajes
RP0     EQU     05h          ;Bit 5 registro STATUS
Digito  EQU     1Fh	     ;Cursor para leer la tabla de datos.
                              

;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>                              
                            
                ORG     00h             ;Direccion del Vector de RESET

                GOTO    INICIO          ;Comienza el programa

                ORG     05h             ;detras del Vector Interrupcion
        

		Include "LCD.LIB"  
   


;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
                                                          
INICIO          CLRF    Digito          ;Pone a 0 la variable digito                              
                CALL    LCD_PORT        ;Puertos en modo LCD        
                BCF     RA,0            ;Desactiva RS del modulo LCD
                BCF     RA,2            ;Desactiva E del modulo LCD 
START           CALL    LCD_INI         ;Inicia LCD (CFG puertos...)                 
START_1         MOVLW   b'00000001'     ;Borrar LCD y Home          
                CALL    LCD_REG                                     
                MOVLW   b'00000110'     ;                           
                CALL    LCD_REG                                     
                MOVLW   b'00001100'     ;LCD On, cursor Off,Parpadeo Off         
                CALL    LCD_REG                                     
                MOVLW   0x80            ;Direccion caracter
                CALL    LCD_REG                           
                                                                    
REPETIR       	MOVF    Digito,w        ;W=Digito
                CALL    DATO_1          ;Coge el caracter           
                IORLW   0               ;Compara 
                BTFSC   STATUS,2        ;Es el ultimo?             
                GOTO    acabar		;Si               
                CALL    LCD_DATOS       ;Visualiza caracter         
                INCF    Digito,f        ;Incrementa numero de Digito
                GOTO    REPETIR         ;Vuelve a escribir
                                                                    
acabar		nop
		goto	acabar		;Buclee infinito
                  
;<<<<<<---------------------- TABLA DE DATOS ------------------------->>>>>>> 
                                                                   
DATO_1          ADDWF   PCL,1                  
                RETLW   'H'             
                RETLW   'O'
                RETLW   'L'           
                RETLW   'A'           
                RETLW   ' '           
                RETLW   'M'           
                RETLW   'U'           
                RETLW   'N'           
                RETLW   'D'           
                RETLW   'O'           
                RETLW 	0x00           
 
;<<<<<<\\\\\\\\\\\THE\\\\\\\\\\\\\\\\////////////////END//////////////>>>>>>>	
		
		END
```
Ya solo lo adaptas para el 16F628 no se te olvide setear el puerto A como digital


----------



## xMaxy93x (Sep 23, 2011)

Darkbytes 

Creo que maso menos lo entendi, voy a ver si lo puedo hacer funcionar asi... Muchas Gracias 
Una pregunta: Acaso hay una libreria para facilitar la config del LCD? Donde puedo verla? o averiguar si hay mas? Creo que eso no lo sabia, se me aclararon un par de cosas ahora jaja ^^


----------



## D@rkbytes (Sep 24, 2011)

xMaxy93x dijo:


> Una pregunta: Acaso hay una libreria para facilitar la config del LCD? Donde puedo verla? o averiguar si hay mas? Creo que eso no lo sabia, se me aclararon un par de cosas ahora jaja ^^


Saludos. 
Pues si, si existen varias, cada programador puede hacer la suya.
Aqui te paso la libreria LCD.LIB que es para el código mencionado anteriormente.
Fue creada por alguien de http://www.x-robotics.com


----------



## mcpiebot (Sep 24, 2011)

Me parece que te falta la inicializacion para la pantalla, revisa esta nota de aplicacion de microchip.

Saludos!


----------



## D@rkbytes (Sep 24, 2011)

mcpiebot dijo:


> Me parece que te falta la inicializacion para la pantalla,


La inicialización esta en la libreria LCD.LIB

```
LCD_INI        MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                MOVLW   b'00111000'
                CALL    LCD_REG         ;Codigo de instruccion
                CALL    DELAY_5MS       ;Temporiza 5 mS.
                RETURN
```


----------



## Basalto (Sep 24, 2011)

Ya lo dije muchas veces. Yo no me fiaría de los resultados de los LCD en el proteus.


----------



## mcpiebot (Sep 24, 2011)

Darkbytes dijo:


> La inicialización esta en la libreria LCD.LIB
> 
> ```
> LCD_INI        MOVLW   b'00111000'
> ...



No en tu código, si no en el código del compañero que inicio el post que es de quien estamos analizando el problema.

Saludos!


----------



## D@rkbytes (Sep 25, 2011)

Saludos xMaxy93x 
Bien pues aca te tengo ahora si la solución definitiva para el LCD sobre un 16F628A
En este ejemplo viene todo en un solo archivo asm, no usa librerias.
Viene con las funciones explicadas en español paso a paso.
Tambien incluye un PDF con la explicación del manejo del LCD
en configuración para usar 4 Bits y no los 8 y su correspondiente simulación.
Originalmente fue escrito para un 16F84 solo le hice unas modificaciones
para correrlo sobre un 16F628A, como ya no uso el 16F84 no pude probar 
los anteriores ejemplos en proto, y en el proteus no los pude correr
ni espantandolos  Pero este si funciona en ambos XD
Bueno, espero haberte servido para el proposito y hasta pronto.


----------



## xMaxy93x (Oct 2, 2011)

Darkbytes

MUCHAS GRACIAS ^^ la verdad no lo aplique al mio aun, pero ya vi el codigo y la simulacion en Proteus y anduvo joya, disculpa que no conteste antes estuve ocupado con cosas del colegio y demas y no tenia tiempo para verlo, ya que como dije antes este era un proyecto propio...
Nuevamente Muchas Gracias por la ayuda y... como cierro el tema para darlo por finalizado?


----------



## D@rkbytes (Oct 2, 2011)

Saludos.
Que bien que ya pudiste controlar el LCD.
Ok Hasta pronto.


----------



## JoseSiles (Abr 16, 2013)

Hola compañeros del foro quisiera saber quien podría ayudarme con el siguiente problema
Tengo que programar un pic 16f628 en l"enguaje assembler" para poder mostrar un mensaje fijo en un lcd 16 x 2, pero me encuentro con el problema de que solo me funciona en la simulación con el Proteus y en la vida real no funciona.
Si alguien pudiera ayudarme le estaría muy agradecido. Les dejo el programa que eh realizado por si alguien quiere verlo.
Desde ya muchísimas gracias y saludos a todos.


----------



## ricbevi (Abr 16, 2013)

JoseSiles dijo:


> Hola compañeros del foro quisiera saber quien podría ayudarme con el siguiente problema
> Tengo que programar un pic 16f628 en l"enguaje assembler" para poder mostrar un mensaje fijo en un lcd 16 x 2, pero me encuentro con el problema de que solo me funciona en la simulación con el Proteus y en la vida real no funciona.
> Si alguien pudiera ayudarme le estaría muy agradecido. Les dejo el programa que eh realizado por si alguien quiere verlo.
> Desde ya muchísimas gracias y saludos a todos.



Hola...No programo en Asembler pero ¿colocaste los fusibles de programación del pic al programarlo? Tu archivo "hex" carece de dicha informacion ya que la omitiste en el "asm
"
Para usar el oscilador interno, los pines como entrada-salida, omitiendo el MCLR  pero si usando el BODEN y el PWRT tienes que usar "_Config 3F50h" o bien "__CONFIG _INTOSC_OSC_NOCLKOUT & _PWRTE_ON & _WDT_OFF & _CP_OFF & _MCLRE_OFF & _BOREN_ON & _LVP_OFF & _DATA_CP_OFF".

Saludos.

Ric.


----------

