Hola a todos, estoy iniciandome con los LCDs. En concreto estoy intentando controlar uno de 2x16 lineas con un pic 16f876. Tengo una serie de librerias que me paso un amigo y que le funcionan bien y yo al hacer un simple programa y intentarlo simular con proteus solamente se enciende la pantalla del LCD y no muestra nada. Bueno aqui os dejo el codigo para ver si me podeis echar una mano los mas entendidos y encontrais el fallo. Ah el lcd esta conectado tal como se muestra en el esquema al pic
RC1>| ---------------------> |RS
RC2>| ---------------------> |R/w
Rc3>| ---------------------> |E
RB<7:0>| <====================> |D<7:0>
;--------------------------------------
;programa para sacar un texto por el lcd
;--------------------------------------
list p=pic16f876
include "p16f876.inc"
org 0x00
goto inicio
org 0x06
inicio
call LCD_PUERTOS
Clear
call LCD_COMANDO ;se borra toda la memoria del LCD
call LCD_INI ;inicialización del LCD
Inc_cursor
call LCD_COMANDO ;modo de incrementar cursor cada vez que se escribe un carácter
Display_On
call LCD_COMANDO ;display on
movlw "H"
call LCD_DATO
acabar
goto acabar ;Buclee infinito
;-----------------------------------------------------------
;rutinas utilizadas
;-----------------------------------------------------------
;BLOQUE DE ETIQUETAS
#define Activa bsf PORTC,3 ;Activa E
#define Desactiva bcf PORTC,3 ;Desactiva
#define Lectura bsf PORTC,2 ;Pone LCD en Modo RD
#define Escritura bcf PORTC,2 ;Pone LCD en Modo WR
#define Modo_Comando bcf PORTC,1 ;Desactiva RS (modo comando)
#define Modo_Dato bsf PORTC,1 ;Activa RS (modo datos)
#define Clear movlw 0x01 ;borra display
#define Inc_Cursor movlw 0x06 ;modo incrementar cursor sin desplazar caracteres
#define Display_ON movlw 0x0c ;enciende el display
;-----------------------------------------------------------------------
;rutina para configurar el lcd con 8bits y 2 lineas
;-----------------------------------------------------------------------
LCD_INI
call LCD_DELAY
call LCD_DELAY
call LCD_DELAY
Modo_Comando ;RS=0, modo comando
Escritura ;R/W#=0
movlw 0x38
call LCD_COMANDO ;interfaz de 8 bits y dos líneas de 5x7 cada carácter
call LCD_DELAY
movlw 0x38
call LCD_COMANDO ;interfaz de 8 bits y dos líneas de 5x7 cada carácter
call LCD_DELAY
movlw 0x38
call LCD_COMANDO ;interfaz de 8 bits y dos líneas de 5x7 cada carácter
call LCD_DELAY
return
;----------------------------------------------------------------------------------------
;RUTINA LCD_BUSY: Chequea el estado del flag BUSY y espera hasta
;que valga 0
;----------------------------------------------------------------------------------------
LCD_BUSY
Lectura ;Pone el LCD en modo lectura
bsf STATUS,RP0
movlw 0xff
movwf TRISB ;PORTB entrada
bcf STATUS,RP0 ;Selecciona el banco 0
Activa ;Habilita la lectura del flag busy
nop
busy
btfsc PORTB,7 ;Chequea bit de Busy
goto busy
Desactiva ;Desactiva LCD
bsf STATUS,RP0
clrf TRISB ;PORTC<7> salida
bcf STATUS,RP0
Escritura ;Pone LCD en modo WR
return
;-----------------------------------------------------------
;cambia E de alto a bajo y espera un tiempo suficiente
;------------------------------------------------------------
LCD_PULSO
Activa ;Activa E E=1
nop
nop
nop
Desactiva ;Desactiva E=0
return
;-----------------------------------------------------------------------------------------
;RUTINA LCD_DATO: Es una rutina que pasa el contenido cargado en el
;registro W,
;-------------------------------------------------------------------------------------
LCD_DATO
movwf PORTB ;Valor ASCII a sacar por PORTC
Modo_Comando ;RS=0
call LCD_BUSY ;Espera a que se libere el LCD
Modo_Dato ;RS=1
call LCD_PULSO ;Genera pulso de E para pasar dato
return
;-------------------------------------------------------------------------------------------------
;RUTINA LCD_COMANDO: El contenido de W ahora es el código de un comando
;para el LCD, que es necesario pasar también a la PUERTA B para su ejecución.
;------------------------------------------------------------------------------------------------
LCD_COMANDO
movwf PORTB ;Código de comando
Modo_Comando ;Desactiva RS (modo comando)
call LCD_BUSY ;Espera a que se libere el LCD
call LCD_PULSO ;Genera pulso de E para pasar comando
return
;---------------------------------------------------------------------------------------------
;RUTINA DELAY: retardo de 5ms
;----------------------------------------------------------------------------------------------
LCD_DELAY
movlw d"7"
movwf 0x20
bucle1
movlw d"238"
movwf 0x21
bucle2
decfsz 0x21,1
goto bucle2
decfsz 0x20,1
goto bucle1
return
;----------------------------------------------------
;subrutina para configurar los puertos para controlar LCD
;en mi caso uso para el bus de datos el puertob y para el control los
;tres primeros bits del puertoC
;-------------------------------------------------------
LCD_PUERTOS
bsf STATUS,RP0 ;con esto ponermos a 1 5º status y accedemos con ello al banco 1 (rp1:0 rp2

movlw 0x00 ;ponemos a 0 w para configurar la puerta B como salida ( (todos sus pines)
movwf TRISB ; Se configuran como entradas las l¡neas de la Puerta B
movwf TRISC ;configuro todos los del C como salida pq en pricipio no necesito el resto y si los necesito sera para salida
bcf STATUS,RP0 ;ponermos el 5 bit de status a 0 para acceder al banco 0 (rp1:0,rp0:0) dejamos todo para acceder a puertos
return
end
Bueno el programa simplemente tiene que mostrar una "H" en la pantalla. Muchas gracias a todos por echarme una mano se que todo esto es bastante coñazo de mirar. Yo lo he repasao todo bastante rato y no encuentro el fallo asi que estoy un poco desesperao, tambien he llegado a pensar que puede ser problema del proteus incluso, aunque lo veo un poco improbable. 1 saludo a todos