12-08-2014, 12:43 AM
Bueno comentar que a quien no lo sepa estoy leyendo el libro "Microcontrolador PIC 16F84 Desarroyo de proyectos", algo anticuado pero sinceramente muy bien explicado, el caso es que estoy en tema 13 que es el del LCD y en este tema hay algo que no me gusta y es que te da a entender que uses su libreria y no te compliques la vida, la verdad es que estamos en agosto y si en algun momento tengo tiempo de complicarme es ahora :dale2: , asi que ni corto ni perezoso Datasheet en mano y libro para observar como lo hacia me he hecho mi programita para manejar el LCD si bien se parece mucho, no es igual ya que conforme he ido entendiendo lo que tenia que ir haciendo lo he hecho y lo que he visto que no me era necesario pues no lo he hecho, pero me ha surgido una duda, este mi codigo.
Bueno el caso es que en la lbreria que se usa en el libro hace una cosa tal que asi en este apartado, os he marcadolo que si esta en esta libreria,por lo que yo entiendo si no me equivoco es que guarda la configuracion de los puertos donde esta conectado el LCD, pero bajo mi punto de vista no deberia ya que no van a ser modificados, entiendo que quiere decir que es por si esos puertos se estuvieran usando para otra cosa distinta del LCD, si durante el codigo se modificaran lo entenderia pero tal cual, la verdad es que no.
Bueno la pregunta de todo esto seria, ¿tal vez sea que se pueden usar los puertos donde esta el LCD para otros fines mientras estan sin uso?
Código:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;Configuración para el grabador
LIST P=16F84A ;Procesador
INCLUDE <P16F84A.INC> ;Definicion de los operandos utilizados
CBLOCK 0x0C
LCD_Dato
LCD_GuardaDato
Retardo
Contador_ms
Contador_Bucle
ENDC
#DEFINE Pin_RS PORTA,0 ;Poner a 1 para modo de datos, a 0 para modo comando
#DEFINE Pin_RW PORTA,1 ;1 LCD habilitado, 0 no hablitado
#DEFINE Pin_E PORTA,2 ;este es el Pin enable
#DEFINE LCD_BUS PORTB
;Usaremos solo el nibble alto para enviar los datos al LCD, no por ahorrar pines sino por la dificultad que conlleva
org 0
Inicio bsf STATUS,RP0
movlw b'00001111'
movwf PORTB ;Configuramos salidas y entradas puerto B
movlw b'00011000'
movwf PORTA ;Configuramos salidas y entradas puerto A
bcf STATUS,RP0
Principal call Inicializa_LCD
movlw 'H'
call Envio_Dato
movlw 'o'
call Envio_Dato
movlw 'l'
call Envio_Dato
movlw 'a'
call Envio_Dato
sleep
;=======================================================================================================================
; La informacion para inicializar el LCD esta en el datasheet del mismo
;=======================================================================================================================
Inicializa_LCD bcf Pin_E
bcf Pin_RS
bcf Pin_RW
movlw d'16'
call Retardo_XXms ;Retardo de 16ms el Datasheet indica un retardo >15ms al inicio
movlw b'00110000'
call Escribe_LCD ;Enviamos el primer comando
movlw d'5'
call Retardo_XXms ;Retardo de 5ms
movlw b'00110000'
call Escribe_LCD ;Enviamos el segundo comando
call Retardo_2ms ;Retardo de 2ms indica que debe ser mayor de 100us pero en este
movlw b'00110000' ;momento no he creado una rutina de micro segundos
call Escribe_LCD ;Enviamos el tercer comando
call Retardo_2ms
movlw b'00100000' ;momento no he creado una rutina de micro segundos
call Escribe_LCD ;Enviamos el cuarto comando que es el que indica que trabajaremos con 4 bits
call Retardo_2ms
call LCD_2Lineas
call Borrar_LCD
call Cursor_OFF
call Cursor_INC
return
;=======================================================================================================================
; Subrutinas de comando del LCD
;=======================================================================================================================
LCD_2Lineas movlw b'00101000'
call Envio_Comando
return
Borrar_LCD movlw b'00000001'
call Envio_Comando
return
Cursor_OFF movlw b'00001100'
call Envio_Comando
return
Cursor_ON movlw b'00001110'
call Envio_Comando
return
Cursor_INC movlw b'00000110'
call Envio_Comando
return
;=======================================================================================================================
; Envio_comando y Envia_caracter
;basicamente en estas subrutinas se hace el swap de nibble para enviar los 8 bits al LCD y se cambia el valor de Pin_RS
;dependiendo de si se va enviar un comando se pone a 0 y si se va a enviar undato se pone a 1
;=======================================================================================================================
Envio_Comando bcf Pin_RS
goto Envia
Envio_Dato bsf Pin_RS
Envia movwf LCD_GuardaDato
call Escribe_LCD
swapf LCD_GuardaDato,W
call Escribe_LCD
call Retardo_2ms ;para comando deberian ser 2ms y para caracter unos 40us
return
;=======================================================================================================================
; Escribe LCD
;=======================================================================================================================
Escribe_LCD
andlw b'11110000' ;solo nos quedamos con el nible alto del mensaje que enviamos que es el que usaremos
movwf LCD_Dato ;Lo guardamos para enviar
movf LCD_BUS,W ;Almacenamos lo que actualmete tiene el PORTB entero solo nos interesa el nibble bajo
andlw b'00001111'
iorwf LCD_Dato,F ;Ahora unimos el nible alto de lo que queremos mandar con el nible bajo de lo que habia en el PORTB
movf LCD_Dato,W ;Colocamos lo que queremos enviar en W
movwf LCD_BUS ;Y lo enviamos al BUS del LCD recordemos que el nibble bajo se ha mantenido solo a cambiado el nible alto
bsf Pin_E ;activamos el lcd
bcf Pin_E ;desactivamos el lcd
return
;=======================================================================================================================
; Esta subrutina esta pensada para crear un retardo de XXX milisegundos exactos que se le pasaran por W
; se han tenido en cuenta tanto el ciclo de asignacion de milisegundos de W como el de la llamada Retardo_XXms
; el maximo aceptado es 255 ms si se realizan 4 asignaciones de W y 4 llamadas a Retardo_XXms se puede comprobar
; que obtenemos 1 segundo exacto, todo ello para cristal de 4Mhz.
; Diseñada por mi XD 08/08/14
;=======================================================================================================================
Retardo_XXms movwf Contador_ms ;1 ciclo
Bucle_XXms decfsz Contador_ms ;(ms)*1 ciclo + 2 al saltar
goto Retardo_1ms ;(ms)*2 ciclos
call Ajuste_ciclos ;2 ciclos al saltar
return ;2 ciclos al saltar
Retardo_1ms ;2 ciclos viene del salto de llamada call o goto Retardo_1ms
nop ;1 ciclo
nop ;1 ciclo
movlw d'248' ;1 ciclo establecemos el valor de K
movwf Retardo ;1 ciclo
Bucle_1ms nop ;(K)*1 cilo
decfsz Retardo ;(K)*1 ciclo + 2 al saltar
goto Bucle_1ms ;(K)*2 ciclos
goto Bucle_XXms ;2 ciclos al saltar
Ajuste_ciclos
Retardo_Ajuste ;2 ciclos viene del salto de llamada call
nop ;1 ciclo
nop ;1 ciclo
nop ;1 ciclo
movlw d'246' ;1 ciclo establecemos el valor de K
movwf Retardo ;1 ciclo
Bucle_Ajuste nop ;(K)*1 cilo
decfsz Retardo ;(K)*1 ciclo + 2 al saltar
goto Bucle_Ajuste ;(K)*2 ciclos
return ;2 ciclos al saltar
;==================================================================================================
;==================================================================================================
Retardo_2ms movlw d'2'
call Retardo_XXms
return
END
Bueno el caso es que en la lbreria que se usa en el libro hace una cosa tal que asi en este apartado, os he marcadolo que si esta en esta libreria,por lo que yo entiendo si no me equivoco es que guarda la configuracion de los puertos donde esta conectado el LCD, pero bajo mi punto de vista no deberia ya que no van a ser modificados, entiendo que quiere decir que es por si esos puertos se estuvieran usando para otra cosa distinta del LCD, si durante el codigo se modificaran lo entenderia pero tal cual, la verdad es que no.
Bueno la pregunta de todo esto seria, ¿tal vez sea que se pueden usar los puertos donde esta el LCD para otros fines mientras estan sin uso?
Código:
;=======================================================================================================================
; Escribe LCD
;=======================================================================================================================
Escribe_LCD
andlw b'11110000' ;solo nos quedamos con el nible alto del mensaje que enviamos que es el que usaremos
movwf LCD_Dato ;Lo guardamos para enviar
movf LCD_BUS,W ;Almacenamos lo que actualmete tiene el PORTB entero solo nos interesa el nibble bajo
andlw b'00001111'
iorwf LCD_Dato,F ;Ahora unimos el nible alto de lo que queremos mandar con el nible bajo de lo que habia en el PORTB
;========================================================================de aqui hacia abajo
bsf STATUS,RP0
movf PORTB,W
movwf LCD_GuardaB
movlw b'00001111'
andwf PORTB,F
bcf STATUS,RP0
;========================================================================hasta aqui
movf LCD_Dato,W ;Colocamos lo que queremos enviar en W
movwf LCD_BUS ;Y lo enviamos al BUS del LCD recordemos que el nibble bajo se ha mantenido solo a cambiado el nible alto
bsf Pin_E ;activamos el lcd
bcf Pin_E ;desactivamos el lcd
;======================================================================== de aqui hacia abajo
bsf STATUS,RP0
movf LCD_GuardaB,W
movwf PORTB
bcf STATUS,RP0
;======================================================================== hasta aqui
return