PROYECTOS DE PIC 16F84A
domingo, 5 de junio de 2011
reloj digital
LIST P=16F84A
INCLUDE "P16F84A.INC"
__CONFIG _XT_OSC &_CP_OFF &_PWRTE_ON &_WDT_OFF
#DEFINE BANCO0 BCF STATUS,RP0
#DEFINE BANCO1 BSF STATUS,RP0
#DEFINE LCD_CTRL PORTA
#DEFINE LCD_DATA PORTB
DELAY_VAR EQU 0x0C
UNISEG EQU 0x0F
DECSEG EQU 0x10
UNIMIN EQU 0x11
DECMIN EQU 0x12
UNIHOR EQU 0x13
DECHOR EQU 0x14
TEMP EQU 0x15
CAMBIOHORA EQU 0X16
LCD_VAR EQU 0X17
ORG 0X000
INICIO BANCO1
bsf TRISA,3
bsf TRISA,4
BANCO0
clrf PORTA
clrf PORTB
clrf UNISEG
clrf DECSEG
clrf UNIMIN
clrf DECMIN
clrf UNIHOR
clrf DECHOR
CALL LCD_UP
CALL LCD_INI
;CALL LCD_CLEAR ; borrar el punto coma si deseas grabarlo al pic y PROYECT/BUILT ALL
movlw 0x05
call LCD_SETDDADDRESS
MOVLW 'H'
CALL LCD_WRITEDATO
MOVLW 'o'
CALL LCD_WRITEDATO
MOVLW 'r'
CALL LCD_WRITEDATO
MOVLW 'a'
CALL LCD_WRITEDATO
MOVLW ':'
CALL LCD_WRITEDATO
LAZO
call MUESTRA
incf UNISEG,F
movlw .10
xorwf UNISEG,W
btfss STATUS,Z
goto LAZO
clrf UNISEG
incf DECSEG,F
movlw .6
xorwf DECSEG,W
btfss STATUS,Z
goto LAZO
clrf DECSEG
incf UNIMIN,F
movlw .10
xorwf UNIMIN,W
btfss STATUS,Z
goto LAZO
clrf UNIMIN
incf DECMIN,F
movlw .6
xorwf DECMIN,W
btfss STATUS,Z
goto LAZO
clrf DECMIN
movlw .2
xorwf DECHOR,W
btfsc STATUS,Z
goto dos
goto nueve
dos
incf UNIHOR,F
movlw .4
xorwf UNIHOR,W
btfss STATUS,Z
goto LAZO
clrf UNIHOR
goto sigue
nueve
incf UNIHOR,F
movlw .10
xorwf UNIHOR,W
btfss STATUS,Z
goto LAZO
clrf UNIHOR
goto sigue
sigue
incf DECHOR,F
movlw .3
xorwf DECHOR,W
btfss STATUS,Z
goto LAZO
clrf DECHOR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
goto LAZO
MUESTRA
MOVLW .250
MOVWF TEMP
MUESTRA2
movlw .4
call DELAY_MS
btfss PORTA,3
GOTO INCHORA
btfss PORTA,4
GOTO INCMINUTO
decfsz TEMP,F
goto MUESTRA2
MUESTRA3
movlw 0x45
call LCD_SETDDADDRESS
movf DECHOR,W
call LCD_TABNUM
CALL LCD_WRITEDATO
movf UNIHOR,W
call LCD_TABNUM
CALL LCD_WRITEDATO
movlw ':'
CALL LCD_WRITEDATO
movf DECMIN,W
call LCD_TABNUM
CALL LCD_WRITEDATO
movf UNIMIN,W
call LCD_TABNUM
CALL LCD_WRITEDATO
movlw ':'
CALL LCD_WRITEDATO
movf DECSEG,W
call LCD_TABNUM
CALL LCD_WRITEDATO
movf UNISEG,W
call LCD_TABNUM
CALL LCD_WRITEDATO
return
INCHORA
btfss PORTA,3
GOTO $-.1
movlw .2
xorwf DECHOR,W
btfsc STATUS,Z
goto dos2
goto nueve2
dos2
incf UNIHOR,F
movlw .4
xorwf UNIHOR,W
btfss STATUS,Z
GOTO MUESTRA3
clrf UNIHOR
goto sigue2
nueve2
incf UNIHOR,F
movlw .10
xorwf UNIHOR,W
btfss STATUS,Z
GOTO MUESTRA3
clrf UNIHOR
goto sigue2
sigue2
incf DECHOR,F
movlw .3
xorwf DECHOR,W
btfss STATUS,Z
GOTO MUESTRA3
clrf DECHOR
GOTO MUESTRA3
INCMINUTO
btfss PORTA,4
GOTO $-.1
incf UNIMIN,F
movlw .10
xorwf UNIMIN,W
btfss STATUS,Z
GOTO MUESTRA3
clrf UNIMIN
incf DECMIN,F
movlw .6
xorwf DECMIN,W
btfss STATUS,Z
GOTO MUESTRA3
clrf DECMIN
GOTO MUESTRA3
;************************************************************************************************
; LCD HITACHI HD44780A 2 X 16 o 1 X 16 8 bits de datos
;************************************************************************************************
;****************************************************************************************
; LCD8.INC
;
; Autor: Ing. Alfredo Moisés Quispe Espinoza
;
;
;Presenta un conjuntos de rutinas que permiten realizar las tareas de control del mòdulo
;de visualización LCD. Con la llamada a LCD_UP se configura para su uso y con la rutina LCD_INI
;se inicializa el LCD. Y la rutina MENSAJE visualiza un mensaje dado en una tabla.
;Las demás rutinas son las de principal uso de control. NOTA: Definir con "Define" los puertos
;LCD_DATA y LCD_CTRL, y en caso de tener cuatro bancos poner RP1 a 0 antes de LCD_UP si es necesario.
;
;Este fichero se debe incluir en los futuros programas fuente mediante la directiva INCLUDE.
;
;LCD_UP: Configura los puertos A y B, y el INTCON para el uso del LCD.
;
;LCD_INI: Inicializa el LCD. Espera 15ms (riso a 4.5V), configura # de bits de datos y # de
; lineas activas.
;
;LCD_MENSAJE: Esta rutina saca al LCD el mensaje cuyo inicio esta indicado en el acumulador. Se
; aconseja para cada mensaje el siguiente formato:
; MENS equ $ ó MENS equ $
; retlw 'O' dt "OK",0x00
; retlw 'K'
; retlw 0x00
; Y debe hacer "movlw MENS" antes de la llamada "call MENSAJE"
;
;LCD_CLEAR: Borra el display y retorna el cursor a la posicion 0.
;
;LCD_HOME: Retorna el cursor a la posicion 0.
;
;LCD_ENTRYMODE: Configura el modo de ingreso al display.
; El modo de funcionamiento deseado deberá cargarse en los 2 bits menores de W:
; x x x x x x b1 b0
; b0 : 0 = no desplazamiento del display 1 = desplazamiento
; b1 : 0 = autodecremento del cursor 1 = autoincremento
; b2-7 : sin importancia
;
;LCD_DISPCURSCONT: Enciende o apaga el display, cursor y parpadeo.
; El modo de control deseado deberá cargarse en los 3 bits menores de W:
; x x x x x b2 b1 b0
; b0 : 0 = no parpadeo del cursor 1 = parpadeo
; b1 : 0 = apagar cursor 1 = encender cursor
; b2 : 0 = apagar display 1 = encender display (los datos siguen en DDRAM)
; b3-7 : sin importancia
;
;LCD_DISPCURSSHIFT: Mueve el cursor o el display.
; El modo de control deseado deberá cargarse en los 2 bits terceros de W:
; x x x x b3 b2 x x
; b2 : 0 = mueve al a izquierda 1 = a la derecha
; b3 : 0 = mueve cursor 1 = mueve display
; b0,1,4-7 : sin importancia
;
;LCD_SETCGADDRESS: Fija la dirección de la CGRAM. La dirección de la CGRAM puede ser
; leída/escrita después de este comando
; La dirección deseada deberá estar en el registro W:
; x x b5 b4 b3 b2 b1 b0
; b0-5 : dirección de la CGRAM
; b6-7 : sin importancia
;
;LCD_SETDDADDRESS: Fija la dirección de la DDRAM. La dirección de la DDRAM puede ser
; leída/escrita después de este comando
; La dirección deseada deberá estar en el registro W:
; x b6 b5 b4 b3 b2 b1 b0
; b0-6 : dirección de la DDRAM
; b7 : sin importancia
;
;LCD_READAC: Obtiene en W el valor de AC.
;
;LCD_WRITEDATO: Escritura de datos de W en la DDRAM o CGRAM
; W = DATO
; LCD_DATA <== W
;
;LCD_READDATO: Lectura de datos de la DDRAM o CGRAM y lo pasa a W
; LCD_DATA = DATO
; W <== LCD_DATA
;
;LCD_TABNUM: Convierte el número HEXADECIMAL que este en W a su equivalente ASCII.
; OjO: No olvidar chequear el PCLATH por tratarse de asignación al PC por istrucción.
;
#define ENABLE bsf LCD_CTRL,2 ;Activa E
#define DISABLE bcf LCD_CTRL,2 ;Desactiva
#define LEER bsf LCD_CTRL,1 ;Pone LCD en Modo RD
#define ESCRIBIR bcf LCD_CTRL,1 ;Pone LCD en Modo WR
#define DATO bsf LCD_CTRL,0 ;Desactiva RS (modo comando)
#define COMANDO bcf LCD_CTRL,0 ;Activa RS (modo dato)
cblock LCD_VAR
LCD_TEMP1 ;Registro temporal de posicion de la tabla
LCD_TEMP2 ;Registro temporal del caracter ASCII
endc
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SUBRUTINAS DEL LCD
;************************************************************************************************
LCD_UP BANCO1
clrf LCD_DATA ;RB <0-7> salidas digitales
movlw B'11111000'
andwf LCD_CTRL,F ;RA0=RS RA1=R/W RA2=E salidas digitales
BANCO0
bcf INTCON,GIE ;Desactivar interrupciones
COMANDO ;RS=0
ESCRIBIR ;R/W=0
DISABLE ;E=0
return
;
;-------------------------------------------------------------------------
LCD_INI movlw 0x0F
call DELAY_MS ;Espera un poco más de 15ms
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x7
call LCD_COMAND
movlw 0x05
call DELAY_MS ;5ms > 4.1ms.(Especificacion de Fabricante)
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x8
call LCD_COMAND
movlw .110
call DELAY_US ;110us > 100us.(Especificacion de Fabricante)
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x8
call LCD_COMAND
movlw B'00001000' ;b3 y b2 puedn ser cambiados para otra configuración
call LCD_FUNCIONSET ;después de este punto no podran ser cambiados N ni F
movlw B'00000100' ;Cursor apagado y Display prendido
goto LCD_DISPCURSCONT
;
;-------------------------------------------------------------------------
LCD_MENSAJE movwf LCD_TEMP1 ;Salva posicion de la tabla
M_E_N_S movf LCD_TEMP1,0 ;Recupera posicion de la tabla
call LCD_TABLA ;Busca caracter de salida
movwf LCD_TEMP2 ;Guarda el caracter
movf LCD_TEMP2,1
btfsc STATUS,Z ;¿Hay más caracteres?
return ;No, fue el último
call LCD_WRITEDATO ;Visualiza en el LCD el caracter
incf LCD_TEMP1,1 ;Siguiente caracter
goto M_E_N_S ;Repite con siguiente caracter
LCD_TABLA movwf PCL ;Desplazamiento sobre la tabla
;
;-------------------------------------------------------------------------
LCD_CLEAR movlw B'00000001' ;Borra LCD y cursor a Home
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_HOME movlw B'00000010' ;Cursor a Home
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_ENTRYMODE andlw 0x03 ;Nos quedamos con b1-b0
iorlw 0x04 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSCONT andlw 0x07 ;Nos quedamos con b2-b1-b0
iorlw 0x08 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSSHIFT andlw 0x0C ;Nos quedamos con b3-b2
iorlw 0x10 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETCGADDRESS andlw 0x3F ;Nos quedamos con b5-b4-b3-b2-b1-b0
iorlw 0x40 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETDDADDRESS iorlw 0x80 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_READAC call LCD_BUSY
LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
movf LCD_DATA,0
andlw 0x7F ;Valor de la dirección de la DDRAM o CGRAM
DISABLE
BANCO1
clrf LCD_DATA
BANCO0
ESCRIBIR
return
;
;-------------------------------------------------------------------------
LCD_WRITEDATO movwf LCD_DATA ;Valor a escribir en la DDRAM o CGRAM
call LCD_BUSY
DATO
goto LCD_E ;Genera pulso de E
;
;-------------------------------------------------------------------------
LCD_READDATO call LCD_BUSY
DATO
LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
movf LCD_DATA,0 ;Valor leido de la DDRAM o CGRAM
DISABLE
BANCO1
clrf LCD_DATA
BANCO0
ESCRIBIR
COMANDO
return
;
;-------------------------------------------------------------------------
LCD_TABNUM addwf PCL,1
dt "0123456789ABCDEF"
;
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SUBRUTINAS INTERNAS DEL LCD
;************************************************************************************************
;LCD_BUSY: Lectura del Flag Busy y la direccion.
LCD_BUSY LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
btfsc LCD_DATA,7 ;Chequea bit de Busy
goto $-1
DISABLE
BANCO1
clrf LCD_DATA ;Puerto B como salida
BANCO0
ESCRIBIR
return
;
;-------------------------------------------------------------------------
;LCD_E: Pulso de Enable
LCD_E ENABLE
nop
DISABLE ;Desactiva E
COMANDO
return
;
;-------------------------------------------------------------------------
;LCD_COMAND: Escritura de comandos del LCD
; W = Codigo de comando para el LCD
; W ==> LCD_DATA
LCD_COMAND movwf LCD_DATA ;Codigo de comando.
call LCD_BUSY
goto LCD_E ;Genera pulso de E
;
;-------------------------------------------------------------------------
;LCD_FUNCIONSET: Configura ela fuente del caracter y número de lineas. No se cambia DL
; El modo de control deseado deberá cargarse en los 2 bits terceros de W:
; x x x x b3 b2 x x
; b2 : 0 = caracter de 5x7 1 = de 5x10
; b3 : 0 = display de 1 linea 1 = de 2 lineas
; b0,1,4-7 : sin importancia
LCD_FUNCIONSET andlw 0x0C ;Nos quedamos con b3-b2 (DL no se cambia)
iorlw 0x30 ;Incorporamos el bit de función y 8 bits
goto LCD_COMAND
;************************************************************************************************
; RETARDOS DE TIEMPO
;************************************************************************************************
;****************************************************************************************
; DELAY.INC
;
; Autor: Robert D. Robles Martínez
; (c) EDIMEL S.R.L. (Lima)
;
; Se tendrá las siguientes rutinas:
; - DELAY_US
; - DELAY_MS
; - DELAY_S
;Estas rutinas controlan los tiempos de retardo en microsegundos,
;milisegundos y en segundos. La cantidad microsegundos, de milisegundos
;o segundos toma del acumulador.
;NOTA: ESTOS TIEMPOS RESULTAN DEL USO DE UN RELOJ DE 4MHz (ciclo de
;instrucción de 1MHz).
;Guarda el registro OPTION en uno temporalal entrar para cargarlo al salir.
;DELAY_VAR EQU dir_inicio_del_bloque
; BLOQUE DE ETIQUETAS
CBLOCK DELAY_VAR ;Inicio de las variables. La primera dirección libre disponible
DELAY_TEMP_1
DELAY_TEMP_2
OPTION_TEMP
ENDC
;RUTINA DELAY_uS: Se trata de un rutina que implementa un retardo
;o temporización en uS. Utiliza la variable DELAY_TEMP_1 que se va
;decrementando hasta alcanzar el tiempo del acumulador dado en uS.
DELAY_US movwf DELAY_TEMP_1
bcf STATUS,C
rrf DELAY_TEMP_1,1
bcf STATUS,C
rrf DELAY_TEMP_1,1
DELAY_U1 nop
decfsz DELAY_TEMP_1,F
goto DELAY_U1
return
;RUTINA DELAY_uS: Esta rutina implementa un retardo o temporización
;en uS. Utiliza la variable DELAY_TEMP_1 que se va decrementando
;hasta alcanzar el tiempo del acumulador dado en mS.
DELAY_MS movwf DELAY_TEMP_1
BANCO1
movf OPTION_REG,W
movwf OPTION_TEMP
movlw B'11010001'
movwf OPTION_REG
BANCO0
DELAY_M1 clrwdt
clrf TMR0
bcf INTCON,T0IF
DELAY_M2 btfss INTCON,T0IF
goto DELAY_M2
decfsz DELAY_TEMP_1,F
goto DELAY_M1
BANCO1
movf OPTION_TEMP,W
movwf OPTION_REG
BANCO0
return
;RUTINA DELAY_S: Se trata de un rutina que implementa un retardo
;o temporización en S. Utiliza las variables DELAY_TEMP_1 y DELAY_TEMP_2
;que se van decrementando hasta alcanzar el tiempo del acumulador dado en S.
DELAY_S movwf DELAY_TEMP_1
BANCO1
movf OPTION_REG,W
movwf OPTION_TEMP
movlw B'11010011'
movwf OPTION_REG
BANCO0
DELAY_1 clrf DELAY_TEMP_2
DELAY_2 clrwdt
bcf INTCON,T0IF
clrf TMR0
DELAY_3 btfss INTCON,T0IF
goto DELAY_3
decfsz DELAY_TEMP_2,F
goto DELAY_2
decfsz DELAY_TEMP_1,F
goto DELAY_1
BANCO1
movf OPTION_TEMP,W
movwf OPTION_REG
BANCO0
return
END
;************************************************************************************************
; RETARDOS DE TIEMPO
;************************************************************************************************
;****************************************************************************************
; DELAY.INC
;
; Autor: Robert D. Robles Martínez
; (c) EDIMEL S.R.L. (Lima)
;
; Se tendrá las siguientes rutinas:
; - DELAY_US
; - DELAY_MS
; - DELAY_S
;Estas rutinas controlan los tiempos de retardo en microsegundos,
;milisegundos y en segundos. La cantidad microsegundos, de milisegundos
;o segundos toma del acumulador.
;NOTA: ESTOS TIEMPOS RESULTAN DEL USO DE UN RELOJ DE 4MHz (ciclo de
;instrucción de 1MHz).
;Guarda el registro OPTION en uno temporalal entrar para cargarlo al salir.
;DELAY_VAR EQU dir_inicio_del_bloque
; BLOQUE DE ETIQUETAS
CBLOCK DELAY_VAR ;Inicio de las variables. La primera dirección libre disponible
DELAY_TEMP_1
DELAY_TEMP_2
OPTION_TEMP
ENDC
;RUTINA DELAY_uS: Se trata de un rutina que implementa un retardo
;o temporización en uS. Utiliza la variable DELAY_TEMP_1 que se va
;decrementando hasta alcanzar el tiempo del acumulador dado en uS.
DELAY_US movwf DELAY_TEMP_1
bcf STATUS,C
rrf DELAY_TEMP_1,1
bcf STATUS,C
rrf DELAY_TEMP_1,1
DELAY_U1 nop
decfsz DELAY_TEMP_1,F
goto DELAY_U1
return
;RUTINA DELAY_uS: Esta rutina implementa un retardo o temporización
;en uS. Utiliza la variable DELAY_TEMP_1 que se va decrementando
;hasta alcanzar el tiempo del acumulador dado en mS.
DELAY_MS movwf DELAY_TEMP_1
BANCO1
movf OPTION_REG,W
movwf OPTION_TEMP
movlw B'11010001'
movwf OPTION_REG
BANCO0
DELAY_M1 clrwdt
clrf TMR0
bcf INTCON,T0IF
DELAY_M2 btfss INTCON,T0IF
goto DELAY_M2
decfsz DELAY_TEMP_1,F
goto DELAY_M1
BANCO1
movf OPTION_TEMP,W
movwf OPTION_REG
BANCO0
return
;RUTINA DELAY_S: Se trata de un rutina que implementa un retardo
;o temporización en S. Utiliza las variables DELAY_TEMP_1 y DELAY_TEMP_2
;que se van decrementando hasta alcanzar el tiempo del acumulador dado en S.
DELAY_S movwf DELAY_TEMP_1
BANCO1
movf OPTION_REG,W
movwf OPTION_TEMP
movlw B'11010011'
movwf OPTION_REG
BANCO0
DELAY_1 clrf DELAY_TEMP_2
DELAY_2 clrwdt
bcf INTCON,T0IF
clrf TMR0
DELAY_3 btfss INTCON,T0IF
goto DELAY_3
decfsz DELAY_TEMP_2,F
goto DELAY_2
decfsz DELAY_TEMP_1,F
goto DELAY_1
BANCO1
movf OPTION_TEMP,W
movwf OPTION_REG
BANCO0
return
;************************************************************************************************
; LCD HITACHI HD44780A 2 X 16 o 1 X 16 8 bits de datos
;************************************************************************************************
;****************************************************************************************
; LCD8.INC
;
; Autor: Ing. Alfredo Moisés Quispe Espinoza
;
;
;Presenta un conjuntos de rutinas que permiten realizar las tareas de control del mòdulo
;de visualización LCD. Con la llamada a LCD_UP se configura para su uso y con la rutina LCD_INI
;se inicializa el LCD. Y la rutina MENSAJE visualiza un mensaje dado en una tabla.
;Las demás rutinas son las de principal uso de control. NOTA: Definir con "Define" los puertos
;LCD_DATA y LCD_CTRL, y en caso de tener cuatro bancos poner RP1 a 0 antes de LCD_UP si es necesario.
;
;Este fichero se debe incluir en los futuros programas fuente mediante la directiva INCLUDE.
;
;LCD_UP: Configura los puertos A y B, y el INTCON para el uso del LCD.
;
;LCD_INI: Inicializa el LCD. Espera 15ms (riso a 4.5V), configura # de bits de datos y # de
; lineas activas.
;
;LCD_MENSAJE: Esta rutina saca al LCD el mensaje cuyo inicio esta indicado en el acumulador. Se
; aconseja para cada mensaje el siguiente formato:
; MENS equ $ ó MENS equ $
; retlw 'O' dt "OK",0x00
; retlw 'K'
; retlw 0x00
; Y debe hacer "movlw MENS" antes de la llamada "call MENSAJE"
;
;LCD_CLEAR: Borra el display y retorna el cursor a la posicion 0.
;
;LCD_HOME: Retorna el cursor a la posicion 0.
;
;LCD_ENTRYMODE: Configura el modo de ingreso al display.
; El modo de funcionamiento deseado deberá cargarse en los 2 bits menores de W:
; x x x x x x b1 b0
; b0 : 0 = no desplazamiento del display 1 = desplazamiento
; b1 : 0 = autodecremento del cursor 1 = autoincremento
; b2-7 : sin importancia
;
;LCD_DISPCURSCONT: Enciende o apaga el display, cursor y parpadeo.
; El modo de control deseado deberá cargarse en los 3 bits menores de W:
; x x x x x b2 b1 b0
; b0 : 0 = no parpadeo del cursor 1 = parpadeo
; b1 : 0 = apagar cursor 1 = encender cursor
; b2 : 0 = apagar display 1 = encender display (los datos siguen en DDRAM)
; b3-7 : sin importancia
;
;LCD_DISPCURSSHIFT: Mueve el cursor o el display.
; El modo de control deseado deberá cargarse en los 2 bits terceros de W:
; x x x x b3 b2 x x
; b2 : 0 = mueve al a izquierda 1 = a la derecha
; b3 : 0 = mueve cursor 1 = mueve display
; b0,1,4-7 : sin importancia
;
;LCD_SETCGADDRESS: Fija la dirección de la CGRAM. La dirección de la CGRAM puede ser
; leída/escrita después de este comando
; La dirección deseada deberá estar en el registro W:
; x x b5 b4 b3 b2 b1 b0
; b0-5 : dirección de la CGRAM
; b6-7 : sin importancia
;
;LCD_SETDDADDRESS: Fija la dirección de la DDRAM. La dirección de la DDRAM puede ser
; leída/escrita después de este comando
; La dirección deseada deberá estar en el registro W:
; x b6 b5 b4 b3 b2 b1 b0
; b0-6 : dirección de la DDRAM
; b7 : sin importancia
;
;LCD_READAC: Obtiene en W el valor de AC.
;
;LCD_WRITEDATO: Escritura de datos de W en la DDRAM o CGRAM
; W = DATO
; LCD_DATA <== W
;
;LCD_READDATO: Lectura de datos de la DDRAM o CGRAM y lo pasa a W
; LCD_DATA = DATO
; W <== LCD_DATA
;
;LCD_TABNUM: Convierte el número HEXADECIMAL que este en W a su equivalente ASCII.
; OjO: No olvidar chequear el PCLATH por tratarse de asignación al PC por istrucción.
;
#define ENABLE bsf LCD_CTRL,2 ;Activa E
#define DISABLE bcf LCD_CTRL,2 ;Desactiva
#define LEER bsf LCD_CTRL,1 ;Pone LCD en Modo RD
#define ESCRIBIR bcf LCD_CTRL,1 ;Pone LCD en Modo WR
#define DATO bsf LCD_CTRL,0 ;Desactiva RS (modo comando)
#define COMANDO bcf LCD_CTRL,0 ;Activa RS (modo dato)
cblock LCD_VAR
LCD_TEMP1 ;Registro temporal de posicion de la tabla
LCD_TEMP2 ;Registro temporal del caracter ASCII
endc
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SUBRUTINAS DEL LCD
;************************************************************************************************
LCD_UP BANCO1
clrf LCD_DATA ;RB <0-7> salidas digitales
movlw B'11111000'
andwf LCD_CTRL,F ;RA0=RS RA1=R/W RA2=E salidas digitales
BANCO0
bcf INTCON,GIE ;Desactivar interrupciones
COMANDO ;RS=0
ESCRIBIR ;R/W=0
DISABLE ;E=0
return
;
;-------------------------------------------------------------------------
LCD_INI movlw 0x0F
call DELAY_MS ;Espera un poco más de 15ms
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x7
call LCD_COMAND
movlw 0x05
call DELAY_MS ;5ms > 4.1ms.(Especificacion de Fabricante)
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x8
call LCD_COMAND
movlw .110
call DELAY_US ;110us > 100us.(Especificacion de Fabricante)
movlw B'00111000' ;Datos de 8 bits, 2 lineas y caracteres de 5x8
call LCD_COMAND
movlw B'00001000' ;b3 y b2 puedn ser cambiados para otra configuración
call LCD_FUNCIONSET ;después de este punto no podran ser cambiados N ni F
movlw B'00000100' ;Cursor apagado y Display prendido
goto LCD_DISPCURSCONT
;
;-------------------------------------------------------------------------
LCD_MENSAJE movwf LCD_TEMP1 ;Salva posicion de la tabla
M_E_N_S movf LCD_TEMP1,0 ;Recupera posicion de la tabla
call LCD_TABLA ;Busca caracter de salida
movwf LCD_TEMP2 ;Guarda el caracter
movf LCD_TEMP2,1
btfsc STATUS,Z ;¿Hay más caracteres?
return ;No, fue el último
call LCD_WRITEDATO ;Visualiza en el LCD el caracter
incf LCD_TEMP1,1 ;Siguiente caracter
goto M_E_N_S ;Repite con siguiente caracter
LCD_TABLA movwf PCL ;Desplazamiento sobre la tabla
;
;-------------------------------------------------------------------------
LCD_CLEAR movlw B'00000001' ;Borra LCD y cursor a Home
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_HOME movlw B'00000010' ;Cursor a Home
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_ENTRYMODE andlw 0x03 ;Nos quedamos con b1-b0
iorlw 0x04 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSCONT andlw 0x07 ;Nos quedamos con b2-b1-b0
iorlw 0x08 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSSHIFT andlw 0x0C ;Nos quedamos con b3-b2
iorlw 0x10 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETCGADDRESS andlw 0x3F ;Nos quedamos con b5-b4-b3-b2-b1-b0
iorlw 0x40 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETDDADDRESS iorlw 0x80 ;Incorporamos el bit de función
goto LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_READAC call LCD_BUSY
LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
movf LCD_DATA,0
andlw 0x7F ;Valor de la dirección de la DDRAM o CGRAM
DISABLE
BANCO1
clrf LCD_DATA
BANCO0
ESCRIBIR
return
;
;-------------------------------------------------------------------------
LCD_WRITEDATO movwf LCD_DATA ;Valor a escribir en la DDRAM o CGRAM
call LCD_BUSY
DATO
goto LCD_E ;Genera pulso de E
;
;-------------------------------------------------------------------------
LCD_READDATO call LCD_BUSY
DATO
LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
movf LCD_DATA,0 ;Valor leido de la DDRAM o CGRAM
DISABLE
BANCO1
clrf LCD_DATA
BANCO0
ESCRIBIR
COMANDO
return
;
;-------------------------------------------------------------------------
LCD_TABNUM addwf PCL,1
dt "0123456789ABCDEF"
;
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SUBRUTINAS INTERNAS DEL LCD
;************************************************************************************************
;LCD_BUSY: Lectura del Flag Busy y la direccion.
LCD_BUSY LEER
BANCO1
comf LCD_DATA,1 ;Puerto B como entrada
BANCO0
ENABLE
nop
btfsc LCD_DATA,7 ;Chequea bit de Busy
goto $-1
DISABLE
BANCO1
clrf LCD_DATA ;Puerto B como salida
BANCO0
ESCRIBIR
return
;
;-------------------------------------------------------------------------
;LCD_E: Pulso de Enable
LCD_E ENABLE
nop
DISABLE ;Desactiva E
COMANDO
return
;
;-------------------------------------------------------------------------
;LCD_COMAND: Escritura de comandos del LCD
; W = Codigo de comando para el LCD
; W ==> LCD_DATA
LCD_COMAND movwf LCD_DATA ;Codigo de comando.
call LCD_BUSY
goto LCD_E ;Genera pulso de E
;
;-------------------------------------------------------------------------
;LCD_FUNCIONSET: Configura ela fuente del caracter y número de lineas. No se cambia DL
; El modo de control deseado deberá cargarse en los 2 bits terceros de W:
; x x x x b3 b2 x x
; b2 : 0 = caracter de 5x7 1 = de 5x10
; b3 : 0 = display de 1 linea 1 = de 2 lineas
; b0,1,4-7 : sin importancia
LCD_FUNCIONSET andlw 0x0C ;Nos quedamos con b3-b2 (DL no se cambia)
iorlw 0x30 ;Incorporamos el bit de función y 8 bits
goto LCD_COMAND
Suscribirse a:
Entradas (Atom)