TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: martos_iii en 06 de Diciembre de 2004, 12:08:00
-
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
-
hola,
bueno, mire un poco y puede haber alguna punta por alli....
1. cuando llamas a LCD_PUERTOS dices por alli q pones portB como entrada y en realidad lo pones como salida, no me fije si esto es importante, pero hechale una ojeada....
2. luego de esto mandas un comando (clear) al LCD q aun esta sin inicializar, con lo cual seguro esa parte no te dara bolilla....
3. luego recien manda inicializar el LCD, no revise esa rutina mucho, pero se ve buena...
Con lo cual te diria q pruebes inicializando primero el LCD y luego recien los comandos..... suele suceder q la inicializacion del LCD se tara sy no le envias la secuencia correcta y en este caso no lo estas haciendo....
Avisa como sigue y suerte.
-
muchas gracias por tus comentarios wqtrp, pero he hecho lo que me has dicho y el lcd cuando lo simulo com proteus sigue haciendo lo mismo, solo se enciende la pantalla y no aparace nada mas. Lo que me has comentado que el puertoB digo que es una entrada aunque lo configuro como salida realmente (me equivoque al escribirlo), el puertoB lo utilizo como bus de datos para el LCD.
No se si alguno de ustedes utiliza el proteus para simular diseños con pic, estoy empezando a pensar que quizas el problema este ahi, aunque creo que lo tengo todo bien puesto también. Bueno si ven algún fallo más no duden en decirmelo. Muchas gracias por todo