# ¿problema de visualizacion  LCD con pic 16f877a?



## May Andres (Abr 6, 2009)

Hola sabios de la Electronica, soy novato en esto de los pic y tengo problemas con la visualizacion por medio de un pic *16f877a*, estoy utilizando un programa en assembler de la pagina  http://www.x-robotics.com/   el cual esta diseñado para la visualizacion con un pic 16f84. Hice *modificaciones* por que tengo el pic16f877A y para empezar deberia tener en cuenta que los RPG empiezan desde la direccion 0x20 mientras que en el 16f84 empiezan los RPG desde 0x0c.

Este es el programa:	



```
list p=16f877A      ;Procesador PIC16f877A ------------->cambio de procesador 
           list c=132        ;Listado a 132 caracteres  -------------->¿no se para que sirve?

TIMER0     equ 01            ;Registro del TIMER0
OPCION     equ 0x1           ;Registro de opciones,pgina 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 0x20          ;Registro del dato A  --------->RPG despues de la direccion 0x20 en el 16f877a y 0x0c en el     
DATO_B     equ 0x21           ;Registro del dato B 
RESUL      equ 0x22           ;Registro de resultados
TEMPO1     equ 0x23           ;Registro temporal 1
TEMPO2     equ 0x24          ;Registro temporal 2
OFFSET     equ 0x25          ;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
```


 para poder ensamblar en Mplab el anterior programa previamente escribi la rutina llamada LCD.lib que por cierto la guarde con extensión *.Lib*  , despues la adicione a la carpeta *library files* y despues ensamble el ejemplo HOLA MUNDO y funciono de maravilla.

¿que hice mal?¿que hago para que  funcione  o que modifico? porque a la hora de probarlo no funciona la LCD solo quedan cuadros oscuros ,muevo el potenciometro pero no aparece nada significativo solo cambia su contraste

si me preguntas sobre ¿la parte electronica? estoy utilizando el puerto A y puerto B,condensadores de 15pf que segun el Datasheet son *recomendados* con un cristal de 4Mhz, simulo en un protoboard aunque no creo que sea el protoboard el del problema , aunque desconfio de su interferencias y filtraciones de ruido.

si me preguntas sobre ¿ la programacion? estoy utilizando el pickit2 para quemar el pic, no lo estoy grabando en LVP(Programacion en bajo voltaje), los fuse los configuro en el software de pickit2 como el tipo de oscilador  *XT* y desactivo el perro guardian.

si me preguntas sobre ¿el pic? tengo entendido que un pic cuando esta dañado se mide continuidad entre VSS y VDD estan en corto y no es este el caso, si no es asi enseñenme por favor...


*Agradeceria* *mucho la ayuda de un sabio* que me pueda colaborar a detectar mi error porque llevo mas de 3 dias intentandolo, o me pudiera dar un programa en assembler para poder visualizar en mi LCD   *con el pic 16f877a* un Hola Mundo el cual estare inmensamente agradecido

Muchas Gracias estare pendiente...


----------



## juanjo1786 (Abr 7, 2009)

Que tal.
En sí, ¿cual es tu problema?.
¿Sólo necesitas un programa?
Has de saber que muchas veces las direcciones de los registros entre microcontrolador y microcontrolador no son iguales, muchas veces, cambian (Por ejemplo el TRISA y TRISB son las direcciones 0x85 y 0x86, respectivamente, que veo que tienes otra cosa). De la misma manera como se configura el preescalador del timer, puesto que tampoco son siempre iguales (Un dato). Te recomiento utilizar capacitores un poquito mas grandes (Entre 22pF y 33pF, del mismo valor ambos).
No precisamente es un corto nada mas  (También cuando te consume al rededor de 300mA cuando no hayy nada mas que un pic conectado, o cuando se calienta sin razón aparente, es un indicio de que se encuentre quemado).

Por otra parte, los LCD de 16x2 (Que sunpongo que es el que estás usando), en algunas ocasiones se utiliza con un potenciómetro de 10K.
Si necesitas un programita sencillo para probarlo y no sabes mucho de programación aún, puedo adjuntarte un archivo sencillo en ensamblador o C (que a lo mejor se te hace mas sencillo) y después depuras tu código , con su simulación en proteus, a lo mejor así puedas probar si está fallando tu PIC o tu LCD.


----------



## tiopepe123 (Abr 7, 2009)

Yo me he encontrado LCD muy "lentas", te recomiendo poner unos buenos bucles de retardo, despues ya los quitaras. simplemente haces una lista de nop(20 nops)  terminado con un ret y lo llamas con un call.


----------



## Cesar_8k (Ago 4, 2009)

Aunque esta respuesta sea quizá demasiado tarde, leo que usas el puerto A y B. tal vez no te diste cuenta que el pin A4 es 'open-drain' [algo asi como colector abierto]. Yo tambien estuve peleando con un problema similar, pero en Basic [PicBasicPro] (y creo que es muchisimo más fácil si eres novato en PICs)...

Te adjunto la captura de la simulación en Proteus...
Si necesitas el hex o el programa...


----------



## teco (Oct 16, 2009)

cesar_8k

Hola podrias ayudarme con el programa fuente y el hex tambien estoy iniciandome en el tema de los LCD y necesito una guía


----------



## cerebroo (Oct 16, 2009)

Hola, si estas trabajando con el MPLAB, en su caprte donde se instalo, hay librerias, y hay una que te declara todos los registros. es P16f877.INC
En cuentrala y la incluyes en tu trabajo.
Tengo programa pero en el 16f84A. En el 16f877, solo hice conversioin A/D

Saludos.
Cerebro.


----------



## adan martinez (Dic 9, 2009)

que tal amigos soy mas que un novato todavia en el tema de los pics estube utilizando en programa de carlos diaz (http://electronica.webcindario.com/circuitos/cerradura.htm)en de la cerradura electronica  para una parte de un proyecto lo que pasa es que no inicia como si fuese que no funcina en pic estoy utilizando el 16f877a y el utilizo el 16f866a quien me puede verificar el programa si es que funciona...


----------



## mechazz (Oct 4, 2010)

hola a todos mi problema es el mismo yo programe en niple version 5.5 y lo simule en proteus y en proteus funciona magnifico pero en el fisico solo se ven lcuadros negros y no los caracteres que deberian verse 
no tengo asesor ni una base de como se debe programar , no se si sea mi lcd y eso de los retardos donde deben de ser colocados despues de inicializar , despues de de enviar una cadena de caracteres fijos y mas o menos de cuanto tiempo son , de ante mano gracias acudi a un buen lugar de programadores


----------



## teco (Oct 8, 2010)

Hola Mechazz:
Mira la verdad cuando tuve problemas con el Pic16f877 y el LCD me las tuve que rebuscar solito...pero espero mi exp. te sirva debes fijarte en el contraste del LCD que se ajusta con un potenciometro si te sale todos los cuadros en negro puede ser solo que está al max. contraste, ahora te doy un dato si el proyecto que requieres no es algo básico el programa en assembler se vuelve un tanto tedioso te recomiendo investigues el software MiKroC donde hay bastante material para aprender en la red. te permite programar en C y viene con compilador incluido generando el archivo.hex luego el archiconocido
IC-Prog y listo. El programador lo adquirí en OLIMEX (programador de PIC y memorias) 
SUERTE !!! desde CHILE estamos a la espera de que saquen pronto a los MINEROS


----------



## jairosaw (Oct 8, 2010)

ola MAY ANDRES, este ejemplo de manejo de un lcd 2x16 con un microcontrolador PIC16F877A  te puede servir.

El control del LCD se encuentra EN A0 y A1 del pic, por lo cual se declara ese puerto como I/O digitales en el ADCON1

Los datos a 8 Bits se encuentran en el Puerto B.

saludos espero te halla ayudado


----------



## animesound (Jun 13, 2011)

oigan pero si el puerto ADCON1 lo kiero usar con un potenciometro para simular un sensor en proteus cole hago?...


----------



## jorgetingo (Jul 2, 2012)

mi problema es algo parecido y diferente .. lo simulo y funciona perfecto pero en placa no corre me da caracteres alterados ... cuañquier cosa menos lo que quiero


----------



## jairosaw (Jul 3, 2012)

Jorge,, prueba el archivo adjunto q tengo mas arriba,,, o si no enseñanos tu programa,,,


----------



## jorgetingo (Jul 4, 2012)

Ahí cuelgo mi libreria de lcd ... no funciona aún .. no sé si será algo  de la configuración del lcd ..por que estoy coloque 10, 100,50 us  ,,  para el enable y le doy 5 ms para los retardos de caracteres y datos y  nada



por fa*vor* ayudenme y si tienen una libreria o explicación de como funciona  un teclado  4x4   adjunten infor*mación*..please necesito entregar esto para el  próximo  martes
... ya no se que hacer

```
;************************************************************************************************
;                      programa - carro controlado por rf
;                       jorge matamoros tingo
;                                version 2.0
;                                          19/10/2010
;************************************************************************************************
;                                            
;************************************************************************************************
processor 16f887 

#include  "p16f887.inc"        

;-------------------------------------------------------------------------------------------


__config _config1, _lvp_off & _fcmen_off & _ieso_off & _bor_off & _cpd_off & _cp_off & _mclre_on & _pwrte_on & _wdt_off & _intrc_osc_clkout
__config _config2, _wrt_off & _bor21v


;************************************************************************************************
;                                bits de configuracion                
;************************************************************************************************

;************************************************************************************************

;************************************************************************************************
;                                   variaveis                    
;************************************************************************************************

cblock        0x20
            
        cuenta
        limite
    ;    tecl_teclaorden    
    

        num
    ;    tecla    
    endc

;************************************************************************************************
;                              constantes del programa        
;************************************************************************************************

;teclado_comprobacion    equ    b'11110000'
;tecl_ultimatecla    equ    d'15'

;************************************************************************************************
;                              shorcuts                
;************************************************************************************************
#define bank0        bcf status,rp0    ;acceso banko 0
#define bank1        bsf status,rp0    ;acceso banko 1
#define int_on        bsf    intcon,7
#define int_off        bsf    intcon,7
;***************************************************************************************************
#define rs        porta,0
#define en        porta,2
#define display    portd

;************************************************************************************************
    org        0x00                    
     goto    inicio
                    
    org     0x05



    include  <retardos.inc>

include  <tecladoso.inc>
;************************************************************************************************
;                    inicio        
;************************************************************************************************
inicio
    call     confi_port        ;configuro puertos        
    call    confi_adc

    call     lcd_init
call retardo_5s
    clrf    cuenta
;**********************************
    movlw     0x01
    call lcd_comando
    call retardo_5ms
    movlw    0x80
    call    lcd_comando
    bsf        rs
;************************************************
    movlw    ' '    
    call lcd_dato    
    movlw    ' '    
    call lcd_dato    
    movlw    'p'
    call lcd_dato
    movlw    'x'
    call lcd_dato
    movlw    'o'
    call lcd_dato
    movlw    'y'    
    call lcd_dato
    movlw    'e'
    call lcd_dato
    movlw    'c'
    call lcd_dato
    movlw    't'
    call lcd_dato
    movlw    'o'
    call lcd_dato
    movlw    ' '
    call lcd_dato
    movlw    'd'
    call lcd_dato
    movlw    'e'
    call lcd_dato
    
    movlw    0xc3
    call    lcd_comando
    bsf        rs
    

    movlw    'e'
    call lcd_dato
    movlw    'l'
    call lcd_dato
    movlw    'e'
    call lcd_dato
    movlw    'c'
    call lcd_dato
    movlw    't'
    call lcd_dato
    movlw    'r'
    call lcd_dato    
    movlw    'o'
    call lcd_dato
    movlw    'n'
    call lcd_dato
    movlw    'i'
    call lcd_dato
    movlw    'c'
    call lcd_dato
    movlw    'a'
    call lcd_dato
    call     retardo_1s    
    movlw    0x01
    call    lcd_comando    
    call     retardo_1s

movlw    0x80
    call    lcd_comando
    bsf        rs
;************************************************
    movlw    'i'    
    call lcd_dato    
    movlw    'n'    
    call lcd_dato    
    movlw    'g'
    call lcd_dato
    movlw    'r'
    call lcd_dato
    movlw    'e'
    call lcd_dato
    movlw    's'    
    call lcd_dato
    movlw    'a'
    call lcd_dato
    movlw    ' '
    call lcd_dato
    movlw    'Ñ'
    call lcd_dato
    movlw    'a'
    call lcd_dato
    movlw    't'
    call lcd_dato
    movlw    'o'
    call lcd_dato

;*****************************************

movlw    0xc0
    call    lcd_comando
    call     retardo_5ms
    bsf    rs

principal



ciclo
call    leer_teclado
        movlw    0
        xorwf    flag_tecla,0
        btfsc    status,z
        goto    ciclo
        movf    tecla,0
        call tabla_lcd
        call    lcd_dato
        call    retardo_100ms



fin
    goto    principal

    

;*****************************************

lcd_comando
bcf rs    ; en cero mando comando 
movwf    display
bsf    en    
call    retardo_100micros
bcf    en
call retardo_1ms
return

;****************************************
lcd_dato
bsf rs    ; en uno mando datos
movwf    display
bsf    en    
call    retardo_100micros
bcf    en
call retardo_1ms
return


;*****************************************
lcd_init
movlw    0x38
call lcd_comando
call    retardo_5ms
movlw    0x38
call lcd_comando
call    retardo_5ms
movlw    0x38
call lcd_comando
call    retardo_5ms
movlw    b'00111000'
call lcd_comando
movlw    b'00000001'
call lcd_comando
call    retardo_5ms
movlw    b'00001100'
call lcd_comando
movlw    b'00000110'
call lcd_comando
call retardo_50ms
return


;************************************************************************************************
;                rutna de configuracion puertos t oscilador interno
;************************************************************************************************                        
 confi_port
    bank1
    movlw    b'01100000'            ; defino oscilador interno de 4.0  mhz
    movwf    osccon
;    movlw    b'10000111'            ;tmro operando como temporizador;pull_ups desabilitados <7>;prescaler aplicado ao tmr0 de 1:32<2:0>
;    movwf    option_reg            ;tmr0 opera como temporizador <5>    ;prescaler direccionado para o tmr0<3>                                
    movlw     b'00100000'            ;interrupcoes desabilitadas
    movwf    intcon        
    bsf     status,rp0
    bsf     status,rp1    
    movlw    b'00000000'            ;     0  ---> se define como digital
    movwf    ansel                ;     1  ---> se define como analogica porta todo digital
    movlw    b'00000000'
    movwf    anselh                ;   ansel h igual pero para el portb
    bsf     status,rp0
    bcf     status,rp1
    movlw    b'00000000'
    movwf    trisa                    ; salida
    movlw    0x00
    movwf    trisc
    movlw    b'1111'
    movwf    trisb
    movlw    0x00
    movwf    trisd
    bcf    option_reg,not_rbpu    
    bcf     status,rp0
    bcf     status,rp1
    clrf    porta
    clrf     portb
    clrf     portc
    clrf     portd




;***************************************
movlw        0x20
movwf        fsr
limpia_ram
clrf        indf
incf        fsr,f
movf        fsr,w
xorlw        0x80
btfss        status,z
    return                                                                

;************************************************************************************************
;                rutna de configuracion convertidor analogico
;************************************************************************************************                        
 confi_adc
    bank1
        movlw    b'00000000'
        movwf    adcon1
    bank0
        movlw    b'10000100'
        movwf    adcon0    
        return    

        
;********************************

tabla_lcd
addwf        pcl,1
    
retlw        '1'
retlw        '2'
retlw        '3'
retlw        'f'        ; primera fila del teclado.
Retlw        '4'
retlw        '5'
retlw        '6'
retlw        'e'        ; segunda fila del teclado
retlw        '7'
retlw        '8'
retlw        '9'
retlw        'd'        ; tercera fila del teclado.
Retlw        'a'
retlw        '0'
retlw        'b'
retlw        'c'    
retlw        '0'    






;*********************************************************************

;************************************************************************************************
end                                    ;fin de programa
;************************************************************************************************

#define rs        porta,0
#define en        porta,2
#define display    portd

;*****************************************

lcd_comando
bcf rs    ; en cero mando comando 
movwf    display
bsf    en    
call    retardo_20micros
bcf    en
call retardo_1ms
return

;****************************************
lcd_dato
bsf rs    ; en uno mando datos
movwf    display
bsf    en    
call    retardo_20micros
bcf    en
call retardo_1ms
return
;******************************************            
lcd_port
bank1
clrf    trisd
clrf    trisa
bank0
clrf    porta
clrf    portb
return
;*****************************************
lcd_init
movlw    0x30
call lcd_comando
call    retardo_5ms
movlw    0x30
call lcd_comando
call    retardo_5ms
movlw    0x30
call lcd_comando
call    retardo_50micros
movlw    b'00111000'
call lcd_comando
movlw    b'00000001'
call lcd_comando
call    retardo_5ms
movlw    b'00001100'
call lcd_comando
movlw    b'00000110'
call lcd_comando
return
;**********************************************
```


----------



## jairosaw (Jul 4, 2012)

Por lo que logro ver en tu programa , y mas precisamente en la rutina que tiene de configuración del convertidor análogo, los pines no están configurados como I/O DIGITALES, para configurar como digitales se debe cargar un:
Movlw 06h
Movwf adcon1
Otra opcion que tienes es utilizar el puerto D o C, debido a que como estas utilizando el Porta debes especificar que sea digital, ya que en este puerto se encuentra precisamente los canales analogos.


----------



## D@rkbytes (Jul 4, 2012)

jairosaw dijo:


> Por lo que logro ver en tu programa , y mas precisamente en la rutina que tiene de configuración del convertidor análogo, los pines no están configurados como I/O DIGITALES, para configurar como digitales se debe cargar un:
> Movlw 06h
> Movwf adcon1


Saludos jairosaw
El compañero jorgetingo esta usando un PIC16F887
en este caso sería:
BANKSEL ANSEL 
CLRF ANSEL ; Digital I/O Para el Puerto A y CLRF ANSELH para el Puerto B

Pero si miras bien el código del compañero, esto si esta declarado.


jorgetingo dijo:


> por fa*vor* ayudenme y si tienen una libreria o explicación de como funciona  un teclado  4x4   adjunten infor*mación*.


En el foro existen muchos temas acerca de teclados matriciales.

Suerte.


----------



## jairosaw (Jul 5, 2012)

Correcto,,, no me habia percatado que era 887,,,


----------

