Problemas con PIC16F887 y LCD 16x2 (Ensamblador)

Hola a todos, mi problema es mando a imprimir algo en el lcd pero no aparece hasta que toco el pin de RB7 con algo metálico o mi dedo, supongo que porque hace tierra o algo parecido.
Este es el código.

Código:
PROCESSOR 16F887
        INCLUDE P16F887.INC
        
    CONT1    EQU    020
    CONT2    EQU 021
    RETARDO        EQU 022
    ;COMANDO EQU 023
    ;DATO    EQU 024

        ORG 0
        GOTO PRINCIPAL
        ORG 004
;============RUTINA DE INTERUPCION========================


;=========================================================
PRINCIPAL
;//////////////////////PROGRAMA PRINCIPAL/////////////////////    
;==========INICIALIZACION DE PUERTOS============
        BSF STATUS,RP0
        BSF STATUS,RP1
        CLRF ANSELH
        BCF STATUS,RP1
        MOVLW 0FF
        MOVWF TRISB                
        MOVLW 0E3
        MOVWF TRISD        
        BCF STATUS,RP0
        CLRF PORTD
        
;===============================================
        MOVLW .250        
        CALL INIRET
        MOVLW .250
        CALL INIRET

                
   
        CALL READ
        MOVLW 033
        CALL OPCOM

        CALL READ
        MOVLW 033
        CALL OPCOM

        CALL READ
        MOVLW 038
        CALL OPCOM

        CALL READ    
        MOVLW 00C
        CALL OPCOM

        CALL READ
        MOVLW 006
        CALL OPCOM

        CALL READ
        MOVLW 001
        CALL OPCOM
FIN
        CALL READ
        MOVLW 081
        CALL OPCOM

        
        CALL READ
        MOVLW 'E'
        CALL OPDAT

        CALL READ
        MOVLW 'F'
        CALL OPDAT

        CALL READ
        MOVLW 'G'
        CALL OPDAT

        CALL READ
        MOVLW 'H'
        CALL OPDAT
        
    
        
        
        
        GOTO FIN

;==========SUBRUTINA DE LECTURA===============================
READ
        BCF PORTD,2;RS=0
        BSF PORTD,3;W=1
BUCLE1    BSF PORTD,4;E=1    
        MOVF PORTB,W
        BCF PORTD,4;E=0    
        BTFSC PORTB,7
        GOTO BUCLE1
        RETURN

;=============SUBRRUTINA: OPERACION DE ESCRITURA DE COMANDO============
OPCOM
        BSF STATUS,RP0
        CLRF TRISB
        BCF STATUS,RP0
        BCF PORTD,3;WR=0
        BCF PORTD,2;RS=0
        BSF PORTD,4;E=1
        CLRF PORTB
        
        MOVWF PORTB
        BCF PORTD,4;E=0
        BSF PORTD,2;RS=1
        BSF STATUS,RP0
        MOVLW 0FF
        MOVWF TRISB
        BCF STATUS,RP0
        RETURN
;=============SUBRRUTINA: OPERACION DE ESCRITURA DE DATO=============
OPDAT        
        BSF STATUS,RP0
        CLRF TRISB
        BCF STATUS,RP0
        BCF PORTD,3;WR=0
        BSF PORTD,2;RS=1
        BSF PORTD,4;E=1
        CLRF PORTB

        MOVWF PORTB
        BCF PORTD,4;E=0
        BCF PORTD,2;RS=0
        BSF STATUS,RP0
        MOVLW 0FF
        MOVWF TRISB
        BCF STATUS,RP0
        RETURN



;===========SUBRRUTINA: RETARDO===================
INIRET
    
        MOVWF CONT1
        MOVWF CONT2

RET        
        DECFSZ CONT1,1
        GOTO RET
        DECFSZ CONT2,1
        GOTO RET
        RETURN

        END
Lo que yo supongo es que el display no manda el cero que debería mandar cuando se desocupa para que así el pic comience a mandarle los comandos y cuando lo toco con algo metálico el RB7 se va a tierra y todo empieza a funcionar el micro manda los comandos y el lcd manda el RB7 a cero cuando se desocupa. De verdad les agradecería mucho algo de orientación ya que llevo días atorado en esto relativamente simple. De antemano gracias.
 
Última edición:
Modificando algunas partes de tu programa, me parece que con estos cambios debe funcionar.
Código:
        PROCESSOR 16F887
        INCLUDE P16F887.INC

    __CONFIG    _CONFIG1, _INTRC_OSC_NOCLKOUT & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF
    __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
    errorlevel    -302
        
CONT1    EQU 0x20
CONT2    EQU 0x21
;RETARDO        EQU 022
    ;COMANDO EQU 023
    ;DATO    EQU 024

        ORG 0
;        GOTO PRINCIPAL
;        ORG 004
;============RUTINA DE INTERUPCION========================


;=========================================================
PRINCIPAL
;//////////////////////PROGRAMA PRINCIPAL/////////////////////    
;==========INICIALIZACION DE PUERTOS============
        BSF STATUS,RP0
        BSF STATUS,RP1
        CLRF ANSELH
        BCF STATUS,RP1
;        MOVLW 0FF                ; Los puertos por default son entradas
;        MOVWF TRISB
        movlw    b'1110100'        ; Oscilador interno estable @ 8MHz.
        movwf    OSCCON                
        MOVLW 0E3
        MOVWF TRISD        
        BCF STATUS,RP0
        CLRF PORTD
        
;===============================================
        
;        CALL INIRET
;        MOVLW .250
;        CALL RETARDO

;        CALL READ
        MOVLW 033
        CALL OPCOM

;        CALL READ
        MOVLW 033
        CALL OPCOM

;        CALL READ
        MOVLW 038
        CALL OPCOM

;        CALL READ    
        MOVLW 00C
        CALL OPCOM

;        CALL READ
        MOVLW 006
        CALL OPCOM

;        CALL READ
        MOVLW 001
        CALL OPCOM

;        CALL READ
        MOVLW 0x83;081        ; Inicia escritura en línea 1 (0x83 Para centrar palabra)
        CALL OPCOM

        
;        CALL READ
        MOVLW 'H'
        CALL OPDAT
;        CALL READ
        MOVLW 'O'
        CALL OPDAT
;        CALL READ
        MOVLW 'L'
        CALL OPDAT
;        CALL READ
        MOVLW 'A'
        CALL OPDAT

        MOVLW ' '
        CALL OPDAT
        MOVLW 'M'
        CALL OPDAT
        MOVLW 'U'
        CALL OPDAT
        MOVLW 'N'
        CALL OPDAT
        MOVLW 'D'
        CALL OPDAT
        MOVLW 'O'
        CALL OPDAT

        MOVLW 0xC3            ; Cambia a línea 2 (0xC3 Para alinear palabra)
        CALL OPCOM

        MOVLW 'H'
        CALL OPDAT
        MOVLW 'E'
        CALL OPDAT
        MOVLW 'L'
        CALL OPDAT
        MOVLW 'L'
        CALL OPDAT
        MOVLW 'O'
        CALL OPDAT
        MOVLW ' '
        CALL OPDAT
        MOVLW 'W'
        CALL OPDAT
        MOVLW 'O'
        CALL OPDAT
        MOVLW 'R'
        CALL OPDAT
        MOVLW 'L'
        CALL OPDAT
        MOVLW 'D'
        CALL OPDAT      
FIN                
        GOTO FIN    ; Bucle infinito
        

;==========SUBRUTINA DE LECTURA===============================
READ
        BCF PORTD,2;RS=0
        BSF PORTD,3;W=1
BUCLE1    BSF PORTD,4;E=1    
        MOVF PORTB,W
        BCF PORTD,4;E=0    
        BTFSC PORTB,7
        GOTO BUCLE1
        RETURN

;=============SUBRRUTINA: OPERACION DE ESCRITURA DE COMANDO============
OPCOM
        BSF STATUS,RP0
        CLRF TRISB
        BCF STATUS,RP0
        BCF PORTD,3;WR=0
        BCF PORTD,2;RS=0
        BSF PORTD,4;E=1
        CLRF PORTB
        
        MOVWF PORTB
        BCF PORTD,4;E=0
        BSF PORTD,2;RS=1
        BSF STATUS,RP0
        MOVLW 0FF
        MOVWF TRISB
        BCF STATUS,RP0
        call    RETARDO
        call    RETARDO
        RETURN
;=============SUBRRUTINA: OPERACION DE ESCRITURA DE DATO=============
OPDAT        
        BSF STATUS,RP0
        CLRF TRISB
        BCF STATUS,RP0
        BCF PORTD,3;WR=0
        BSF PORTD,2;RS=1
        BSF PORTD,4;E=1
        CLRF PORTB

        MOVWF PORTB
        BCF PORTD,4;E=0
        BCF PORTD,2;RS=0
        BSF STATUS,RP0
        MOVLW 0FF
        MOVWF TRISB
        BCF STATUS,RP0
        call RETARDO
        RETURN

;===========SUBRRUTINA: RETARDO===================
RETARDO
    movlw    0x1E
    movwf    CONT1
    movlw    0x04
    movwf    CONT2
RetBucle
    decfsz    CONT1,F
    goto    $+2
    decfsz    CONT2,F
    goto    RetBucle
    goto    $+1
    nop
    return

        END
En dado caso que no te funcione, modifica la rutina de retardo, pero me parece que así debe funcionar.
Notarás que configuré el programa con oscilador interno a 8MHz y con MCRL = OFF
El retardo que usé es de 0.002 segundos, y lo puedes modificar para mejor respuesta, según tu LCD.

Suerte.
 
Si claro que me funciono para entender en que estaba mal y ya no darme de topes buscando fallas en la tarjeta, en el micro, en el lcd. Según yo para leía la bandera para evitar los retardo y al final los termine usando. Solamente me queda una duda, se supone que el lcd me tenia que mandar un cero para decirme que estaba desocupado y así empezar a mandarle los comandos...por qno lo hizo?, solamente hasta que yo lo aterrizaba empezaba a funcionar.

Y lo del te AMO fue porque me deje llevar por la emoción de ver el "HOLA MUNDO" y el "HELLO WORLD" XD
 
Última edición por un moderador:
lo del te AMO fue porque me deje llevar por la emoción de ver el "HOLA MUNDO" y el "HELLO WORLD" XD
:LOL: Entiendo, así pasa cuando las cosas funcionan.
Si claro que me funciono para entender en que estaba mal y ya no darme de topes buscando fallas en la tarjeta, en el micro, en el lcd. Según yo para leía la bandera para evitar los retardo y al final los termine usando.
Que bien, es que siempre queda uno con la duda de saber si las modificaciones funcionaron.
Y es porque yo no tengo ese PIC para haber hecho una prueba físicamente.
Solamente me queda una duda, se supone que el lcd me tenia que mandar un cero para decirme que estaba desocupado y así empezar a mandarle los comandos...por qno lo hizo?, solamente hasta que yo lo aterrizaba empezaba a funcionar.
En teoría así debería de ser, sin embargo parece que los controladores de los LCD han cambiado.
Por ejemplo, mira este programa...
Código:
; Lectura del Flag Busy
LCD_BUSY       
    bsf     PORTA,1         ; (Pin RW) Pone el LCD en modo de lectura
    bsf     STATUS,RP0      ; Selecciona el banco 1
    movlw   0xFF
    movwf   TRISB           ; Puerto B como entradas
    bcf     STATUS,RP0      ; Selecciona el banco 0
    call    Delay_5Ms       ; Retardo para que se desactive el Flag Busy
L_BUSY          
    btfsc   PORTB,7         ; Checa el Bit de Busy (D7)
    goto    L_BUSY
    bcf     PORTA,2         ; Desactiva LCD
    bsf     STATUS,RP0      ; Selecciona banco 1
    clrf    TRISB           ; Puerto B como salidas
    bcf     STATUS,RP0      ; Selecciona el banco 0
    bcf     PORTA,1         ; (Pin RW) Pone el LCD en modo de escritura 
    return
Como puedes ver, se espera que el pin D7 se ponga a 0 para poner en 0 el pin E (Enable) del LCD.
Con los nuevos LCD, se puede quedar en el bucle esperando el 0, y pensarás que no funciona.

Ésta rutina de comprobación del Flag Busy, ya es obsoleta con los nuevos LCD.
Y debe llegar a funcionar si se comenta el uso de esta sección...
Código:
L_BUSY          
    btfsc   PORTB,7         ; Checa el Bit de Busy (D7)
    goto    L_BUSY
Ésta rutina funcionaba con retardos de 5Ms, y ahora he usado retardos de 2Ms sin problemas.
Por eso es que te comentaba que si no funcionaba el programa, modificaras el retardo de 2Ms.

Saludos.
 
Última edición:
amigo disculpa e visto tu codigo pero no comprendo las conecciones a realizar podrias ayudarme en eso
Saludos.
Cuando realice la modificación del amigo EdrSd no hice ningún esquema, ni simulación,
ya que las conexiones las deduje mirando el código del programa.

Pero ya que requieres el esquema de conexiones, lo acabo de hacer y aquí lo adjunto.

Aprovechando, y para que no se pierda el trabajo, adjunto también el proyecto con el programa corregido.

Suerte.
 

Adjuntos

  • 16F887 LCD 16x2 8 Bits SCH.jpg
    16F887 LCD 16x2 8 Bits SCH.jpg
    69.5 KB · Visitas: 55
  • 16F887 LCD 16x2.zip
    17.6 KB · Visitas: 99
Última edición:
Saludos.
Cuando realice la modificación del amigo EdrSd no hice ningún esquema, ni simulación,
ya que las conexiones las deduje mirando el código del programa.

Pero ya que requieres el esquema de conexiones, lo acabo de hacer y aquí lo adjunto.

Aprovechando, y para que no se pierda el trabajo, adjunto también el proyecto con el programa corregido.

Suerte.


Muchas gracias amigo, viéndolo bien no está dificil la conexión,
es solo que no he trabajado el display. Nuevamente gracias =)
 
Última edición por un moderador:
Aquí adjunto mi reporte y el código en ensamblador del proyecto por si a alguien le sirve. Saludos.
 

Adjuntos

  • Proyecto Alarma.rar
    801.4 KB · Visitas: 61
Atrás
Arriba