****************************************** HTTP://WWW.INGENIOPIC.COM *******
; PROGRAMA : USART_RX_TX.ASM
; FUNCION : VISUALIZAR DATOS RECIVIDOS DE LA USART POR EL PUERTO B Y TRANSMITIR EL VALOR DEL PUERTO A.POR LA USART INTERNA DEL PIC. .
; (HAY QUE DESCONECTAR CUALQUIER CABLE CONECTADO EN TX,PARA PODER RECIVIR POR RX)
; SERIAL PORT CONFIG: 9600 BAUDIOS,8 BITS,PARIDAD = NONE
;
; REVISION : 1.0 6/1/2009 PROGRAMA PARA : PIC16F876
; CPU CLOCK : 4 MHZ RELOJ INSTRUCCION : 4 MHZ = 0.25 US
; WDT : DESHABILITADO TIPO DE RELOJ : XT
; CODE PROT : OFF VELOCIDAD USART: 9.600 KBPS
;****************************************** HTTP://WWW.INGENIOPIC.COM *******
LIST P=16F877 ;SE INDICA EL MODO DE PROCESADOR
RADIX HEX ;SISTEMA DE NUMERACION HEXADECIMAL
INCLUDE <P16F877.INC> ;SE INCLUYE LA DEFINICION DE LOS REGISTROS
;REGISTROS INTERNOS
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC & _BODEN_OFF &_LVP_OFF &_CPD_OFF &_WRT_ENABLE_OFF
ERRORLEVEL -302 ;PARA QUE NO SE NOTIFIQUEN LOS ERRIRES POR LOS REGISTROS FUERA DEL BANCO DE RAM.
COUNTERA EQU 20H ;REGISTROS PARA RETARDO
COUNTERB EQU 21H
COUNTERC EQU 22H
W_TEMP EQU 23H
STATUS_TEMP EQU 24H
PCLATH_TEMP EQU 25H
#DEFINE GIE_ON BSF INTCON,GIE
#DEFINE GIE_OFF BCF INTCON,GIE
BANK0 MACRO ;MACRO PARA LA SELECCION DEL BANCO 0
BCF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK1 MACRO ;MACRO PARA LA SELECCION DEL BANCO 1
BSF STATUS,RP0
BCF STATUS,RP1
ENDM
PUSH MACRO ;MACRO PARA SALVAR REGISTROS ANTES DE UNA LLAMADA A INTERRUPCION
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
CLRF STATUS
MOVFW PCLATH
MOVWF PCLATH_TEMP
CLRF PCLATH
ENDM
POP MACRO ;MACRO PARA RESTAURAR REGISTROS DESPUES DE UNA LLAMADA A INTERRUPCION
MOVFW PCLATH_TEMP
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
ENDM
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0X00 ;INICIO EN EL VECTOR DE RESET
GOTO INICIO ;VA A LA PRIMERA INSTRUCCION DEL PROGRAMA
;<<<<<<------------------- VECTOR DE INTERRUPCION -------------------->>>>>>>
ORG 0X04 ;VECTOR DE INTERRUPCION
GOTO INTER ;SALTA A LA LINEA INTER
;<<<<<<----------------- CONFIGURACION DE LOS REGISTROS GENERALES ------------------->>>>>>>
INICIO
BANK0 ;CAMBIO AL BANCO 0
CLRF PORTA ;BORRA PUERTO A
MOVLW B'10010000' ;CONFIGURACION DE LA USART
MOVWF RCSTA ;PARA RECEPCION CONTINUA Y HABILITACION DE LA USART
BANK1
MOVLW 0X06
MOVWF ADCON1 ;CONFIGURA PORTA COMO ENTRADAS DIGITALES
MOVLW 0XFF
MOVWF TRISA ;PORTA COMO ENTRADA DE DATOS
CLRF TRISB ;PUERTO B COMO SALIDA DE DATOS
BSF TRISC,7 ;RC7/RX COMO ENTRADA
BCF TRISC,6 ;RC6/TX COMO SALIDA
MOVLW .25 ;VALOR PARA SELECCIONAR 9600 BAUDIOS
MOVWF SPBRG ;METE EL VALOR EN EL REGISTRO BAUD RATE GENERATOR
MOVLW B'00100100' ;CONFIGURACION USART MODO ALTA VELOCIDAD 9600 BAUD Y ACTIVACION DE TRANSMISION
MOVWF TXSTA ;CARGA VALOR ANTERIOR EN REGISTRO ASOCIADO AL GENERADOR DEL BAUD RATE
BSF PIE1,RCIE ;HABILITACION INTERRUPCION RX
BANK0
CLRF PORTB ;BORRA LAS SALIDAS DEL PUERTO B
MOVLW B'11000000' ;HABILITACION PARA LAS
MOVWF INTCON ;INTERRUPCIONES GENERALES Y PERIFERICAS.
;<<<<<<<<-----------------------------PROGRAMA PRINCIPAL--------------------------->>>>>>>>>>>>>>>>>>>>>>>>
NOP ;AQUI SE PONDRA EL PROGRAMA PRINCIPAL Y CUANDO QUERAMOS MANDAR UN DATO,
NOP ;SOLO TENDREMOS QUE HACER UN SALTO AL PROGRAMA DE ENVIO DE DATOS "ESCRIBEDATO"
PRINCIPAL GOTO INTER
;CALL ESCRIBEDATO
;<<<<<<<<-------------------------------ENVIO DE DATOS--------------------------->>>>>>>>>>>>>>
ESCRIBEDATO GIE_OFF ;DESHABILITA INTERRUPCIONES.PARA QUE CUANDO ESTE ENVIANDO UN DATO,NO HAYA ERRORES
BANK0 ;SELECCIONA BANCO 0
BCF PIR1,TXIF
MOVFW PORTA ;CARAGA EN W EL CONTENIDO DEL PUERTO A
MOVWF TXREG ;ESCRIBE LOS DATOS EN EL REGISTRO DE ENVIO DE DATOS
BANK1 ;SELECCIONA BANCO1
COMP_TX BTFSS TXSTA,TRMT ;COMPRUEBA SI EL SHIFT REGISTER(TSR)ESTA LLENO.Y SI ES ASI SALTA.
GOTO COMP_TX ;EN CASO CONTRARIO BUCLE INFINITO.
BANK0 ;SELECCIONA BANCO 0
BCF PIR1,TXIF
GIE_ON
;HABILITA INTERRUPCIONES
CALL RETARDO ;PAUSA PARA EL ENVIO DE DATOS
;RETURN ;RETORNA A PRINCIPAL
;<<<<<<<<-------------------COMPROVACION DE TIPO DE INTERRUPCION------------>>>>>>>>>>>>>>
INTER PUSH ;SALVA EL CONTENIDO DE W,STATUS Y PCLATH
BANK0
VOLVER BTFSS PIR1,RCIF ;COMPRUEBA SI EL SHIFT REGISTER(RSR)ESTA LLENO.Y SI ES ASI SALTA
GOTO VOLVER
BCF PIR1,RCIF ;REPONER EL FLAG DE INTERRUPCION
;BSF INTCON,PEIE
GOTO LEEDATO
POP ;RESTAURA EL CONTENIDO DE W,STATUS Y PCLATH
RETFIE ;RETORNO DE INTERRUPCION SI NO SE HA DADO LA CIRCUNSTANCIA ANTERIOR
;<<<<<<<<-------------------------VISUALIZACION DE DATO RECIVIDO------------>>>>>>>>>>>>>>
LEEDATO BANK0
MOVF RCREG,W ;LECTURA DATO RECIBIDO
MOVWF PORTB ;VISUALIZA DATO RECIBIDO EN EL PUERTO B
XORLW 0X31
BTFSC STATUS,Z
CALL ESCRIBEDATO
POP
RETFIE
GOTO LEEDATO ;RESTAURA EL CONTENIDO DE W,STATUS Y PCLATH
;RETORNA DE LA INTERRUPCION.
;<<<<<<----------------------- RUTINAS DE RETARDO ------------------------->>>>>>>
RETARDO ;SUB PROGRAMA PARA REALIZAR UNA PAUSA EN EL ENVIO DE DATOS
MOVLW D'1'
MOVWF COUNTERC
MOVLW D'20'
MOVWF COUNTERB
MOVLW D'50'
MOVWF COUNTERA
LOOP DECFSZ COUNTERA,1
GOTO LOOP
DECFSZ COUNTERB,1
GOTO LOOP
DECFSZ COUNTERC,1
GOTO LOOP
RETURN
END
valla! muchas gracias por tu aporte.he visto que utilizas algunas funciones que desconocia.como esta linea:
incf AddrTabla+1,F ;Si excede => incrementamos la parte alta. supongo que lo que realiza es el incremento de AddrTabla y luego suma 1 al resultado.
i2cEEAddr:2 ;en esta instruccion i2cEEAddr:2
hace lo mismo que en esta?: OffsTabla, AddrTabla:.2 o es que esta equivocada?
no lo sabia.lo hare en el proximo asm que posteo.
saludos.
Yo aquí por Bolivia no vi ningún pic de gama baja, ni para comprar ni nadie que se trajera uno.Hola Jojojorge5, creo que para aprender se puede aprender con casi cualquier micro 16Fxxx, y estoy totalmente de acuerdo contigo en que el 84a es una pésima inversión, el 628 es más barato y mejor.
Si los tuviera por aquí y fueran baratos, ya los estaría exprimiendo hasta el último bit de memoria.
Por el momento lomas barato que puedo conseguir es un 16f628 aunque ya pasa tiempo de la última ves que pregunte y tal ves ya ni lo tienen.
También no esta demás decir que el 16f84 me parece muy mala inversión, pero para aprender yo creo que esta bien porque existen muchos ejemplos para este pic.
DEMORA movlw .5 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .181 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1,1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0,1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
/quote]
yo casi siempre uso temporizaciones como esta:
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7
goto pausae
incf AUX1,f
btfss AUX1,4
goto pausae2
incf AUX2,f;
btfss AUX2,0 ;cambiar a 1;
goto pausae3 ;
retlw 0x00
uso mas la instruccion btfsc. no se cual sistema consume menos recursos.no me ha dado tiempo a comprobarlo. :D
perdon por no hacer bien la cita.pero nunca me aclaro con estas herramientas de los foros
;*****************************************www.ingeniopic.com***************************+******
; PROGRAMA : usart_16F84
; Funcion : recepcion de datos serie
;
;
; Revision : 1.0 12/12/2009 Programa para : PIC16F84
; CPU Clock : 4 MHz o 20Mhz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;*****************************************www.ingeniopic.com**********************************
;
;NOTAS: este programa esta preparado para interrumpir el funcionamiento del programa programa principal para atender
; una interrupcion por recepcion de datos provenientes de una usart.la velocidad de la usart podemos modificarla
; cambiando el valor del registro BAUDRATE.que esta un poco mas abajo de la etiqueta INICIO.cuanto mayor sea la velocidad.mayor sera el margen de error.
; el dato que recivamos por PB0 sera transmitido por PB1.
;
LIST P=16F84 ;Se indica el modo de procesador
RADIX HEX ;Sistema de numeracion hexadecimal
INCLUDE "P16F84.inc"
;registros internos
__CONFIG _XT_OSC & _CP_OFF & _WDT_OFF
ERRORLEVEL -302
CBLOCK 0x0C
CONTADOR
DATO
BAUDRATE
W_TEMP
STATUS_TEMP
PCLATH_TEMP
ENDC
PUSH MACRO ;macro para salvar registros antes de una llamada a interrupcion
movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP
clrf STATUS
movfw PCLATH
movwf PCLATH_TEMP
clrf PCLATH
ENDM
POP MACRO ;macro para restaurar registros despues de una llamada a interrupcion
movfw PCLATH_TEMP
movwf PCLATH
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
ENDM
#define BANK0 bcf STATUS,RP0
#define BANK1 bsf STATUS,RP0
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;Va a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTEUPCIONES ------------------------>>>>>>>
ORG 0x04 ;Inicio en el Vector de Reset
goto INTERRUPCIONES ;Va a la primera instruccion del programa
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO BANK1
movlw b'10000000' ;activar interrupcion por cambio de estado a 0 de RB0
movwf OPTION_REG
movlw b'10010000' ;configura interrupcion por desbordaminto de TMR0 y por cambio de estado a 0 de RB0
movwf INTCON
movlw b'00010001' ;habilita interrupcion por cambio de estado en RB0/INT
movwf TRISB
BANK0
bsf PORTB,1 ;establecer la salida usart a 1
movlw d'15' ;valor para la velocidad de la usart
movwf BAUDRATE
;valores para el baudrate:para 4Mhz
;
;para divisor TMR0=000
;190=2400bps, 90=4800bps, 40=9600bps, 15=19200bps,
;
;para divisor TMR0=010
;97=1200bps,
;
;valores para el baudrate:para 20Mhz
;
;para divisor TMR0=000
;51=38400,31=57600.
;<<<<<<<------------------------------------------------PROGRAMA PRINCIPAL---------------------------------------->>>>>>>>>>>>>>
PRINCIPAL NOP
goto PRINCIPAL
;<<<<<<---------------------------------------------SUBPROGRAMA RECEPCION DE DATOS--------------------------
RECEPCION clrf CONTADOR ;borra el contador de bits
clrf TMR0 ;borra TMR0
movfw BAUDRATE ;carga valor del baudrate en w
subwf TMR0,w ;comprueva si ha llegado al valor o se pasa
btfss STATUS,C ;si es menos sigue comprovando
goto $-3
COMP1 clrf TMR0 ;borra TMR0
COMP2 movfw BAUDRATE ;carga valor del baudrate en w
subwf TMR0,w ;resta el contenido de TMR0 con el de w(comprovacion => )
btfss STATUS,C ;comprueva si ha llegado al valor o se pasa
goto COMP2 ;si es menos sigue comprovando
btfsc PORTB,0 ;comprueva el estado del pin de entrada
call UNO ;si es 1 salta a UNO
btfss PORTB,0 ;comprueva el estado del pin de entrada
call CERO ;si es 0 salta a CERO
incf CONTADOR,F ;incrementa el contador de bits
movlw 0x08 ;valor de bit a comprovar
xorwf CONTADOR,W ;hacer xor con CONTADOR
btfss STATUS,Z ;comprueva si es igual
goto COMP1 ;si no es igual sigue las comprobaciones
movfw DATO ;carga el dato recivido en w
return ;retorno de subprograma RECEPCION
UNO rrf DATO,F ;rota a la derecha una posicion
bsf DATO,7 ;pon a 1 el bit 7 del registro DATO
return ;retorna
CERO rrf DATO,F ;rota a la derecha una posicion
bcf DATO,7 ;pon a 0 el bit 7 del registro DATO
return ;retorna
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<SUBPROGRAMA DE ENVIO DE DATOS>>>>>>>>>>>>>>>>>
ENVIO bsf PORTB,1 ;establecer la salida a 1(evitar errores primer caracter)
ENVIO2 clrf CONTADOR ;borra el registro CONTADOR de bits
bcf PORTB,1 ;bit START
call RETARDO
ENV_1 btfsc DATO,0 ;comprueva bit 0 del registro DATO(comprovacion de bits a enviar)
call UNOS ;salta a UNOS si el bit leido es 1
btfss DATO,0 ;comprueva bit 0 del registro DATO(comprovacion de bits a enviar)
call CEROS ;salta a CEROS si el bit leido es 0
ENV_2 rrf DATO,F ;rota a la derecha el registro DATO
incf CONTADOR,F ;incrementa CONTADOR (registro contador de bits)
movlw 0x08 ;valor de bits a leer
xorwf CONTADOR,W ;comprueva si son 8
btfss STATUS,Z ;si no es 8 repite la comprovacion del siguiente bit
goto ENV_1 ;comprueva de nuevo
bsf PORTB,1 ;establecer a 1 la salida
return ;retorna
UNOS bsf PORTB,1 ;saca valor 1 por pin 1 de PORTB
call RETARDO ;tiempo de un bit
return ;retorna
CEROS bcf PORTB,1 ;saca valor 0 por pin 1 de PORTB
call RETARDO ;tiempo de un bit
return ;retorna
;**********************************************RETARDO***************************************
;
;
RETARDO clrf TMR0 ;borra el temporizador
COMP movfw BAUDRATE ;valor del retardo
subwf TMR0,w ;comprueva si ha llegado al valor o se pasa
btfss STATUS,C ;si es menos sigue comprovando
goto COMP
return ;si ha llegado retorna
;*********************************************INTERRUPCIONES******************************
INTERRUPCIONES PUSH ;guarda valores de registros
btfss INTCON,INTF ;comprueva interrupcion por cambio de PB0/INT
goto SALIR ;salir del programa
call RECEPCION ;programa de recepcion de datos
call ENVIO ;programa de envio de datos
SALIR bcf INTCON,INTF ;borra bandera señalizadora de interrupcion por cambio en PB0/INT
POP ;restaura valores de registros
retfie ;retorna y activa interrupciones
end ;fin
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : mensage.asm
; Funcion : control de temperatura
;
;
; Revision : 1.0 7/8/2011 Programa para : PIC16F876A
; CPU Clock : 4 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
LIST P=16F876A ; Se emplea el PIC 16F876A
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P16F876A.INC"
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _BODEN_OFF &_LVP_OFF &_CPD_OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
TEMP_W
OFFSET
RESUL
INDICE
TEMP_PCL
TEMP_PCLATH
AUX0
AUX1
AUX2
CONT_CARACTER
ENDC
BANK0 MACRO ;CONMUTACION DE BANCOS
BCF STATUS,IRP
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK1 MACRO
BCF STATUS,IRP
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK2 MACRO
BSF STATUS,IRP
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
BANK3 MACRO
BSF STATUS,IRP
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
org 5
INICIO
BANK0
CLRF PORTA ; Initialize PORTA by
BANK1
MOVLW 0x06 ; Configure all pins
MOVWF ADCON1 ; as digital inputs
MOVLW 0xCF ; Value used to
MOVWF TRISA ; Set RA<3:0> as inputs
;PROGRAMA PRINCIPAL
movlw b'01000000' ;activado interrupcion por desbordamiento de tmr0
movwf INTCON
movlw b'00000001' ;activado interrupcion por desbordamiento de TMR1
movwf PIE1
movlw 0xff
movwf TRISA ;porta como entradas
movlw 0x00 ;
movwf TRISB ;
movlw b'00011111'
movwf TRISC ;portc como ENTRADAS
movlw b'00000000'
movwf OPTION_REG ;configuracion del WDT(div128)y activa resistencias pull-up
BANK0 ;selecciona el banco 0
clrf PORTB ;borra PORTB
clrf PORTC
movlw b'00000101'
movwf T1CON ;configuracion del TMR1 preescaler sin divisiones
bcf PIR1,TMR2IF ;borra flag de desbordamiento de TMR2
movlw 0XFF ;valor final de sector
movwf TEMP_PCL ;temporal del PCL
;clrf CONT_PCL
movlw 0x08 ;pagina donde esta ubicada la tabla(DIR 0X800 =pagina1)
MOVWF TEMP_PCLATH
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL CALL LCD
REP GOTO REP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD clrf INTCON ;deshabilita las interrupciones
BANK0 ;selecciona el banco 0
clrf PORTA ;borra lacht del PORTA
BANK1 ;selecciona el banco 1
movlw 0x06
movwf ADCON1
clrf TRISA ; Puerta A como salidas digitales
call UP_LCD ;prepara puerta de E/S
call BORRA_Y_HOME ;borra el display y posicion 0 para caracter.
call LCD_DELAY
movlw b'00110000' ;8 bit interfaz,1 linea LCD,5x8 pixel.
call FUNCTION_SET ;envia funcion
call LCD_DELAY
movlw b'00001100' ;display on,cursor off,blinking off.
call DISPLAY_ON_OFF ;envia funcion
call LCD_DELAY
movlw b'00000110' ;Establece la dirección de movimiento del cursor
call ENTRY_MODE_SET
call LCD_DELAY
call BIENVENIDA
BUCLE goto BUCLE
;********************************************* MENSAGE LCD *********************************************
;La funcion de este programa es visualizar los caracteres de la tabla.en un lcd de 16 caracteres por 2 lineas.
;para ello se almacenan los primeros 40 caracteres de la tabla en la DDRAM.para obtener un mejor efecto visual
;los primeros 16 caracteres de la tabla estaran en blanco.
;Una vez cargados los caracteres en la DDRAM,comenzaremos la rotacion del mensage por la pantalla.hasta que el caracter-
;numero 40,quede en la posicion mas a la izquierda de la pantalla.que serian 24 desplazamientos.
;Posteriormente borraremos la pantalla y colocaremos el cursor en la primera direccion de la DDRAM
;grabaremos los siguientes 40 caracteres de la tabla.pero cogeremos 16 de los ultimos caracteres que utilizamos
;en la primera visualizacion.de esta forma obtendremos un efecto visual de que el mensage no se ha cortado.
;En las lineas de abajo explico como funciona.
;Datos de la tabla:
;................ESTA ES UNA PRUEVA DE ME NSAGES LARGOS QUE CONTIENE UNA CANTIDAD DE CARACTERES LIMITADA POR LA MEMORIA
;1ª grabacion en DDRAM.los puntos son en realidad 16 espacios en blanco.
;................ESTA ES UNA PRUEVA DE ME
;2ª grabacion.
;UNA PRUEVA DE MENSAGES LARGOS QUE CONTIE
;3ª grabacion
;ARGOS QUE CONTIENE UNA CANTIDAD DE CARAC
;4ª grabacion
;ANTIDAD DE CARACTERES LIMITADA POR LA ME
;5ª grabacion
;MITADA POR LA MEMORIA...................
;Despues de cada grabacion se realizara 24 desplazamientos hacia la izquierda.si nos fijamos bien
;notaremos que despues de 24 desplazamientos,los caracteres coinciden con la siguiente grabacion.
;este es el efecto visual que hara que parezca un solo mensage muy largo.aunque en realidad son 5 mensages superpuestos
BIENVENIDA BANK0 ;selecciona banco 0
clrf CONT_CARACTER ;incrementa registro contador de caracteres
clrf RESUL ;
retorn movf OFFSET,W ;carga en W el puntero de tabla
addwf RESUL,W ;suma el contenido de W al registro RESUL
call MENSAGE ;salta a tabla de caraceres
incf RESUL,F ;incrementa resul
incf INDICE,F ;incrementa indice de tabla
movf TEMP_W,W ;restaura W
call LCD_DATO ;introduce caracter contenido en W a la ddram de la LCD.
movlw d'40' ;numero de caracteres de la ddram(primera fila)
subwf RESUL,W ;resta el valor contenido en W al registro RESUL.
btfss STATUS,C ;comprueva si se llego a meter los 40 caracteres en la ddram de la LCD
goto retorn ;si no ha llegado salta a retorn en caso contrario continua
FDG call ROTA_IZQ ;rota el LCD hacia la izquierda
call pausa1 ;pausa de rotacion de la LCD
incf CONT_CARACTER,F ;incrementa el contador de caracteres
movlw .24 ;carga valor de desplazamientos hacia la izquierda para mostrar el mensage completo del a ddram.40-16=24 => 40 bytes - 16 caracteres visibles = 24 caracteres no visibles
xorwf CONT_CARACTER,w ;comprueva si se llego al valor anterior
btfss STATUS,Z ;si no ha llegado,sigue rotando
goto FDG
movlw .16 ;numero de bytes visibles de la LCD (LCD 16x2)
subwf INDICE,F ;desplaza el indice para grabar los 16 ultimos caracteres del primer mensage de la ddr,en los 16 primeros caracteres del siguiente mensage
clrf CONT_CARACTER ;borra contador de caracteres
clrf RESUL ;borra RESUL
call BORRA_Y_HOME ;borra el display y posicion 0 para caracter.
goto retorn ;siguiente mensage
;************************************************ RETARDO **********************************************************
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de emporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,1 ;velor de temporizacion
goto pausae3
return
;************************************************ MENSAGE ******************************************************
MENSAGE movlw 0xfc
xorwf INDICE,W ;compara si es igual al indice
btfsc STATUS,Z ;si es asi.(valor final del sector)
fin_bank incf TEMP_PCLATH,F ;incrementa PCLATH (para leer datos del siguiente sector)
bsf PCLATH,3 ;conmuta pagina 1 antes de la llamada al subprograma MENSAGE que esta hubicado en la misma
movlw d'32' ;valor del final de la memoria de programa
xorwf TEMP_PCLATH,W ;comparalo con temporal de paginacion
btfsc STATUS,Z
return ;si ha llegado termina el programa de visualizacion de mensages en LCD
call TABLA ;localiza caracter a leer en la tabla
movwf TEMP_W ;guarda el valor localizado de la tabla en el temporal del acumulador
clrf PCLATH ;borra PCLATH antes de retornar a la pagina 0
return ;retorna
org 0x800 ;direccion de memoria donde se hubicara la tabla(primer byte de la pagina 1)
TABLA movf TEMP_PCLATH,W ;carga en w el valor de la pagina
movwf PCLATH ;conmuta la pagina
movfw INDICE ;carga el contenido de INDICE en w
addwf PCL,f ;direcciona el valor a leer de la tabla.
dt " En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua,"
dt " rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lentejas los viernes, algún palomin"
dt "o de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas con sus pantufl"
dt "os de lo mismo, los días de entre semana se honraba con su vellori de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta, y una sobrina que no llegab"
dt "a a los veinte, y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años, era de c"
dt "omplexión recia, seco de carnes, enjuto de rostro; gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de Quijada o Quesada (que en esto hay"
dt " alguna diferencia en los autores que deste caso escriben), aunque por conjeturas verosímiles se deja entender que se llama Quijana; pero esto importa poco a nuest"
dt "ro cuento; basta que en la narración dél no se salga un punto de la verdad. Es, pues, de saber, que este sobredicho hidalgo, los ratos que estaba ocioso (que eran "
dt "los más del año) se daba a leer libros de caballerías con tanta afición y gusto, que olvidó casi de todo punto el ejercicio de la caza, y aun la administración de "
dt "su hacienda; y llegó a tanto su curiosidad y desatino en esto, que vendió muchas hanegas de tierra de sembradura, para comprar libros de caballerías en que leer; y"
dt " así llevó a su casa todos cuantos pudo haber dellos; y de todos ningunos le parecían tan bien como los que compuso el famoso Feliciano de Silva: porque la clarida"
dt "d de su prosa, y aquellas intrincadas razones suyas, le parecían de perlas; y más cuando llegaba a leer aquellos requiebros y cartas de desafío, donde en muchas pa"
dt "rtes hallaba escrito: la razón de la sinrazón que a mi razón se hace, de tal manera mi razón enflaquece, que con razón me quejo de la vuestra fermosura, y también "
dt "cuando leía: los altos cielos que de vuestra divinidad divinamente con las estrellas se fortifican, y os hacen merecedora del merecimiento que merecela vuestra gra"
dt "deza. Con estas y semejantes razones perdía el pobre caballero el juicio, y desvelábase por entenderlas, y desentrañarles el sentido, que no se lo sacara, ni las e"
dt " entendiera el mismo Aristóteles, si resucitara para sólo ello. No estaba muy bien con las heridas que don Belianis daba y recibía, porque se imaginaba quepor gran"
dt "des maestros que le hubiesen curado, no dejaría de tener el rostro y todo el cuerpo lleno de cicatrices y señales; pero con todo alababa en su autor aquel acabar s"
dt "u libro con la promesa de aquella inacabable aventura, y muchas veces le vino deseo de tomar la pluma, y darle fin al pie de la letra como allí se promete; y sin d"
dt "uda alguna lo hiciera, y aun saliera con ello, si otros mayores y continuos pensamientos no se lo estorbaran. Tuvo muchas veces competencia con el cura de su lugar"
dt " (que era hombre docto graduado en Sigüenza), sobre cuál había sido mejor caballero, Palmerín de Inglaterra o Amadís de Gaula; mas maese Nicolás, barbero del mismo"
dt " pueblo, decía que ninguno llegaba al caballero del Febo, y que si alguno se le podía comparar, era don Galaor, hermano de Amadís de Gaula, porque tenía muy acomod"
dt "ada condición para todo; que no era caballero melindroso, ni tan llorón como su hermano, y que en lo de la valentía no le iba en zaga. En resolución, él se enenfra"
dt "scó tanto en su lectura, que se le pasaban las noches leyendo de claro en claro, y los días de turbio en turbio, y así, del poco dormir y del mucho leer, se le sec"
dt "ó el cerebro, de manera que vino a perder el juicio. Llenósele la fantasía de todo aquello que leía en los libros, así de encantamientos, como de pendencias, batal"
dt "las, desafíos, heridas, requiebros, amores, tormentas y disparates imposibles, y asentósele de tal modo en la imaginación que era verdad toda aquella máquina de aq"
dt "uellas soñadas invenciones que leía, que para él no había otra historia más cierta en el mundo. Decía él, que el Cid Ruy Díaz había sido muy buen caballero; pero q"
dt "ue ver con el caballero de la ardiente espada, que de sólo un revés había partido por medio dos fieros y descomunales gigantes. Mejor estaba con Bernardo del Carpi"
dt "Carpio, porque en Roncesvalle había muerto a Roldán el encantado, valiéndose de la industria de Hércules, cuando ahogó a Anteo, el hijo de la Tierra, entre los bra"
dt "brazos. Decía mucho bien del gigante Morgante, porque con ser de aquella generación gigantesca, que todos son soberbios y descomedidos, él solo era afable y bien c"
dt "riado; pero sobre todos estaba bien con Reinaldos de Montalbán, y más cuando le veía salir de su castillo y robar cuantos topaba, y cuando en Allende robó aquel íd"
dt "olo de Mahoma, que era todo de oro, según dice su historia. Diera él, por dar una mano de coces al traidor de Galalón, al ama que tenía y aun a su sobrina de añadi"
dt "dura. En efecto, rematado ya su juicio, vino a dar en el más extraño pensamiento que jamás dio loco en el mundo, y fue que le pareció convenible y necesario, así p"
dt "ara el aumento de su honra, como para el servicio de su república, hacerse caballero andante, e irse por todo el mundo con sus armas y caballo a buscar las aventur"
dt "as, y a ejercitarse en todo aquello que él había leído, que los caballeros andantes se ejercitaban, deshaciendo todo género de agravio, y poniéndose en ocasiones y"
dt " peligros, donde acabándolos, cobrase eterno nombre y fama. Imaginábase el pobre ya coronado por el valor de su brazo por lo menos del imperio de Trapisonda: y así"
dt " con estos tan agradables pensamientos, llevado del estraño gusto que en ellos sentía, se dió priesa a poner en efecto lo que deseaba. Y lo primero que hizo, fue l"
dt "impiar unas arma"
org 0x1f00
dt "s, que habían sido de sus bisabuelos, que, tomadas de orín y llenas de moho, luengos siglos había que estaban puestas y olvidadas en un rincón. Lim"
dt "piólas y aderezólas lo mejor que pudo; pero vió que tenían una gran falta, y era que no tenía celada de encaj"
org 0x500
include "lcd_cxx_V2.inc"
end
;LCD_CXX.ASM
;El conjunto de rutinas que se presentan a continuaci¢n permiten realizar
;las tareas b sicas de control del m¢dulo de visualizaci¢n LCD. Se emplean
;con los PIC 16c8xx. En el programa principal se deber reservar memoria
;para el bloque de variables que utiliza el LCD del modo:
LCD_VAR EQU 0x5A ;direccion de inicio del bloque para meter datos en variables
;BLOQUE DE ETIQUETAS
#define ENABLE bsf PORTA,2 ;Activa E
#define DISABLE bcf PORTA,2 ;Desactiva
#define LEER bsf PORTA,1 ;Pone LCD en Modo RD
#define ESCRIBIR bcf PORTA,1 ;Pone LCD en Modo WR
#define OFF_COMANDO bcf PORTA,0 ;Desactiva RS (modo comando)
#define ON_COMANDO bsf PORTA,0 ;Activa RS (modo datos)
CBLOCK LCD_VAR
LCD_TEMP_2 ;Inicio de las variables. Ser la primera direcci¢n libre
; disponible
LCD_TEMP_1
ENDC
LIST
;RUTINA UP_LCD: Con esta rutina se configura el PIC para que trabaje con el LCD.
UP_LCD
BANK1 ;Banco 1
clrf TRISB;PORTB ;RB <0-7> salidas digitales
clrf TRISB;PORTA ;RA <0-4> salidas digitales
BANK0 ;Banco 0
OFF_COMANDO ;RS=0
DISABLE ;E=0
return
;RUTINA LCD_BUSY: Con esta rutina se chequea el estado del
;flag BUSY del m¢dulo LCD, que indica, cuando est activado, que el
;m¢dulo a£n no ha terminado el comando anterior. La rutina espera a
;que se complete cualquier comando anterior antes de retornar al
;programa principal, para poder enviar un nuevo comando.
LCD_BUSY LEER ;Pone el LCD en Modo RD
BANK1
movlw H'FF'
movwf TRISB ;Puerta B como entrada
BANK0 ;Selecciona el banco 0
ENABLE ;Activa el LCD
nop
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY
DISABLE ;Desactiva LCD
BANK1
clrf TRISB ;Puerta B salida
BANK0
ESCRIBIR ;Pone LCD en modo WR
return
;RUTINA LCD_E: Se trata de una peque¤a rutina que se encarga de generar
;un impulso de 1æ s (para una frecuencia de funcionamiento de 4 Mhz)
;por la patita de salida de la Puerta A RA2, que se halla conectada
;a la se¤al E (Enable) del m¢dulo LCD. Con esta rutina se pretende activar
;al m¢dulo LCD.
LCD_E ENABLE ;Activa E
nop
DISABLE ;Desactiva E
return
;RUTINA LCD_DATO: Es una rutina que pasa el contenido cargado en el
;registro W, el cual contiene un car cter ASCII, a la PUERTA B, para
;visualizarlo por el LCD o escribirlo en la CGRAM.
LCD_DATO OFF_COMANDO ;Desactiva RS (modo comando)
movwf PORTB ;Valor ASCII a sacar por PORTB
call LCD_BUSY ;Espera a que se libere el LCD
ON_COMANDO ;Activa RS (modo dato)
call LCD_E ;Genera pulso de E
return
;RUTINA LCD_REG: Rutina parecida a la anterior, pero 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_REG OFF_COMANDO ;Desactiva RS (modo comando)
BANK0
movwf PORTB ;C¢digo de comando
call LCD_BUSY ;LCD libre?.
call LCD_E ;S¡. Genera pulso de E.
return
;RUTINA LCD_INI: Esta rutina se encarga de realizar la secuencia de
;inicializaci¢n del m¢dulo LCD de acuerdo con los tiempos dados por
;el fabricante (15 ms). Se especifican los valores de DL, N y F,
;as¡ como la configuraci¢n de un interfaz de 8 l¡neas con el bus
;de datos del PIC, y 2 l¡neas de 16 caracteres de 5 x 7 pixels.
LCD_INI
movlw b'00111000'
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
movlw b'00111000'
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
movlw b'00111000'
call LCD_REG ;C¢digo de instrucci¢n
call LCD_DELAY ;Temporiza
return
;RUTINA BORRA_Y_HOME: Borra el display y retorna el cursor a la posici¢n 0.
BORRA_Y_HOME movlw b'00000001' ;Borra LCD y Home.
call LCD_REG
return
;RUTINA DISPLAY_ON_CUR_OFF: Control del display y cursor.
;Activa el display y desactiva es cursor
DISPLAY_ON_OFF ;movlw b'00001100' ;LCD on, cursor off.
call LCD_REG
return
;RUTINA LCD_LINEA2
LCD_LINEA2 movlw 0xC0
call LCD_REG
return
;RUTINA LCD_LINEA1
LCD_LINEA1 movlw 0x80
call LCD_REG
return
ROTA_DER movlw b'00011000'
call LCD_REG
call LCD_DELAY ;Temporiza
return
SET_DDRAM ;movlw b'00100000'
call LCD_REG
call LCD_DELAY
return
FUNCTION_SET
call LCD_REG
return
ENTRY_MODE_SET
call LCD_REG
return
ROTA_IZQ
movlw b'00011100'
call LCD_REG
return
;RUTINA LCD_DELAY: Se trata de un rutina que implementa un retardo
;o temporizaci¢n de 5 ms. Utiliza dos variables llamadas LCD_TEMP_1
;y LCD_TEMP_2, que se van decrementando hasta alcanzar dicho tiempo.
LCD_DELAY clrwdt
movlw 10
movwf LCD_TEMP_1
clrf LCD_TEMP_2
LCD_DELAY_1 decfsz LCD_TEMP_2,F
goto LCD_DELAY_1
decfsz LCD_TEMP_1,F
goto LCD_DELAY_1
return
LIST
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : mensage_16f876_4bit.asm
; Funcion : visualizacion de un mensage largo en el modo LCD 4bit
;
;
; Revision : 1.0 7/8/2011 Programa para : PIC16F876A
; CPU Clock : 4 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
LIST P=16F876A ; Se emplea el PIC 16F876A
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P16F876A.INC"
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _BODEN_OFF &_LVP_OFF &_CPD_OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
TEMP_W
OFFSET
RESUL
INDICE
TEMP_PCL
TEMP_PCLATH
AUX0
AUX1
AUX2
CONT_CARACTER
TEMPLCD
TEMP_PORTB
PDel0
TEMP_RS
ENDC
BANK0 MACRO ;CONMUTACION DEL BANCO 0
BCF STATUS,IRP
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK1 MACRO ;CONMUTACION DEL BANCO 1
BCF STATUS,IRP
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK2 MACRO ;CONMUTACION DEL BANCO 2
BSF STATUS,IRP
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
BANK3 MACRO ;CONMUTACION DEL BANCO 3
BSF STATUS,IRP
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
PULSO MACRO ;PULSO EN TERMINAL E DE LA LCD
bsf PORTA,2
call RETARDO
bcf PORTA,2
ENDM
#define COMANDOS bcf PORTA,0 ;Desactiva RS (modo comando)
#define DATOS bsf PORTA,0 ;Activa RS (modo datos)
#define E EQU 2
#define RS EQU 0
#define READ bsf PORTA,1
#define WRITE bcf PORTA,1
#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD
org 5
INICIO
BANK0
clrf PORTA ; inicializa PORTA
clrf PORTB ; inicializa PORTB
BANK1
movlw 0x06 ; configura los pin
movwf ADCON1 ; como entradas digitales
movlw 0xCF ; Value used to
movwf TRISA ; activa RA<3:0> como entradas
movlw 0x00 ;
movwf TRISB ;PORTB como salidas
BANK0 ;selecciona el banco 0
clrf PORTB ;borra PORTB
movlw 0XFF ;valor final de sector
movwf TEMP_PCL ;temporal del PCL
movlw 0x08 ;pagina donde esta ubicada la tabla(DIR 0X800 =pagina1)
movwf TEMP_PCLATH
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL CALL LCD
REP GOTO REP ;fin del programa.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD clrf INTCON ;deshabilita las interrupciones
BANK0 ;selecciona el banco 0
clrf PORTA ;borra lacht del PORTA
BANK1 ;selecciona el banco 1
movlw 0x06
movwf ADCON1
clrf TRISA ; Puerta A como salidas digitales
call LCDINI ;inicializa la LCD
call BIENVENIDA ;salta a mensage de bienvenida
return
;********************************************* MENSAGE LCD *********************************************
;La funcion de este programa es visualizar los caracteres de la tabla.en un lcd de 16 caracteres por 2 lineas.
;para ello se almacenan los primeros 40 caracteres de la tabla en la DDRAM.para obtener un mejor efecto visual
;los primeros 16 caracteres de la tabla estaran en blanco.
;Una vez cargados los caracteres en la DDRAM,comenzaremos la rotacion del mensage por la pantalla.hasta que el caracter-
;numero 40,quede en la posicion mas a la izquierda de la pantalla.que serian 24 desplazamientos.
;Posteriormente borraremos la pantalla y colocaremos el cursor en la primera direccion de la DDRAM
;grabaremos los siguientes 40 caracteres de la tabla.pero cogeremos 16 de los ultimos caracteres que utilizamos
;en la primera visualizacion.de esta forma obtendremos un efecto visual de que el mensage no se ha cortado.
;En las lineas de abajo explico como funciona.
;Datos de la tabla:
;................ESTA ES UNA PRUEVA DE ME NSAGES LARGOS QUE CONTIENE UNA CANTIDAD DE CARACTERES LIMITADA POR LA MEMORIA
;1ª grabacion en DDRAM.los puntos son en realidad 16 espacios en blanco.
;................ESTA ES UNA PRUEVA DE ME
;2ª grabacion.
;UNA PRUEVA DE MENSAGES LARGOS QUE CONTIE
;3ª grabacion
;ARGOS QUE CONTIENE UNA CANTIDAD DE CARAC
;4ª grabacion
;ANTIDAD DE CARACTERES LIMITADA POR LA ME
;5ª grabacion
;MITADA POR LA MEMORIA...................
;Despues de cada grabacion se realizara 24 desplazamientos hacia la izquierda.si nos fijamos bien
;notaremos que despues de 24 desplazamientos,los caracteres coinciden con la siguiente grabacion.
;este es el efecto visual que hara que parezca un solo mensage muy largo.aunque en realidad son 5 mensages superpuestos
;**************************************************** FUNCIONAMIENTO DE ALGUNAS RUTINAS ************************************************
;
;Ddebido a que el uso de una libreria para LCD es un desaprobecho de los recursos del pic.ya que ocupariamos una gran
;parte de la memoria de programa.y perdida de tiempo en las llamadas a estas rutinas.
;He decidido insertar los comandos en el programa principal.estos comandos iran precedidos de una instruccion para
;la conmutacion entre datos y comandos.ejamplo:
;
;envio de un comando a la LCD:
;COMANDOS
;MOVLW 0X01 ;envio del comando HOME
;CALL BYTE
;
;envio de un datos a la LCD:
;DATOS
;MOVLW 'A' ;envio del caracter "A"
;CALL BYTE
;
;************************************************************MENSAGE DE BIENVENIDA******************************************************
BIENVENIDA BANK0 ;selecciona banco 0
clrf CONT_CARACTER ;incrementa registro contador de caracteres
clrf RESUL ;borra registro RESUL
retorn DATOS ;selecciona modo de envio de datos
movf OFFSET,W ;carga en W el puntero de tabla
addwf RESUL,W ;suma el contenido de W al registro RESUL
call MENSAGE ;salta a tabla de caraceres
incf RESUL,F ;incrementa resul
incf INDICE,F ;incrementa indice de tabla
movf TEMP_W,W ;restaura W
call BYTE ;introduce caracter contenido en W a la ddram de la LCD.
movlw d'40' ;numero de caracteres de la ddram(primera fila)
subwf RESUL,W ;resta el valor contenido en W al registro RESUL.
btfss STATUS,C ;comprueva si se llego a meter los 40 caracteres en la ddram de la LCD
goto retorn ;si no ha llegado salta a retorn en caso contrario continua
FDG COMANDOS ;selecciona modo de envio de comandos
movlw b'00011100' ;comando de rotacion a izquierdas
call BYTE ;envia comando
call pausa1 ;pausa de rotacion de la LCD
incf CONT_CARACTER,F ;incrementa el contador de caracteres
movlw .24 ;carga valor de desplazamientos hacia la izquierda para mostrar el mensage completo del a ddram.40-16=24 => 40 bytes - 16 caracteres visibles = 24 caracteres no visibles
xorwf CONT_CARACTER,w ;comprueva si se llego al valor anterior
btfss STATUS,Z ;si no ha llegado,sigue rotando
goto FDG
movlw .16 ;numero de bytes visibles de la LCD (LCD 16x2)
subwf INDICE,F ;desplaza el indice para grabar los 16 ultimos caracteres del primer mensage de la ddr,en los 16 primeros caracteres del siguiente mensage
clrf CONT_CARACTER ;borra contador de caracteres
clrf RESUL ;borra RESUL
COMANDOS ;selecciona el modo comando para la LCD
movlw 0X01 ;HOME. posicion 0 de la DD RAM.
call BYTE ;envia comando
goto retorn ;siguiente mensage
;************************************************** INICIALIZACION LCD *************************************************************
LCDINI COMANDOS ;selecciona el modo comando para la LCD
movlw 0X02 ;HOME. posicion 0 de la DD RAM.
call BYTE
movlw 0X28 ;FUNCTION SET. bus 4bit,LCD 1 linea.
call BYTE
movlw 0X0C ;DISPLAY ON/OFF. display on.
call BYTE
movlw 0X06 ;ENTRY MODE.incremento del cursor
call BYTE
movlw 0X01 ;CLEAR DISPLAY. borra display y activa incremento del cursor
call BYTE
return
;********************************************** ENVIO DE NIBLES A LA LCD ******************************************************
BYTE BANK0 ;selcciona el banco 0
movwf TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD
call LCD_BUSY ;comprueva si el LCD esta libre
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
movf TEMPLCD,W ;carga el contenido de TEMPLCD en W
andlw 0xf0 ;seleccionar el nible alto de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
swapf TEMPLCD,W ;inbierte los nibles del registro TEMPLCD
andlw 0xf0 ;seleccionar el alto bajo de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
return ;retorna
LCD_BUSY call RETARDO ;retardo para evitar que la lectura del flag BUSY se quede bloqueado.
movfw PORTA ;carga en W el contenido de PORTA
andlw 0x01 ;guarda el valor del estado del bit RS
movwf TEMP_RS ;salva el valor de RS en el registro temporal
COMANDOS ;selecciona el modo comandos
BANK1 ;selecciona banco 1
movlw H'F0' ;
movwf TRISB ;nible alto de PORT B como entrada
BANK0 ;Selecciona el banco 0
READ ;Pone el LCD en Modo RD "lectura"
ENABLE ;Activa el LCD (lectura del nible alto)
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY ;espera a que la LCD este libre
DISABLE ;Desactiva LCD
ENABLE ;Activa el LCD (lectura del nible bajo)
call RETARDO ;retardo de 1ms
DISABLE ;Desactiva LCD
BANK1 ;selecciona banco 1
clrf TRISB ;Puerta B salida
BANK0 ;Selecciona el banco 0
WRITE ;Pone LCD en modo WR
movfw TEMP_RS ;restaura el valor de SR
iorwf PORTA,f ;activa en PORTA el bit RS
return ;retorna
;************************************************ RETARDO DE VELOCIDAD DE DESPLAZAMIENTO **********************************************************
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de temporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,1 ;velor de temporizacion
goto pausae3
return
;************************************************ RETARDO 1mS **********************************************************
RETARDO movlw .248 ; 1 set numero de repeticion
movwf PDel0 ; 1 |
PLoop0 clrwdt ; 1 clear watchdog
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;************************************************ MENSAGE ******************************************************
MENSAGE movlw 0xfc
xorwf INDICE,W ;compara si es igual al indice
btfsc STATUS,Z ;si es asi.(valor final del sector)
fin_bank incf TEMP_PCLATH,F ;incrementa PCLATH (para leer datos del siguiente sector)
bsf PCLATH,3 ;conmuta pagina 1 antes de la llamada al subprograma MENSAGE que esta hubicado en la misma
movlw d'32' ;valor del final de la memoria de programa
xorwf TEMP_PCLATH,W ;comparalo con temporal de paginacion
btfsc STATUS,Z
return ;si ha llegado termina el programa de visualizacion de mensages en LCD
call TABLA ;localiza caracter a leer en la tabla
movwf TEMP_W ;guarda el valor localizado de la tabla en el temporal del acumulador
clrf PCLATH ;borra PCLATH antes de retornar a la pagina 0
return ;retorna
org 0x800 ;direccion de memoria donde se hubicara la tabla(primer byte de la pagina 1)
TABLA movf TEMP_PCLATH,W ;carga en w el valor de la pagina
movwf PCLATH ;conmuta la pagina
movfw INDICE ;carga el contenido de INDICE en w
addwf PCL,f ;direcciona el valor a leer de la tabla.
dt " En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua,"
dt " rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lentejas los viernes, algún palomin"
dt "o de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas con sus pantufl"
dt "os de lo mismo, los días de entre semana se honraba con su vellori de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta, y una sobrina que no llegab"
dt "a a los veinte, y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años, era de c"
dt "omplexión recia, seco de carnes, enjuto de rostro; gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de Quijada o Quesada (que en esto hay"
dt " alguna diferencia en los autores que deste caso escriben), aunque por conjeturas verosímiles se deja entender que se llama Quijana; pero esto importa poco a nuest"
dt "ro cuento; basta que en la narración dél no se salga un punto de la verdad. Es, pues, de saber, que este sobredicho hidalgo, los ratos que estaba ocioso (que eran "
dt "los más del año) se daba a leer libros de caballerías con tanta afición y gusto, que olvidó casi de todo punto el ejercicio de la caza, y aun la administración de "
dt "su hacienda; y llegó a tanto su curiosidad y desatino en esto, que vendió muchas hanegas de tierra de sembradura, para comprar libros de caballerías en que leer; y"
dt " así llevó a su casa todos cuantos pudo haber dellos; y de todos ningunos le parecían tan bien como los que compuso el famoso Feliciano de Silva: porque la clarida"
dt "d de su prosa, y aquellas intrincadas razones suyas, le parecían de perlas; y más cuando llegaba a leer aquellos requiebros y cartas de desafío, donde en muchas pa"
dt "rtes hallaba escrito: la razón de la sinrazón que a mi razón se hace, de tal manera mi razón enflaquece, que con razón me quejo de la vuestra fermosura, y también "
dt "cuando leía: los altos cielos que de vuestra divinidad divinamente con las estrellas se fortifican, y os hacen merecedora del merecimiento que merecela vuestra gra"
dt "deza. Con estas y semejantes razones perdía el pobre caballero el juicio, y desvelábase por entenderlas, y desentrañarles el sentido, que no se lo sacara, ni las e"
dt " entendiera el mismo Aristóteles, si resucitara para sólo ello. No estaba muy bien con las heridas que don Belianis daba y recibía, porque se imaginaba quepor gran"
dt "des maestros que le hubiesen curado, no dejaría de tener el rostro y todo el cuerpo lleno de cicatrices y señales; pero con todo alababa en su autor aquel acabar s"
dt "u libro con la promesa de aquella inacabable aventura, y muchas veces le vino deseo de tomar la pluma, y darle fin al pie de la letra como allí se promete; y sin d"
dt "uda alguna lo hiciera, y aun saliera con ello, si otros mayores y continuos pensamientos no se lo estorbaran. Tuvo muchas veces competencia con el cura de su lugar"
dt " (que era hombre docto graduado en Sigüenza), sobre cuál había sido mejor caballero, Palmerín de Inglaterra o Amadís de Gaula; mas maese Nicolás, barbero del mismo"
dt " pueblo, decía que ninguno llegaba al caballero del Febo, y que si alguno se le podía comparar, era don Galaor, hermano de Amadís de Gaula, porque tenía muy acomod"
dt "ada condición para todo; que no era caballero melindroso, ni tan llorón como su hermano, y que en lo de la valentía no le iba en zaga. En resolución, él se enenfra"
dt "scó tanto en su lectura, que se le pasaban las noches leyendo de claro en claro, y los días de turbio en turbio, y así, del poco dormir y del mucho leer, se le sec"
dt "ó el cerebro, de manera que vino a perder el juicio. Llenósele la fantasía de todo aquello que leía en los libros, así de encantamientos, como de pendencias, batal"
dt "las, desafíos, heridas, requiebros, amores, tormentas y disparates imposibles, y asentósele de tal modo en la imaginación que era verdad toda aquella máquina de aq"
dt "uellas soñadas invenciones que leía, que para él no había otra historia más cierta en el mundo. Decía él, que el Cid Ruy Díaz había sido muy buen caballero; pero q"
dt "ue ver con el caballero de la ardiente espada, que de sólo un revés había partido por medio dos fieros y descomunales gigantes. Mejor estaba con Bernardo del Carpi"
dt "Carpio, porque en Roncesvalle había muerto a Roldán el encantado, valiéndose de la industria de Hércules, cuando ahogó a Anteo, el hijo de la Tierra, entre los bra"
dt "brazos. Decía mucho bien del gigante Morgante, porque con ser de aquella generación gigantesca, que todos son soberbios y descomedidos, él solo era afable y bien c"
dt "riado; pero sobre todos estaba bien con Reinaldos de Montalbán, y más cuando le veía salir de su castillo y robar cuantos topaba, y cuando en Allende robó aquel íd"
dt "olo de Mahoma, que era todo de oro, según dice su historia. Diera él, por dar una mano de coces al traidor de Galalón, al ama que tenía y aun a su sobrina de añadi"
dt "dura. En efecto, rematado ya su juicio, vino a dar en el más extraño pensamiento que jamás dio loco en el mundo, y fue que le pareció convenible y necesario, así p"
dt "ara el aumento de su honra, como para el servicio de su república, hacerse caballero andante, e irse por todo el mundo con sus armas y caballo a buscar las aventur"
dt "as, y a ejercitarse en todo aquello que él había leído, que los caballeros andantes se ejercitaban, deshaciendo todo género de agravio, y poniéndose en ocasiones y"
dt " peligros, donde acabándolos, cobrase eterno nombre y fama. Imaginábase el pobre ya coronado por el valor de su brazo por lo menos del imperio de Trapisonda: y así"
dt " con estos tan agradables pensamientos, llevado del estraño gusto que en ellos sentía, se dió priesa a poner en efecto lo que deseaba. Y lo primero que hizo, fue l"
dt "impiar unas arma"
org 0x1f00
dt "s, que habían sido de sus bisabuelos, que, tomadas de orín y llenas de moho, luengos siglos había que estaban puestas y olvidadas en un rincón. Lim"
dt "piólas y aderezólas lo mejor que pudo; pero vió que tenían una gran falta, y era que no tenía celada de encaj"
org 0x500
include "lcd_cxx_V2.inc"
end
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : pruevas_LCD_v1.asm
; Funcion : pruevas con los comandos de una lcd en modo a 4bits
;
;
; Revision : 1.0 8/9/2011 Programa para : PIC16F876A
; CPU Clock : 4 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
LIST P=16F876A ; Se emplea el PIC 16F876A
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P16F876A.INC"
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _BODEN_OFF &_LVP_OFF &_CPD_OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
TEMP_W
OFFSET
RESUL
INDICE
TEMP_PCL
TEMP_PCLATH
AUX0
AUX1
AUX2
CONT_CARACTER
TEMPLCD
TEMP_PORTB
PDel0
TEMP_RS
ENDC
BANK0 MACRO ;CONMUTACION DEL BANCO 0
BCF STATUS,IRP
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK1 MACRO ;CONMUTACION DEL BANCO 1
BCF STATUS,IRP
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK2 MACRO ;CONMUTACION DEL BANCO 2
BSF STATUS,IRP
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
BANK3 MACRO ;CONMUTACION DEL BANCO 3
BSF STATUS,IRP
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
PULSO MACRO ;PULSO EN TERMINAL E DE LA LCD
bsf PORTA,2
call RETARDO
bcf PORTA,2
ENDM
#define COMANDOS bcf PORTA,0 ;Desactiva RS (modo comando)
#define DATOS bsf PORTA,0 ;Activa RS (modo datos)
#define E EQU 2
#define RS EQU 0
#define READ bsf PORTA,1
#define WRITE bcf PORTA,1
#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD
org 5
INICIO
BANK0
clrf PORTA ; inicializa PORTA
clrf PORTB ; inicializa PORTB
BANK1
movlw 0x06 ; configura los pin
movwf ADCON1 ; como entradas digitales
movlw 0xCF ; Value used to
movwf TRISA ; activa RA<3:0> como entradas
movlw 0x00 ;
movwf TRISB ;PORTB como salidas
BANK0 ;selecciona el banco 0
clrf PORTB ;borra PORTB
movlw 0XFF ;valor final de sector
movwf TEMP_PCL ;temporal del PCL
movlw 0x08 ;pagina donde esta ubicada la tabla(DIR 0X800 =pagina1)
movwf TEMP_PCLATH
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL CALL LCD
REP GOTO REP ;fin del programa.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD clrf INTCON ;deshabilita las interrupciones
BANK0 ;selecciona el banco 0
clrf PORTA ;borra lacht del PORTA
BANK1 ;selecciona el banco 1
movlw 0x06
movwf ADCON1
clrf TRISA ; Puerta A como salidas digitales
call LCDINI ;inicializa la LCD
call PRUEVAS ;salta a mensage de bienvenida
return
;************************************************************ PRUEVAS ******************************************************
PRUEVAS NOP
DATOS ;activa envio de datos
MOVLW 'E'
CALL BYTE
MOVLW 's'
CALL BYTE
MOVLW 'p'
CALL BYTE
MOVLW 'a'
CALL BYTE
MOVLW 'ñ'
CALL BYTE
MOVLW 'a'
CALL BYTE
COMANDOS ;activa envio de comandos
MOVLW B'00001110' ;activa display,y el cursor
CALL BYTE
MOVLW B'00000100' ;decremento del cursor
CALL BYTE
DATOS ;activa envio de datos
MOVLW ' '
CALL BYTE
MOVLW ' '
CALL BYTE
COMANDOS ;activa envio de comandos
MOVLW B'00000110' ;incremento del cursor
CALL BYTE
DATOS ;activa envio de datos
MOVLW b'11101110' ;letra "ñ"
CALL BYTE
MOVLW 'a'
CALL BYTE
MOVLW ' '
CALL BYTE
MOVLW 'F'
CALL BYTE
MOVLW 'C'
CALL BYTE
MOVLW '.'
CALL BYTE
COMANDOS
MOVLW B'00010100'; mueve el cursor a la derecha
CALL BYTE
MOVLW B'00010000'; mueve el cursor a la izquierda
CALL BYTE
MOVLW B'00010000'; mueve el cursor a la izquierda
CALL BYTE
MOVLW B'00001101'; display on,cursor on.
CALL BYTE
MOVLW B'00001111'; display on,cursor on,parpadeo on.
CALL BYTE
goto $-2
RETURN
;************************************************** INICIALIZACION LCD *************************************************************
LCDINI COMANDOS ;selecciona el modo comando para la LCD
movlw 0X02 ;HOME. posicion 0 de la DD RAM.
call BYTE
movlw 0X28 ;FUNCTION SET. bus 4bit,LCD 1 linea.
call BYTE
movlw 0X0C ;DISPLAY ON/OFF. display on.
call BYTE
movlw 0X06 ;ENTRY MODE.incremento del cursor
call BYTE
movlw 0X01 ;CLEAR DISPLAY. borra display y activa incremento del cursor
call BYTE
return
;********************************************** ENVIO DE NIBLES A LA LCD ******************************************************
BYTE BANK0 ;selcciona el banco 0
movwf TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD
call LCD_BUSY ;comprueva si el LCD esta libre
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
movf TEMPLCD,W ;carga el contenido de TEMPLCD en W
andlw 0xf0 ;seleccionar el nible alto de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
swapf TEMPLCD,W ;inbierte los nibles del registro TEMPLCD
andlw 0xf0 ;seleccionar el alto bajo de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
return ;retorna
LCD_BUSY call RETARDO ;retardo para evitar que la lectura del flag BUSY se quede bloqueado.
movfw PORTA ;carga en W el contenido de PORTA
andlw 0x01 ;guarda el valor del estado del bit RS
movwf TEMP_RS ;salva el valor de RS en el registro temporal
COMANDOS ;selecciona el modo comandos
BANK1 ;selecciona banco 1
movlw H'F0' ;
movwf TRISB ;nible alto de PORT B como entrada
BANK0 ;Selecciona el banco 0
READ ;Pone el LCD en Modo RD "lectura"
ENABLE ;Activa el LCD (lectura del nible alto)
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY ;espera a que la LCD este libre
DISABLE ;Desactiva LCD
ENABLE ;Activa el LCD (lectura del nible bajo)
call RETARDO ;retardo de 1ms
DISABLE ;Desactiva LCD
BANK1 ;selecciona banco 1
clrf TRISB ;Puerta B salida
BANK0 ;Selecciona el banco 0
WRITE ;Pone LCD en modo WR
movfw TEMP_RS ;restaura el valor de SR
iorwf PORTA,f ;activa en PORTA el bit RS
return ;retorna
;************************************************ RETARDO DE VELOCIDAD DE DESPLAZAMIENTO **********************************************************
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de temporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,1 ;velor de temporizacion
goto pausae3
return
;************************************************ RETARDO 1mS **********************************************************
RETARDO movlw .248 ; 1 set numero de repeticion
movwf PDel0 ; 1 |
PLoop0 clrwdt ; 1 clear watchdog
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
end
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : teclado_LCD_v1.asm
; Funcion : pruevas con teclado y lcd
;
;
; Revision : 1.0 9/9/2011 Programa para : PIC18F2550
; CPU Clock : 48 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
;
;NOTA: se han activado las resistencias pull-up de PORTB.debido a que se nproducia un error al leer el bit BUSY de la LCD.
; ya que las salidas de la lcd se quedan en alta impedancia.y el pic no leia correctamente D7.
LIST P=18F2550 ; Se emplea el PIC 16F876A
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P18F2550.INC"
CONFIG FOSC = HS ;Osc por XTAL 20mhz
CONFIG DEBUG = OFF
CONFIG PWRT = OFF
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
AUX0
AUX1
AUX2
TEMPLCD
PDel0
PDel1
TEMP_RS
FLAGS
ENDC
PULSO MACRO ;PULSO EN TERMINAL E DE LA LCD
bsf PORTA,2
call RETARDO
bcf PORTA,2
ENDM
#define COMANDOS bcf PORTA,0 ;Desactiva RS (modo comando)
#define DATOS bsf PORTA,0 ;Activa RS (modo datos)
#define E EQU 2
#define RS EQU 0
#define READ bsf PORTA,1
#define WRITE bcf PORTA,1
#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;ir a la primera instruccion del programa
ORG 0X001C
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO clrf INTCON,ACCESS ; deshabilita todas la interrupciones
clrf UCON,1
clrf FLAGS ;borra registro de banderas
movlw b'01110000' ;activa resistencias pull-up (evitar fallo lectura BUSY LCD)
movwf INTCON2
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL CALL LCD
REP GOTO REP ;fin del programa.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD clrf INTCON ;deshabilita las interrupciones
clrf PORTA ;borra lacht del PORTA
clrf LATA
movlw 0x0F
movwf ADCON1
movlw 0x07
movwf CMCON
clrf TRISA ; Puerta A como salidas digitales
CLRF PORTB
CLRF LATB
CLRF TRISB
call LCDINI ;inicializa la LCD
call PRUEVAS ;salta a mensage de bienvenida
return
;************************************************************ PRUEVAS ******************************************************
PRUEVAS NOP
DATOS ;activa envio de datos
MOVLW 'E'
CALL BYTE
MOVLW 's'
CALL BYTE
MOVLW 'p'
CALL BYTE
MOVLW 'a'
CALL BYTE
MOVLW 'ñ'
CALL BYTE
MOVLW 'a'
CALL BYTE
COMANDOS ;activa envio de comandos
MOVLW B'00001110' ;activa display,y el cursor
CALL BYTE
MOVLW B'00000100' ;decremento del cursor
CALL BYTE
DATOS ;activa envio de datos
MOVLW ' '
CALL BYTE
MOVLW ' '
CALL BYTE
COMANDOS ;activa envio de comandos
MOVLW B'00000110' ;incremento del cursor
CALL BYTE
DATOS ;activa envio de datos
MOVLW b'11101110' ;letra "ñ"
CALL BYTE
MOVLW 'a'
CALL BYTE
MOVLW ' '
CALL BYTE
MOVLW 'F'
CALL BYTE
MOVLW 'C'
CALL BYTE
MOVLW '.'
CALL BYTE
COMANDOS
MOVLW B'00010100'; mueve el cursor a la derecha
CALL BYTE
MOVLW B'00010000'; mueve el cursor a la izquierda
CALL BYTE
MOVLW B'00010000'; mueve el cursor a la izquierda
CALL BYTE
MOVLW B'00001101'; display on,cursor on.
CALL BYTE
MOVLW B'00001111'; display on,cursor on,parpadeo on.
CALL BYTE
goto $-2
RETURN
;************************************************** INICIALIZACION LCD *************************************************************
LCDINI COMANDOS ;selecciona el modo comando para la LCD
movlw 0X02 ;HOME. posicion 0 de la DD RAM.
call BYTE
movlw 0X28 ;FUNCTION SET. bus 4bit,LCD 1 linea.
call BYTE
movlw 0X0C ;DISPLAY ON/OFF. display on.
call BYTE
movlw 0X06 ;ENTRY MODE.incremento del cursor
call BYTE
movlw 0X01 ;CLEAR DISPLAY. borra display y activa incremento del cursor
call BYTE
return
;********************************************** ENVIO DE NIBLES A LA LCD ******************************************************
BYTE movwf TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD
call LCD_BUSY ;comprueva si el LCD esta libre
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
movf TEMPLCD,W ;carga el contenido de TEMPLCD en W
andlw 0xf0 ;seleccionar el nible alto de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
swapf TEMPLCD,W ;inbierte los nibles del registro TEMPLCD
andlw 0xf0 ;seleccionar el alto bajo de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
return ;retorna
LCD_BUSY call RETARDO ;retardo para evitar que la lectura del flag BUSY se quede bloqueado.
movf PORTA,W ;carga en W el contenido de PORTA
andlw 0x01 ;guarda el valor del estado del bit RS
movwf TEMP_RS ;salva el valor de RS en el registro temporal
COMANDOS ;selecciona el modo comandos
movlw H'F0' ;
movwf TRISB ;nible alto de PORT B como entrada
READ ;Pone el LCD en Modo RD "lectura"
ENABLE ;Activa el LCD (lectura del nible alto)
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY ;espera a que la LCD este libre
DISABLE ;Desactiva LCD
ENABLE ;Activa el LCD (lectura del nible bajo)
call RETARDO ;retardo de 1ms
DISABLE ;Desactiva LCD
clrf TRISB ;Puerta B salida
WRITE ;Pone LCD en modo WR
movf TEMP_RS,W ;restaura el valor de SR
iorwf PORTA,f ;activa en PORTA el bit RS
return ;retorna
;************************************************ RETARDO DE VELOCIDAD DE DESPLAZAMIENTO **********************************************************
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de temporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,1 ;velor de temporizacion
goto pausae3
return
;************************************************ RETARDO 1mS **********************************************************
RETARDO movlw .67 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .35 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2
return ; 2+2 Fin.
end
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : teclado_LCD_v1.asm
; Funcion : pruevas con teclado y lcd
;
;
; Revision : 1.0 9/9/2011 Programa para : PIC18F2550
; CPU Clock : 48 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
;
;NOTA: se han activado las resistencias pull-up de PORTB.debido a que se nproducia un error al leer el bit BUSY de la LCD.
; ya que las salidas de la lcd se quedan en alta impedancia.y el pic no leia correctamente D7.
LIST P=18F2550 ; Se emplea el PIC 18F2550
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P18F2550.INC"
CONFIG FOSC = HS ;Osc por XTAL 20mhz
CONFIG DEBUG = OFF
CONFIG PWRT = OFF
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
AUX0
AUX1
AUX2
TEMPLCD
PDel0
PDel1
TEMP_RS
FLAGS
ROTA_KEYB
ENDC
PULSO MACRO ;PULSO EN TERMINAL E DE LA LCD
bsf PORTA,2
call RETARDO
bcf PORTA,2
ENDM
#define COMANDOS bcf PORTA,0 ;Desactiva RS (modo comando)
#define DATOS bsf PORTA,0 ;Activa RS (modo datos)
#define E EQU 2
#define RS EQU 0
#define READ bsf PORTA,1
#define WRITE bcf PORTA,1
#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD
#define GIE_ON bsf INTCON,GIE
#define GIE_OFF bcf INTCON,GIE
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;ir a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES ALTA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X08
goto INTERRUPCIONES
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES BAJA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X18
goto INTERRUPCIONES
ORG 0X001C
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO
movlw b'00001000' ;permiso de la interrupción por cambio de estado del PORTB
movwf INTCON
clrf UCON,1
clrf FLAGS ;borra registro de banderas
movlw b'01110000' ;activa resistencias pull-up (evitar fallo lectura BUSY LCD)
movwf INTCON2
clrf PIE1,1 ; deshabilita interrupciones perifericas
movlw 0x01
movwf ROTA_KEYB
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL CALL LCD
REP CALL REFR_KEYB
GOTO REP ;fin del programa.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD GIE_OFF;clrf INTCON ;deshabilita las interrupciones
;clrf PORTA ;borra lacht del PORTA
;MOVLW 0XFF
;MOVWF PORTA
;MOVLW 0XFF
CLRF LATA
movlw 0x0F
movwf ADCON1
movlw 0x07
movwf CMCON
clrf TRISA ; Puerta A como salidas digitales
;MOVLW 0XFF
;MOVWF PORTA
;CLRF PORTB
;movlw 0x0f
;movwf TRISB
CLRF LATB
;CLRF TRISB
movlw 0x0f
movwf TRISB
clrf UCON,1
call LCDINI ;inicializa la LCD
call PRUEVAS ;salta a mensage de bienvenida
return
;************************************************************ PRUEVAS ******************************************************
PRUEVAS NOP
DATOS ;activa envio de datos LCD
MOVLW 'C' ;texto de la primera fila
CALL BYTE
MOVLW 'l'
CALL BYTE
MOVLW 'a'
CALL BYTE
MOVLW 'v'
CALL BYTE
MOVLW 'e'
CALL BYTE
MOVLW ' '
CALL BYTE
MOVLW 'D'
CALL BYTE
MOVLW 'e'
CALL BYTE
MOVLW ' '
CALL BYTE
MOVLW 'A'
CALL BYTE
MOVLW 'c'
CALL BYTE
MOVLW 'c'
CALL BYTE
MOVLW 'e'
CALL BYTE
MOVLW 's'
CALL BYTE
MOVLW 'o'
CALL BYTE
COMANDOS ;activa envio de comandos LCD
MOVLW B'00001111' ;display on,cursor on,parpadeo on.
CALL BYTE
MOVLW 0XC0 ;principio de la segunda linea
CALL BYTE
DATOS ;activa envio de datos LCD
return
REFR_KEYB movlw 0Xf0 ;nible bajo de POTB como salida
movwf TRISB
movf PORTB,W ;leer PORTB para borrar RBIF por una condición de unión mal hecha
bcf INTCON,RBIF ;se evita que salte la interrupcion al ejecutar el programa
rlncf ROTA_KEYB,F ;rota hacia la izquierda
btfsc ROTA_KEYB,4 ;comprueva si el bit se ha salido del nible bajo.
swapf ROTA_KEYB,F ;si es asi,invierte los nibles
movf ROTA_KEYB,W ;guarda el valor del registro de rotacion en W
andlw 0X0F ;tener en cuenta solo el nible bajo
movwf PORTB ;sacalo por PORTB
GIE_ON ;habilita interrupciones generales
return ;retorna
;************************************************** INICIALIZACION LCD *************************************************************
LCDINI COMANDOS ;selecciona el modo comando para la LCD
movlw 0X02 ;HOME. posicion 0 de la DD RAM.
call BYTE
movlw 0X28 ;FUNCTION SET. bus 4bit,LCD 2 linea.
call BYTE
movlw 0X0C ;DISPLAY ON/OFF. display on.
call BYTE
movlw 0X06 ;ENTRY MODE.incremento del cursor
call BYTE
movlw 0X01 ;CLEAR DISPLAY. borra display y activa incremento del cursor
call BYTE
return
;********************************************** ENVIO DE NIBLES A LA LCD ******************************************************
BYTE movwf TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD
call LCD_BUSY ;comprueva si el LCD esta libre
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
movf TEMPLCD,W ;carga el contenido de TEMPLCD en W
andlw 0xf0 ;seleccionar el nible alto de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
swapf TEMPLCD,W ;inbierte los nibles del registro TEMPLCD
andlw 0xf0 ;seleccionar el alto bajo de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
return ;retorna
LCD_BUSY call RETARDO ;retardo para evitar que la lectura del flag BUSY se quede bloqueado.
movf PORTA,W ;carga en W el contenido de PORTA
andlw 0x01 ;guarda el valor del estado del bit RS
movwf TEMP_RS ;salva el valor de RS en el registro temporal
COMANDOS ;selecciona el modo comandos
movlw H'FF' ;
movwf TRISB ;PORT B como entrada
;MOVWF LATB
READ ;Pone el LCD en Modo RD "lectura"
ENABLE ;Activa el LCD (lectura del nible alto)
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY ;espera a que la LCD este libre
DISABLE ;Desactiva LCD
ENABLE ;Activa el LCD (lectura del nible bajo)
call RETARDO ;retardo de 1ms
DISABLE ;Desactiva LCD
movlw 0X0F ;nible bajo como entradas
movwf TRISB
bsf INTCON2,RBPU ;deshabilita resistencias pull-up de PORTB
;MOVWF LATB
;clrf PORTB ;Puerta B salida
WRITE ;Pone LCD en modo WR
movf TEMP_RS,W ;restaura el valor de SR
iorwf PORTA,f ;activa en PORTA el bit RS
return ;retorna
;************************************************ RETARDO DE VELOCIDAD DE DESPLAZAMIENTO **********************************************************
;pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de temporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,1 ;velor de temporizacion
goto pausae3
return
;************************************************ RETARDO 1mS **********************************************************
RETARDO movlw .67 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .35 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 return ; 2+2 Fin.
INTERRUPCIONES
btfsc INTCON,RBIF
call TECLADO
retfie
TECLADO movf PORTB,W ;leer PORTB para borrar RBIF por una condición de unión mal hecha
bcf INTCON,RBIF ;borra flag de interrupcion por cambio de estado de PORTB
;comparacion de entradas por PORTB desde el teclado
movlw 0x14
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_1
movlw 0x24
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_2
movlw 0x44
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_3
movlw 0x81
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_A
movlw 0x12
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_4
movlw 0x22
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_5
movlw 0x42
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_6
movlw 0x82
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_B
movlw 0x11
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_7
movlw 0x21
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_8
movlw 0x41
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_9
movlw 0x84
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_C
movlw 0x18
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_F
movlw 0x28
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_0
movlw 0x48
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_E
movlw 0x88
xorwf PORTB,W
btfsc STATUS,Z
goto TECLA_D
retfie
TECLA_1 btfsc PORTB,4 ;comprueva si la tecla esta pulsada
goto $-2 ;si esta pulsada,espera
movlw '1' ;dato a enviar por la LCD
call BYTE ;envia dato
return
TECLA_2 btfsc PORTB,5
goto $-2
movlw '2'
call BYTE
return
TECLA_3 btfsc PORTB,6
goto $-2
movlw '3'
call BYTE
return
TECLA_A btfsc PORTB,7
goto $-2
movlw 'A'
call BYTE
return
TECLA_4 btfsc PORTB,4
goto $-2
movlw '4'
call BYTE
return
TECLA_5 btfsc PORTB,5
goto $-2
movlw '5'
call BYTE
return
TECLA_6 btfsc PORTB,6
goto $-2
movlw '6'
call BYTE
return
TECLA_B btfsc PORTB,7
goto $-2
movlw 'B'
call BYTE
return
TECLA_7 btfsc PORTB,4
goto $-2
movlw '7'
call BYTE
return
TECLA_8 btfsc PORTB,5
goto $-2
movlw '8'
call BYTE
return
TECLA_9 btfsc PORTB,6
goto $-2
movlw '9'
call BYTE
return
TECLA_C btfsc PORTB,7
goto $-2
movlw 'C'
call BYTE
return
TECLA_F btfsc PORTB,4
goto $-2
movlw 'F'
call BYTE
return
TECLA_0 btfsc PORTB,5
goto $-2
movlw '0'
call BYTE
return
TECLA_E btfsc PORTB,6
goto $-2
movlw 'E'
call BYTE
return
TECLA_D btfsc PORTB,7
goto $-2
movlw 'D'
call BYTE
return
end
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : mensage_18F_tblptr_4bit
; Funcion : visualizacion de un mensage en una LCD de 16caracteres 2 lineas.en el modo a 4bit.sin el sistema de direccionamiento indirecto
;
;
; Revision : 1.0 22/9/2011 Programa para : PIC18F2550
; CPU Clock : 48 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
;
LIST P=18F2550 ; Se emplea el PIC 18F2550
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P18F2550.INC"
CONFIG FOSC = HS ;Osc por XTAL 20mhz
CONFIG DEBUG = OFF
CONFIG PWRT = OFF
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
AUX0
AUX1
AUX2
TEMPLCD
PDel0
PDel1
TEMP_RS
FLAGS
DIR_EEPROM
TBLPTRL_TOP
TBLPTRH_TOP
CONT_CARACTER
RESUL
ENDC
PULSO MACRO ;PULSO EN TERMINAL E DE LA LCD
bsf PORTA,2
call RETARDO
bcf PORTA,2
ENDM
#define COMANDOS bcf PORTA,0 ;Desactiva RS (modo comando)
#define DATOS bsf PORTA,0 ;Activa RS (modo datos)
#define E EQU 2
#define RS EQU 0
#define READ bsf PORTA,1
#define WRITE bcf PORTA,1
#define ENABLE bsf PORTA,2 ;habilita LCD
#define DISABLE bcf PORTA,2 ;deshabilita LCD
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;ir a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES ALTA PRIORIDAD ---------------->>>>>>>>>>
;ORG 0X08
;goto INTERRUPCIONES
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES BAJA PRIORIDAD ---------------->>>>>>>>>>
;ORG 0X18
;goto INTERRUPCIONES
ORG 0X001C
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO
movlw b'00001000' ;permiso de la interrupción por cambio de estado del PORTB
movwf INTCON
clrf UCON,1
clrf FLAGS ;borra registro de banderas
movlw b'01110000' ;activa resistencias pull-up (evitar fallo lectura BUSY LCD)
movwf INTCON2
clrf PIE1,1 ; deshabilita interrupciones perifericas
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
PRINCIPAL
CALL LCD
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<INICIALIZA LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCD clrf LATA
movlw 0x0F
movwf ADCON1
movlw 0x07
movwf CMCON
clrf TRISA ; Puerta A como salidas digitales
bsf PORTA,3
clrf LATB
movlw 0x07
clrf TRISB
movlw 0x0f
movwf TRISB
clrf UCON,1
movlw b'10001000'
movwf T0CON
clrf TMR0L
clrf TMR0H
movlw 0XFF
movwf DIR_EEPROM ;carga la direccion
call LCDINI ;inicializa la LCD
call PRUEVAS ;salta a mensage de bienvenida
return
;************************************************************ PRUEVAS ******************************************************
PRUEVAS call BIENVENIDA
goto PRUEVAS
;************************************************** INICIALIZACION LCD *************************************************************
LCDINI COMANDOS ;selecciona el modo comando para la LCD
movlw 0X02 ;HOME. posicion 0 de la DD RAM.
call BYTE
movlw 0X28 ;FUNCTION SET. bus 4bit,LCD 2 linea.
call BYTE
movlw 0X0C ;DISPLAY ON/OFF. display on.
call BYTE
movlw 0X06 ;ENTRY MODE.incremento del cursor
call BYTE
movlw 0X01 ;CLEAR DISPLAY. borra display y activa incremento del cursor
call BYTE
return
;********************************************** ENVIO DE NIBLES A LA LCD ******************************************************
BYTE movwf TEMPLCD ;guarda el contenido de W en registro temporal TEMPLCD
call LCD_BUSY ;comprueva si el LCD esta libre
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
movf TEMPLCD,W ;carga el contenido de TEMPLCD en W
andlw 0xf0 ;seleccionar el nible alto de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
movlw 0x0f ;pon a 0 el nible alto de W
andwf PORTB,F ;borra el nible alto de portb sin tocar el nible bajo.
swapf TEMPLCD,W ;inbierte los nibles del registro TEMPLCD
andlw 0xf0 ;seleccionar el alto bajo de W
iorwf PORTB,F ;manda nible alto de W a PORTB.
PULSO ;pulso de 1ms en terminal E de la LCD
return ;retorna
LCD_BUSY call RETARDO ;retardo para evitar que la lectura del flag BUSY se quede bloqueado.
movf PORTA,W ;carga en W el contenido de PORTA
andlw 0x01 ;guarda el valor del estado del bit RS
movwf TEMP_RS ;salva el valor de RS en el registro temporal
COMANDOS ;selecciona el modo comandos
movlw H'FF' ;
movwf TRISB ;PORT B como entrada
READ ;Pone el LCD en Modo RD "lectura"
ENABLE ;Activa el LCD (lectura del nible alto)
L_BUSY btfsc PORTB,7 ;Chequea bit de Busy
goto L_BUSY ;espera a que la LCD este libre
DISABLE ;Desactiva LCD
ENABLE ;Activa el LCD (lectura del nible bajo)
call RETARDO ;retardo de 1ms
DISABLE ;Desactiva LCD
movlw 0X0F ;nible bajo como entradas
movwf TRISB
bsf INTCON2,RBPU ;deshabilita resistencias pull-up de PORTB
WRITE ;Pone LCD en modo WR
movf TEMP_RS,W ;restaura el valor de SR
iorwf PORTA,f ;activa en PORTA el bit RS
return ;retorna
;************************************************ RETARDO DE VELOCIDAD DE DESPLAZAMIENTO **********************************************************
pausa1 clrf AUX2
pausae3 clrf AUX1
pausae2 clrf AUX0
pausae incf AUX0,f
btfss AUX0,7 ;valor de temporizacion
goto pausae
incf AUX1,f
btfss AUX1,7 ;valor de temporizacion
goto pausae2
incf AUX2,f
btfss AUX2,3 ;velor de temporizacion
goto pausae3
return
;************************************************ RETARDO 1mS **********************************************************
RETARDO movlw .5;.67 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .5;.35 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 return ; 2+2 Fin.
;************************************************************MENSAGE DE BIENVENIDA******************************************************
BIENVENIDA clrf CONT_CARACTER ;incrementa registro contador de caracteres
clrf RESUL ;borra registro RESUL
movlw 0x00
movwf TBLPTRL ;direccion baja de principio de frase
movlw 0x02
movwf TBLPTRH ;direccion alta de principio de frase
movlw 0xfe
movwf TBLPTRL_TOP ;byte bajo de caracteres a enviar
movlw 0x7f
movwf TBLPTRH_TOP ;byte alto de caracteres a enviar
retorn DATOS ;selecciona modo de envio de datos
call TABLA ;salta a tabla de caraceres
btfsc FLAGS,0 ;comprueva si se ha llegado al ultimo caracter a leer
return ;si ha llegado.fin del programa
incf RESUL,F ;incrementa resul
movf TABLAT,W ;mete valor leido del byte bajo de tabla en W
call BYTE ;introduce caracter contenido en W a la ddram de la LCD.
movlw d'40' ;numero de caracteres de la ddram(primera fila)
subwf RESUL,W ;resta el valor contenido en W al registro RESUL.
btfss STATUS,C ;comprueva si se llego a meter los 40 caracteres en la ddram de la LCD
goto retorn ;si no ha llegado salta a retorn en caso contrario continua
REP COMANDOS ;selecciona modo de envio de comandos
movlw b'00011100' ;comando de rotacion a izquierdas
call BYTE ;envia comando
call pausa1 ;pausa de rotacion de la LCD
incf CONT_CARACTER,F ;incrementa el contador de caracteres
movlw .24 ;carga valor de desplazamientos hacia la izquierda para mostrar el mensage completo del a ddram.40-16=24 => 40 bytes - 16 caracteres visibles = 24 caracteres no visibles
xorwf CONT_CARACTER,w ;comprueva si se llego al valor anterior
btfss STATUS,Z ;si no ha llegado,sigue rotando
goto REP
movlw .32 ;numero de bytes visibles de la LCD (LCD 16x2)
subwf TBLPTRL,F ;desplaza el indice para grabar los 16 ultimos caracteres del primer mensage de la ddr,en los 16 primeros caracteres del siguiente mensage
btfss STATUS,C ;comprueva si al restar ha habido acarreo
decf TBLPTRH,f ;si lo ha habido decrementa TBLPTRH (inprescindible para detectar fin de frase)
clrf CONT_CARACTER ;borra contador de caracteres
clrf RESUL ;borra RESUL
COMANDOS ;selecciona el modo comando para la LCD
movlw 0X01 ;HOME. posicion 0 de la DD RAM.
call BYTE ;envia comando
goto retorn ;siguiente mensage
TABLA tblrd+* ;incrementa puntero de tabla antes de su lectura
tblrd+* ;incrementa puntero de tabla antes de su lectura
movf TBLPTRL,W ;carga en W el contenido de TBLPTRL
xorwf TBLPTRL_TOP,w ;compara el valor con el valor tope del byte bajo
btfss STATUS,Z ;si es diferente
return ;retorna
movf TBLPTRH,W ;carga en W el contenido de TBLPTRH
xorwf TBLPTRH_TOP,w ;compara el valor con el valor tope del byte alto
btfss STATUS,Z ;si es diferente
return ;retorna
bsf FLAGS,0 ;activa bit de fin de mensage
return ;retorna
org 0x200
dt " En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua,"
dt " rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lentejas los viernes, algún palomin"
dt "o de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas con sus pantufl"
dt "os de lo mismo, los días de entre semana se honraba con su vellori de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta, y una sobrina que no llegab"
dt "a a los veinte, y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años, era de c"
dt "omplexión recia, seco de carnes, enjuto de rostro; gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de Quijada o Quesada (que en esto hay"
dt " alguna diferencia en los autores que deste caso escriben), aunque por conjeturas verosímiles se deja entender que se llama Quijana; pero esto importa poco a nuest"
dt "ro cuento; basta que en la narración dél no se salga un punto de la verdad. Es, pues, de saber, que este sobredicho hidalgo, los ratos que estaba ocioso (que eran "
dt "los más del año) se daba a leer libros de caballerías con tanta afición y gusto, que olvidó casi de todo punto el ejercicio de la caza, y aun la administración de "
dt "su hacienda; y llegó a tanto su curiosidad y desatino en esto, que vendió muchas hanegas de tierra de sembradura, para comprar libros de caballerías en que leer; y"
dt " así llevó a su casa todos cuantos pudo haber dellos; y de todos ningunos le parecían tan bien como los que compuso el famoso Feliciano de Silva: porque la clarida"
dt "d de su prosa, y aquellas intrincadas razones suyas, le parecían de perlas; y más cuando llegaba a leer aquellos requiebros y cartas de desafío, donde en muchas pa"
dt "rtes hallaba escrito: la razón de la sinrazón que a mi razón se hace, de tal manera mi razón enflaquece, que con razón me quejo de la vuestra fermosura, y también "
dt "cuando leía: los altos cielos que de vuestra divinidad divinamente con las estrellas se fortifican, y os hacen merecedora del merecimiento que merecela vuestra gra"
dt "deza. Con estas y semejantes razones perdía el pobre caballero el juicio, y desvelábase por entenderlas, y desentrañarles el sentido, que no se lo sacara, ni las e"
dt " entendiera el mismo Aristóteles, si resucitara para sólo ello. No estaba muy bien con las heridas que don Belianis daba y recibía, porque se imaginaba quepor gran"
dt "des maestros que le hubiesen curado, no dejaría de tener el rostro y todo el cuerpo lleno de cicatrices y señales; pero con todo alababa en su autor aquel acabar s"
dt "u libro con la promesa de aquella inacabable aventura, y muchas veces le vino deseo de tomar la pluma, y darle fin al pie de la letra como allí se promete; y sin d"
dt "uda alguna lo hiciera, y aun saliera con ello, si otros mayores y continuos pensamientos no se lo estorbaran. Tuvo muchas veces competencia con el cura de su lugar"
dt " (que era hombre docto graduado en Sigüenza), sobre cuál había sido mejor caballero, Palmerín de Inglaterra o Amadís de Gaula; mas maese Nicolás, barbero del mismo"
dt " pueblo, decía que ninguno llegaba al caballero del Febo, y que si alguno se le podía comparar, era don Galaor, hermano de Amadís de Gaula, porque tenía muy acomod"
dt "ada condición para todo; que no era caballero melindroso, ni tan llorón como su hermano, y que en lo de la valentía no le iba en zaga. En resolución, él se enenfra"
dt "scó tanto en su lectura, que se le pasaban las noches leyendo de claro en claro, y los días de turbio en turbio, y así, del poco dormir y del mucho leer, se le sec"
dt "ó el cerebro, de manera que vino a perder el juicio. Llenósele la fantasía de todo aquello que leía en los libros, así de encantamientos, como de pendencias, batal"
dt "las, desafíos, heridas, requiebros, amores, tormentas y disparates imposibles, y asentósele de tal modo en la imaginación que era verdad toda aquella máquina de aq"
dt "uellas soñadas invenciones que leía, que para él no había otra historia más cierta en el mundo. Decía él, que el Cid Ruy Díaz había sido muy buen caballero; pero q"
dt "ue ver con el caballero de la ardiente espada, que de sólo un revés había partido por medio dos fieros y descomunales gigantes. Mejor estaba con Bernardo del Carpi"
dt "Carpio, porque en Roncesvalle había muerto a Roldán el encantado, valiéndose de la industria de Hércules, cuando ahogó a Anteo, el hijo de la Tierra, entre los bra"
dt "brazos. Decía mucho bien del gigante Morgante, porque con ser de aquella generación gigantesca, que todos son soberbios y descomedidos, él solo era afable y bien c"
dt "riado; pero sobre todos estaba bien con Reinaldos de Montalbán, y más cuando le veía salir de su castillo y robar cuantos topaba, y cuando en Allende robó aquel íd"
dt "olo de Mahoma, que era todo de oro, según dice su historia. Diera él, por dar una mano de coces al traidor de Galalón, al ama que tenía y aun a su sobrina de añadi"
dt "dura. En efecto, rematado ya su juicio, vino a dar en el más extraño pensamiento que jamás dio loco en el mundo, y fue que le pareció convenible y necesario, así p"
dt "ara el aumento de su honra, como para el servicio de su república, hacerse caballero andante, e irse por todo el mundo con sus armas y caballo a buscar las aventur"
dt "as, y a ejercitarse en todo aquello que él había leído, que los caballeros andantes se ejercitaban, deshaciendo todo género de agravio, y poniéndose en ocasiones y"
dt " peligros, donde acabándolos, cobrase eterno nombre y fama. Imaginábase el pobre ya coronado por el valor de su brazo por lo menos del imperio de Trapisonda: y así"
dt " con estos tan agradables pensamientos, llevado del estraño gusto que en ellos sentía, se dió priesa a poner en efecto lo que deseaba. Y lo primero que hizo, fue l"
dt "impiar unas arma"
org 0x2ff8
dt "s, que habían sido de sus bisabuelos, que, tomadas de orín y llenas de moho, luengos siglos había que estaban puestas y olvidadas en un rincón. Lim"
dt "piólas y aderezólas lo mejor que pudo; pero vió que tenían una gran falta, y era que no tenía celada de encajencaje, sino morrión simple; mas a esto suplió su indu"
dt "stria, porque de cartones hizo un modo de media celada, que encajada con el morrión, hacía una apariencia de celada entera. Es verdad que para probar si era fuerte"
dt ", y podía estar al riesgo de una cuchillada, sacó su espada, y le dió dos golpes, y con el primero y en un punto deshizo lo que había hecho en una semana: y no dej"
dt "ó de parecerle mal la facilidad con que la había hecho pedazos, y por asegurarse de este peligro, lo tornó a hacer de nuevo, poniéndole unas barras de hierro por d"
dt "e dentro de tal manera, que él quedó satisfecho de su fortaleza; y, sin querer hacer nueva experiencia de ella, la diputó y tuvo por celada finísima de encaje. Fue"
dt " luego a ver a su rocín, y aunque tenía más cuartos que un real, y más tachas que el caballo de Gonela, que tantum pellis, et ossa fuit, le pareció que ni el Bucéf"
dt "alo de Alejandro, ni Babieca el del Cid con él se igualaban. Cuatro días se le pasaron en imaginar qué nombre le podría: porque, según se decía él a sí mismo, no e"
dt "ra razón que caballo de caballero tan famoso, y tan bueno él por sí, estuviese sin nombre conocido; y así procuraba acomodársele, de manera que declarase quien hab"
dt "ía sido, antes que fuese de caballero andante, y lo que era entones: pues estaba muy puesto en razón, que mudando su señor estado, mudase él también el nombre; y l"
dt "e cobrase famoso y de estruendo, como convenía a la nueva orden y al nuevo ejercicio que ya profesaba: y así después de muchos nombres que formó, borró y quitó, añ"
dt "adió, deshizo y tornó a hacer en su memoria e imaginación, al fin le vino a llamar Rocinante, nombre a su parecer alto, sonoro y significativo de lo que había sido"
dt " cuando fue rocín, antes de lo que ahora era, que era antes y primero de todos los rocines del mundo. Puesto nombre y tan a su gusto a su caballo, quiso ponérsele "
dt "a sí mismo, y en este pensamiento, duró otros ocho días, y al cabo se vino a llamar don Quijote, de donde como queda dicho, tomaron ocasión los autores de esta tan"
dt " verdadera historia, que sin duda se debía llamar Quijada, y no Quesada como otros quisieron decir. Pero acordándose que el valeroso Amadís, no sólo se había conte"
dt "ntado con llamarse Amadís a secas, sino que añadió el nombre de su reino y patria, por hacerla famosa, y se llamó Amadís de Gaula, así quiso, como buen caballero, "
dt "añadir al suyo el nombre de la suya, y llamarse don Quijote de la Mancha, con que a su parecer declaraba muy al vivo su linaje y patria, y la honraba con tomar el "
dt "sobrenombre della. Limpias, pues, sus armas, hecho del morrión celada, puesto nombre a su rocín, y confirmándose a sí mismo, se dió a entender que no le faltaba ot"
dt "ra cosa, sino buscar una dama de quien enamorarse, porque el caballero andante sin amores, era árbol sin hojas y sin fruto, y cuerpo sin alma. Decíase él: si yo po"
dt "r malos de mis pecados, por por mi buena suerte, me encuentro por ahí con algún gigante, como de ordinario les acontece a los caballeros andantes, y le derribo de "
dt "un encuentro, o le parto por mitad del cuerpo, o finalmente, le venzo y le rindo, ¿no será bien tener a quién enviarle presentado, y que entre y se hinque de rodil"
dt "las ante mi dulce señora, y diga con voz humilde y rendida: yo señora, soy el gigante Caraculiambro, señor de la ínsula Malindrania, a quien venció en singular bat"
dt "alla el jamás como se debe alabado caballero D. Quijote de la Mancha, el cual me mandó que me presentase ante la vuestra merced, para que la vuestra grandeza dispo"
dt "nga de mí a su talante? ¡Oh, cómo se holgó nuestro buen caballero, cuando hubo hecho este discurso, y más cuando halló a quién dar nombre de su dama! Y fue, a lo q"
dt "ue se cree, que en un lugar cerca del suyo había una moza labradora de muy buen parecer, de quien él un tiempo anduvo enamorado, aunque según se entiende, ellajamá"
dt "s lo supo ni se dió cata de ello. Llamábase Aldonza Lorenzo, y a esta le pareció ser bien darle título de señora de sus pensamientos; y buscándole nombre que no de"
dt "sdijese mucho del suyo, y que tirase y se encaminase al de princesa y gran señora, vino a llamarla Dulcinea del Toboso, porque era natural del Toboso, nombre a su "
dt "parecer músico y peregrino y significativo, como todos los demás que a él y a sus cosas había puesto.Hechas, pues, estas prevenciones, no quiso aguardar más tiempo"
dt " a poner en efecto su pensamiento, apretándole a ello la falta que él pensaba que hacía en el mundo su tardanza, según eran los agravios que pensaba deshacer, tuer"
dt "tos que enderezar, sinrazones que enmendar, y abusos que mejorar, y deudas que satisfacer; y así, sin dar parte a persona alguna de su intención, y sin que nadie l"
dt "e viese, una mañana, antes del día (que era uno de los calurosos del mes de Julio), se armó de todas sus armas, subió sobre Rocinante, puesta su mal compuesta cela"
dt "da, embrazó su adarga, tomó su lanza, y por la puerta falsa de un corral, salió al campo con grandísimo contento y alborozo de ver con cuánta facilidad había dado "
dt "principio a su buen deseo. Mas apenas se vió en el campo, cuando le asaltó un pensamiento terrible, y tal, que por poco le hiciera dejar la comenzada empresa: y fu"
dt "e que le vino a la memoria que no era armado caballero, y que, conforme a la ley de caballería, ni podía ni debía tomar armas con ningún caballero; y puesto qeu lo"
dt " fuera, había de llevar armas blancas, como novel caballero, sin empresa en el escudo, hasta que por su esfuerzo la ganase.Estos pensamientos le hicieron titubear "
dt "en su propósito; mas pudiendo más su locura que otra razón alguna, propuso de hacerse armar caballero del primero que topase, a imitación de otros muchos que así l"
dt "o hicieron, según él había leído en los libros que tal le tenían. En lo de las armas blancas pensaba limpiarlas de manera, en teniendo lugar, que lo fuesen más que"
dt " un armiño: y con esto se quietó y prosiguió su camino, sin llevar otro que el que su caballo quería, creyendo que en aquello consistía la fuerza de las aventuras."
dt " Yendo, pues, caminando nuestro flamante aventurero, iba hablando consigo mismo, y diciendo: ¿Quién duda sino que en los venideros tiempos, ciando salga a luz la v"
dt "erdadera historia de mis famosos hechos, que el sabio que los escribiere, no ponga, cuando llegue a contar esta mi primera salida tan de mañana, de esta manera? Ap"
dt "enas había el rubicundo Apolo tendido por la faz de la ancha y espaciosa tierra las doradas hebras de sus hermosos cabellos, y apenas los pequeños y pintados pajar"
dt "illos con sus arpadas lenguas habían saludado con dulce y meliflua armonía la venida de la rosada aurora que dejando la blanda cama del celoso marido, por las puer"
dt "tas y balcones del manchego horizonte a los mortales se mostraba, cuando el famoso caballero D. Quijote de la Mancha, dejando las ociosas plumas, subió sobre su fa"
dt "moso caballo Rocinante, y comenzó a caminar por el antiguo y conocido campo de Montiel. (Y era la verdad que por él caminaba) y añadió diciendo: dichosa edad, y si"
dt "glodichoso aquel adonde saldrán a luz las famosas hazañas mías, dignas de entallarse en bronce, esculpirse en mármoles y esculpirse en mármoles y pintarse en tabla"
dt "s para memoria en lo futuro. ¡Oh tú, sabio encantador, quienquiera que seas, a quien ha de tocar el ser coronista de esta peregrina historia! Ruégote que no te olv"
dt "ides de mi buen Rocinante compañero eterno mío en todos mis caminos y carreras. Luego volvía diciendo, como si verdaderamente fuera enamorado: ¡Oh, princesa Dulcin"
dt "ea, señora de este cautivo corazón! Mucho agravio me habedes fecho en despedirme y reprocharme con el riguroso afincamiento de mandarme no parecer ante la vuestra "
dt "fermosura. Plégaos, señora, de membraros de este vuestro sujeto corazón, que tantas cuitas por vuestro amor padece. Con estos iba ensartando otros disparates, todo"
dt "s al modo de los que sus libros le habían enseñado, imitando en cuanto podía su lenguaje; y con esto caminaba tan despaico, y el sol entraba tan apriesa y con tant"
dt "o ardor, que fuera bastante a derretirle los sesos, si algunos tuviera. Casi todo aquel día caminó sin acontecerle cosa que de contar fuese, de lo cual se desesper"
dt "aba, poerque quisiera topar luego, con quien hacer experiencia del valor de su fuerte brazo.Autores hay que dicen que la primera aventura que le avino fue la de Pu"
dt "erto Lápice; otros dicen que la de los molinos de viento; pero lo que yo he podido averiguar en este caso, y lo que he hallado escrito en los anales de la Mancha, "
dt "es que él anduvo todo aquel día, y al anochecer, su rocín y él se hallaron cansados y muertos de hambre; y que mirando a todas partes, por ver si descubriría algún"
dt " castillo o alguna majada de pastores donde recogerse, y adonde pudiese remediar su mucha necesidad, vió no lejos del camino por donde iba una venta, que fucomo si"
dt " viera una estrella, que a los portales, si no a los alcázares de su redención, le encaminaba. Dióse priesa a caminar, y llegó a ella a tiempo que anochecía. Estab"
dt "an acaso a la puerta dos mujeres mozas, de estas que llaman del partido, las cuales iban a Sevilla con unos arrieros, que en la venta aquella noche acertaron a hac"
dt "er jornada; y como a nuestro aventurero todo cuanto pensaba, veía o imaginaba, le parecía ser hecho y pasar al modo de lo que había leído, luego que vió la venta s"
dt "e le representó que era un castillo con sus cuatro torres y chapiteles de luciente plata, sin faltarle su puente levadizo y honda cava, con todos aquellos adherent"
dt "es que semejantes castillos se pintan.Fuese llegando a la venta (que a él le parecía castillo), y a poco trecho de ella detuvo las riendas a Rocinante, esperando q"
dt "ue algún enano se pusiese entre las almenas a dar señal con alguna trompeta de que llegaba caballero al castillo; pero como vió que se tardaban, y que Rocinante se"
dt " daba priesa por llegar a la caballeriza, se llegó a la puerta de la venta, y vió a las dos distraídas mozas que allí estaban, que a él le parecieron dos hermosas "
dt "doncellas, o dos graciosas damas, que delante de la puerta del castillo se estaban solazando. En esto sucedió acaso que un porquero, que andaba recogiendo"
end CBLOCK 0X22
Scratchpad1
Scratchpad2
Scratchpad3
Scratchpad4
Scratchpad5
Scratchpad6
Scratchpad7
Scratchpad8
Scratchpad9
CRC
CONT
CONT2
INDEX
TEMP_CRC
FLAGS_DS18B20
ZONA_MEM
ENDC
#define POLY 0X8C ;polinomio invertido 0x131
#define CRC_OK bsf FLAGS_DS18B20,0
#define CRC_NOK bcf FLAGS_DS18B20,0
PRINCIPAL call GEN_CRC
btfsc FLAGS_DS18B20,0 ;comprueba si la trama tiene un crc correcto
call siguente programa ;si el crc es correcto continua el programa
goto PRINCIPAL
movlw Scratchpad1
movwf ZONA_MEM
movlw 0x08 ;0x08 para leer el Scratchpad y 0x07 para leer la ROM "identidad"
call GEN_CRC
;**************************************************** GEN_CRC **************************************************************
GEN_CRC movwf CONT2 ;carga en CONT2 la cantidad de bytes a generar
CRC_NOK ;borra el flag de coincidencia de crc
movlb 0x00 ;seleccion de banco
movlw 0X00 ;valor de direccion del banco 0 de la flash
movwf FSR1H ;selecciona el banco 0 de la eeprom de programa.
movlw Scratchpad1 ;principio de la zona de datos donde se ubica la trama a convertir
movwf FSR1L ;introduce el valor en la direccion a leer
movff INDF1,TEMP_CRC ;lee el valor
clrf INDEX ;limpia variable INDEX
PROX movf INDF1,W ;carga valor de la trama
xorwf INDEX,W ;operacion xor de W con INDEX
call CALC_CRC8 ;llamada a la rutina de calclo de CRC del byte leido
movwf INDEX ;introduce el CRC generado en INDEX
incf FSR1L,F ;siguiente direccion del byte a leer
decfsz CONT2,F ;decrementa el contador de bytes analizados
goto PROX ;siguente byte a leer
movf INDEX,W ;carga el crc calculado en W
xorwf Scratchpad9,W ;compara el crc recibido con el crc generado
btfsc STATUS,Z ;comprueba si son iguales
CRC_OK ;si son iguales activa flag
return ;return
;*************************************************** CALC_CRC8 *************************************************************
;Generacion del CRC
CALC_CRC8 movwf CRC ;carga en CRC el byte a generar
movlw .8 ;numero de bits a desplazar
movwf CONT ;contador de bits
NEXT_CRC bcf STATUS,C ;limpia el carry
rrcf CRC,F ;rota el registro hacia la derecha
movlw POLY ;carga en w el polinomio 0x131 invertido
btfsc STATUS,C ;comprueba el carry
xorwf CRC,F ;si ha habido acarreo hacer xor entre el polinomio y el registro CRC
decfsz CONT,F ;decrementa el contador de bits
goto NEXT_CRC ;siguente bit
movf CRC,W ;carga el CRC generado en el registro CRC
return ;retorna
;****************************************** GEN_CRC_TBL **************************************************
;Calculo del crc por el sistema de tabla
GEN_CRC_TBL movwf CONT2 ;carga en CONT2 la cantidad de bytes a generar
CRC_NOK ;borra el flag de coincidencia de crc
movlb 0x00 ;seleccion de banco
movlw 0X00 ;valor de direccion del banco 0 de la flash
movwf FSR1H ;selecciona el banco 0 de la eeprom de programa.
movlw Scratchpad1 ;principio de la zona de datos donde se ubica la trama a convertir
movwf FSR1L ;introduce el valor en la direccion a leer
movff INDF1,TEMP_CRC ;lee el valor
clrf INDEX ;limpia variable INDEX
PROX2 movf INDF1,W ;carga valor de la trama
xorwf INDEX,W ;operacion xor de W con INDEX
call CRC8 ;llamada a la rutina de calclo de CRC del byte leido
movwf INDEX ;introduce el CRC generado en INDEX
incf FSR1L,F ;siguiente direccion del byte a leer
decfsz CONT2,F ;decrementa el contador de bytes analizados
goto PROX2 ;siguente byte a leer
movf INDEX,W ;carga el crc calculado en W
xorwf Scratchpad9,W ;compara el crc recibido con el crc generado
btfsc STATUS,Z ;comprueba si son iguales
CRC_OK ;si son iguales activa flag
return ;return
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CRC8 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CRC8 movwf TBLPTRL ;
movlw 0X50
movwf TBLPTRH
bcf STATUS,C ;borra el carry
rlcf TBLPTRL,F ;multiplica por 2
bnc $+4 ;si ha habido acarreo,
incf TBLPTRH ;incrementa puntero alto de tabla
TABLA_CRC8 tblrd+* ;incrementa puntero de tabla despues de su lectura
tblrd+* ;incrementa puntero de tabla despues de su lectura
movf TABLAT,W
return
ORG 0X5002
dt .00, .94, .188, .226, .97, .63, .221, .131, .194, .156, .126, .32, .163, .253, .31, .65
dt .157, .195, .33, .127, .252, .162, .64, .30, .95, .1, .227, .189, .62, .96, .130, .220
dt .35, .125, .159, .193, .66, .28, .254, .160, .225, .191, .93, .3, .128, .222, .60, .98
dt .190, .224, .2, .92, .223, .129, .99, .61, .124, .34, .192, .158, .29, .67, .161, .255
dt .70, .24, .250, .164, .39, .121, .155, .197, .132, .218, .56, .102, .229, .187, .89,.7
dt .219, .133, .103, .57, .186, .228, .6, .88, .25, .71, .165, .251, .120, .38, .196, .154
dt .101, .59, .217, .135, .4, .90, .184, .230, .167, .249, .27, .69, .198, .152, .122, .36
dt .248, .166, .68, .26, .153, .199, .37, .123, .58, .100, .134, .216, .91, .5, .231, .185
dt .140, .210, .48, .110, .237, .179, .81, .15, .78, .16, .242, .172, .47, .113, .147, .205
dt .17, .79, .173, .243, .112, .46, .204, .146, .211, .141, .111, .49, .178, .236, .14, .80
dt .175, .241, .19, .77, .206, .144, .114, .44, .109, .51, .209, .143, .12, .82, .176, .238
dt .50, .108, .142, .208, .83, .13, .239, .177, .240, .174, .76, .18, .145, .207, .45, .115
dt .202, .148, .118, .40, .171, .245, .23, .73, .8, .86, .180, .234, .105, .55, .213, .139
dt .87, .9, .235, .181, .54, .104, .138, .212, .149, .203, .41, .119, .244, .170, .72, .22
dt .233, .183, .85, .11, .136, .214, .52, .106, .43, .117, .151, .201, .74, .20, .246, .168
dt .116, .42, .200, .150, .21, .75, .169, .247, .182, .232, .10, .84, .215, .137, .107, .53
;******************************************************** CLEAR_ALL **************************************************************
;borra toda la memoria
CLEAR_ALL movlw 0x0f ;valor limite de borrado FSR0H
lfsr FSR0,700h ;direcciona la ram
clr2 clrf INDF0 ;borra direccion direccionada
incfsz FSR0L ;siguiente direccion a borrar
goto clr2 ;salta a borrado de direccion
decf FSR0H,f ;decrementa direccionamiento alto
cpfseq FSR0H ;comprueba si se ha llegado al final del direccionamiento
goto clr2 ;si no ha llegado,continua borrando
return ;retorna si se a acabado el borrado
#define TABLA_CRCs 0x5000 ;direccion donde meter la tabla.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CRC8 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CRC8 movwf TBLPTRL ;carga indexado de la tabla
movlw HIGH TABLA_CRCs ;direccion alta de tabla
movwf TBLPTRH ;cargalo en registro
clrf WREG ;dato 0x00
xorwf TBLPTRL,w ;comprueba si el dato indexado es igual a 0x00
btfsc STATUS,Z ;si es asi,
goto TABLA_CRC8 ;salta a tabla para leer el primer valor "0"
bcf STATUS,C ;borra el carry
rlcf TBLPTRL,F ;multiplica por 2
bnc TABLA_CRC8 ;salta a tabla si el valor indexado esta en los primeros 256bytes.en caso contrario,
incf TBLPTRH ,f ;incrementa puntero alto de tabla
goto TABLA_CRC8 ;y salta a tabla en resto de bytes.
TABLA_CRC8 tblrd*+ ;incrementa puntero de tabla antes de su lectura
movf TABLAT,W ;carga el valor leido de la tabla en W
return ;retorna
;la tabla tiene 256 valores.pero en este pic ocupa 512bytes.ya que cada direccion ocupa 2bytes.y solo uno de ellos es valido.
ORG TABLA_CRCs
dt .00, .94, .188, .226, .97, .63, .221, .131, .194, .156, .126, .32, .163, .253, .31, .65
dt .157, .195, .33, .127, .252, .162, .64, .30, .95, .1, .227, .189, .62, .96, .130, .220
dt .35, .125, .159, .193, .66, .28, .254, .160, .225, .191, .93, .3, .128, .222, .60, .98
dt .190, .224, .2, .92, .223, .129, .99, .61, .124, .34, .192, .158, .29, .67, .161, .255
dt .70, .24, .250, .164, .39, .121, .155, .197, .132, .218, .56, .102, .229, .187, .89,.7
dt .219, .133, .103, .57, .186, .228, .6, .88, .25, .71, .165, .251, .120, .38, .196, .154
dt .101, .59, .217, .135, .4, .90, .184, .230, .167, .249, .27, .69, .198, .152, .122, .36
dt .248, .166, .68, .26, .153, .199, .37, .123, .58, .100, .134, .216, .91, .5, .231, .185
dt .140, .210, .48, .110, .237, .179, .81, .15, .78, .16, .242, .172, .47, .113, .147, .205
dt .17, .79, .173, .243, .112, .46, .204, .146, .211, .141, .111, .49, .178, .236, .14, .80
dt .175, .241, .19, .77, .206, .144, .114, .44, .109, .51, .209, .143, .12, .82, .176, .238
dt .50, .108, .142, .208, .83, .13, .239, .177, .240, .174, .76, .18, .145, .207, .45, .115
dt .202, .148, .118, .40, .171, .245, .23, .73, .8, .86, .180, .234, .105, .55, .213, .139
dt .87, .9, .235, .181, .54, .104, .138, .212, .149, .203, .41, .119, .244, .170, .72, .22
dt .233, .183, .85, .11, .136, .214, .52, .106, .43, .117, .151, .201, .74, .20, .246, .168
dt .116, .42, .200, .150, .21, .75, .169, .247, .182, .232, .10, .84, .215, .137, .107, .53
;Este programa devuelbe en el registro TEMP_TECLA ,el indice de la tecla pregrabada.
;la peculariedad de que este programa sea tan grande,es que tiene un sistema de comprovacion de errores,que al pulsar
;una tecla.se almazenan en memoria 10 valores de esa tecla y se coje el valor mas repetido.de esa forma se evita el que al
;pulsar un boton resistivo,no cojamos el valor mas aproximado al real de ese boton.y que nos falle la identificacion de esa tecla.
;el programa tarda en ejecutarse
;La memorizacion de teclas esta limitada a 16 para mas teclas modificar: (#define N_BYTES .16)
;pero habra que tener en cuenta un byte en la posicion 17 para el valor de numeros de teclas memorizadas
;La memorizacion se realiza pulsando el numero de teclas definido.en el caso de que las teclas sean inferiores a las definidas
;solo haria falta pulsar la primera tecla que se presiono para la finalizacion del aprendizaje.
;la primera tecla sera asignada con el valor .0 la siguiente .1 .2 .3 - etc y asi hasta que finalizemos.
;Para el borrado de teclas y reaprendizage,poner a masa la entrada analogica.
CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
TEMP_KEY
TEMP_KEY2
CONT_REG
CONT_COINC
CONT_ALMAC ;contador de las teclas almacenadas
PRIMR_TECL ;primera tecla plsada en el aprendizaje
FLAGS_KEY
N_KEYS ;numero de teclas aprendidas
TEMP_TECLA
ENDC
#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC
#define KEY_OK bsf FLAGS_KEY,0
#define KEY_NOK bcf FLAGS_KEY,0
#define KEY_OK2 bsf FLAGS_KEY,1
#define FIND_OFF bsf FLAGS_KEY,2
#define FLASH_OK bsf FLAGS_KEY,3
#define N_BYTES .16 ;numero de teclas a gestionar y direccion de la eeprom donde se metera el dato del numero de bytes guardados
BOTON_PULS setf PRIMR_TECL
setf TEMP_KEY2
btfsc FLAGS_KEY,3 ;comprueba si ha habido pregrabacion en la eeprom de datos
goto SEARCH ;si la ha habido salta a busqueda de tecla pulsada
bt2 clrf DIR_EEPROM
call ALMAC ;salta a almacenamiento de aprendizage de teclas pulsadas en la eeprom
btfss FLAGS_KEY,2 ;comprueba si se termino con el aprendizage del teclado
goto bt3
call EEP_RAM ;si es asi,traspasa los bytes de la eeprom a la ram
return
bt3 setf TEMP_KEY2 ;en caso contrario setea el registro
goto bt2 ;y sigue el aprendizage
;********************************************************** KEYB ***********************************************************************
;adquisicion de valor de tecla pulsada
KEYB call TECLA ;lee valor de tecla pulsada
btfss FLAGS_KEY,0 ;comprueba si se ha pulsado una tecla
return ;si no es si,retorna
movff TEMP_KEY,TEMP_KEY2 ;guarda valor de tecla pulsada
kb1 call TECLA ;lee valor de tecla pulsada
btfsc FLAGS_KEY,0 ;comprueba si se ha soltado la tecla
goto kb1 ;si no es asi,vuelbe a leer valor de tecla pulsada
return ;retorna
;************************************************************ TECLA ********************************************************************
;Lectura de la entrada analogica y transferencia de 10 valores a la ram
TECLA setf TEMP_KEY
movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H
REPE call DAT_AN ;lee dato analogico
call BORRA_TECL ;opcion a borrado de teclado
setf WREG ;valor 0xff.tecla sin pulsar
cpfseq TEMP_ANALOG ;compara con el valor analogico de tecla
goto tec1
KEY_NOK
return ;si el valor analogico de la teclaes 0xff repite busqueda analogica(VALOR DE TECLA SIN PULSAR)
tec1 movff TEMP_ANALOG,INDF0
incf FSR0L,F ;incrementa FSR
clrf WREG
cpfseq FSR0L
goto REPE ;si no se ha llegado al tope de la ram repite
; aqui leemos la ram y buscamos el dato mas repetido
; en esta rutina se cogen los valores almacenados entre las direcciones seleccionadas y se coge valor que tenga mas numeros repetidos.
BUSCA_REP movlw BANCO_GENERAL ;banco donde trabajaremos con los registros generales
movwf FSR2H ;selecciona bancos de direccionamiento indirecto
movwf FSR1H
movwf FSR0H
movlw INI_TABLA ;inicio de tabla ram donde estan los valores a comparar
movwf FSR0L ;selecciona indice de tabla
decf FSR0L,F ;decrementa una direccion para luego incrementarla
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR2L ;selecciona indice de tabla
decf FSR2L,F ;decrementa una direccion para luego incrementarla
movlw .11 ;bytes a comparar menos 1
movwf CONT_COINC ;contador de comparaciones
regsig2 dcfsnz CONT_COINC,F ;decrementa el contador de comparaciones
goto discrim ;si se ha terminado de comprobar las coincidencias salta a esta direccion
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR1L ;selecciona indice de tabla
incf FSR2L,F ;incrementa indice de tabla
decf FSR1L,F
movff INDF2,COMPARADOR ;introduce valor de la tabla en registro comparador
movlw .11 ;registros a comparar
movwf CONT_REG ;contador de registros a comparar
incf FSR0L,F ;incrementa indice de registros
regsig1 incf FSR1L,F ;incrementa indice de comparaciones
movf INDF1,W ;lee el registro indexado
dcfsnz CONT_REG,F ;decrementa contador de registros
goto regsig2 ;si se ha llegado al limite salta a lectura de siguiente registro
cpfseq COMPARADOR ;comprueba si w es igual a COMPARADOR
goto regsig1 ;siguiente comparacion
incf INDF0,F ;incrementa direccion seleccionada si hay coincidencia
goto regsig1 ;siguiente comparacion
;busca el valor mas alto
discrim movlw .9 ;cantidad de registros a comparar
movwf CONT_REG ;registro contador
movlw INI_TABLA ;inicio de tabla
movwf FSR0L ;direcciona tabla ram
movff INDF0,TEMP_KEY ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt TEMP_KEY ;comprueba si es mayor
movff INDF0,TEMP_KEY ;si es mayor introduce el valor en el registro prevalescente
decfsz CONT_REG,F ;decrementa contador de comprobaciones
goto dis1 ;siguiente comprovacion
;busca el valor mas alto de las coincidencias
movlw INI_TABLA ;carga inicio de tabla
movwf FSR0L
pre1 movf INDF0,W ;carga el valor direccionado en W
xorwf TEMP_KEY,W ;comparalo con el valor mas alto
btfsc STATUS,Z ;si se ha encontrado,
goto pre2 ;salta a pre2
incf FSR0L,F ;incrementa direccion
goto pre1 ;repite comparacion
pre2 movlw .10 ;valor de salto a tabla de valores
addwf FSR0L ;salta al valor
movff INDF0,TEMP_KEY ;introduce valor en W
KEY_OK
KEY_OK2
return ;retorna CON EL VALOR ANALOGICO DE LA TECLA PULSADA
;******************************************************* BORRA_TECL **********************************************************************
;Borrado de teclas para nuevo aprendizage "entrada analogica a masa para el borrado"
BORRA_TECL clrf WREG ;valor 0x00
cpfseq TEMP_ANALOG ;comprueba si la tecla pulsada esta a masa
return ;retorna en caso de que no este a masa
clrf DIR_EEPROM ;direccion 0x00 de la eeprom
setf DATO_EEPROM ;valor 0xff a grabar en la eeprom
call ESCRIBIR_DATO ;graba el dato
pop ;salir de todas las llamadas
pop
pop
pop
return ;retorna
;//////////////////////////////////(conversor A/D)////////////////////////////////////////////////////////////////////////////////////////////////
;///////////////busca el dato analogico introducido por el pin seleccionado/////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;Si queremos que funcionen todas las entradas analogicas.hay que habilitar las lineas deshabilitadas
DAT_AN bsf ADCON0,GO_DONE ;inicia la conversion
AD_GOIN btfsc ADCON0,GO_DONE ;comprueva si la conversion ha finalizado
goto AD_GOIN ;si la conversion ha finalizado continua
movf ADRESH,w ;carga dato analogico en el acumulador
movwf TEMP_ANALOG ;carga el dato de w en TEMP_ANALOG
;movf ADCON0,W
;movwf CANAL ;mete el contenido de ADCON0 en CANAL
;movf CONT_AD,W ;dato que se suma a ADCON0 para que a la siguiente lectura sea en el proximo canal de AD
;addwf ADCON0,F ;incrementa el canal analogico(AN0->AN4)
;movlw b'00100001';valor para usar AN5 -> b'00101001' ;valor del ultimo registro del conversor analogico
;xorwf ADCON0,w
;btfss STATUS,Z ;si llega a este valor
;return
;movlw 0x01 ;selecciona de nuevo el conversor AN0
;movwf ADCON0
return
;******************************************************** ALMAC *******************************************************************
;Aprendizaje del teclado.
ALMAC clrf FLAGS_KEY
call KEYB ;devuelve dato de tecla pulsada
movlw 0x02
cpfseq FLAGS_KEY
goto ALMAC
AL2 clrf WREG ;valor 0x00
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
movff TEMP_KEY2,PRIMR_TECL;almacena la primera tecla pulsada en PRIMR_TRCL.
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
goto al1
movf PRIMR_TECL,w ;comprueba si se ha vuelto a pulsar la primera tecla.
cpfseq TEMP_KEY2 ;si no se ha pulsado,-
goto al1 ;salta a al1
al3 movff DIR_EEPROM, N_KEYS ;guardar el numero de teclas aprendidas
movff N_KEYS,DATO_EEPROM ;pasalo a DATO_EEPROM
movlw N_BYTES ;direccion de la eeprom donde se metera el dato del numero de bytes guardados
movwf DIR_EEPROM ;carga direccion de la eeprom
call ESCRIBIR_DATO ;graba el dato
FIND_OFF ;finalizacion de la memorizacion de teclas
return ;retorna.fin del programa
al1 movff TEMP_KEY2,DATO_EEPROM;carga valor analogico de tecla pulsada en registro de dato eeprom
call ESCRIBIR_DATO ;graba el dato en la eeprom
incf DIR_EEPROM,F ;incrementa la direccion
movlw N_BYTES ;carga tope de bytes a grabar
cpfseq DIR_EEPROM ;comprueba si ha llegado al tope
goto ALMAC ;si no ha llegado salta a ALMAC para siguiente tecla
goto al3 ;en caso contrario salta a al3 para ultima grabacion de numero de bytes y finaliza.
;*************************************************** SEARCH *******************************************************************
;Compara entre tecla pulsada y los valores de tecla almacenados en la eeprom
SEARCH setf TEMP_TECLA
call KEYB ;lee valor de tecla
setf WREG ;valor para tecla sin pulsar
cpfseq TEMP_KEY2 ;comprueba si la tecla esta pulsada.
goto sr1 ;si esta pulsada salta a sr1
return ;en caso contrario.retorna
sr1 clrf DIR_EEPROM ;direccion 0 de la eeprom
sr3 call LEER_DATO ;lee el dato
cpfseq TEMP_KEY2 ;comparalo con la tecla pulsada
goto sr2 ;siguiente direccion a comparar
goto SELEC ;si se ha encontrado la tecla pulsada selecciona valor de tecla.
sr2 incf DIR_EEPROM,F ;increenta la direccion a leer de la eeprom
movf DIR_EEPROM,W ;introducela en el acumulador
cpfsgt N_KEYS ;si la tecla pulsada no esta memorizada,
return ;retorna
goto sr3 ;en caso contrario compara siguiente tecla
SELEC movff DIR_EEPROM,TEMP_TECLA ;almacena en TEMP_TECLA el valor de tecla pulsada.
return ;retorna
;******************************************************* COPM_FLASH *************************************************************
COMP_MEMO clrf FLAGS_KEY ;borra flags
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
call LEER_DATO ;lee el dato
setf WREG ;valor 0xFF
cpfseq TEMP_EEP ;comprueba si se ha grabado algo en la direccion 0x00
call EEP_RAM;FLASH_OK ;si se ha grabado algo activa flag de aprendizage
return ;retorna
;***************************************************** EEP_RAM *****************************************************************
;Traspaso de keys de la eeprom de datos a la ram
EEP_RAM btfsc FLAGS_KEY,2 ;comprueba si es primer reinicio del pic
goto eep2 ;si es el primero,salta a eep2.en caso contrario lee de la eeprom el valor de bytes almacenados
movlw N_BYTES ;direccion de numero de bytes a leer
movwf DIR_EEPROM ;carga la direccion
call LEER_DATO ;lee el dato almacenado en la eeprom
movff TEMP_EEP,N_KEYS ;carga el valor en numero de teclas pulsadas
eep2 lfsr 0,0X07EB ;principio de direccion donde se introduciran los datos leidos de la eeprom de datos
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
eep1 call LEER_DATO ;lee el dato
movff TEMP_EEP,INDF0 ;traspasa el dato ledo de la eeprom a la ram
decf FSR0L ;direccion anterior de la ram
incf DIR_EEPROM,f ;siguiente dato a leer de la eeprom
movf N_KEYS,w ;numero de bytes previamente almacenados
cpfseq DIR_EEPROM ;comprueba si se ha llegdo al final de la lectura
goto eep1 ;si no ha llegado.tarspasa siguente byte
FLASH_OK ;flag de datos grabados en flash
return ;retorna call COMP_MEMO ;comprueba si hay algun dato guardado en la direccion 0x00 de la eeprom de datos.y restablece valores de teclas pulsadas
;pr call BOTON_PULS ;deteccion de tecla pulsada
; setf WREG
; cpfseq TEMP_TECLA
; NOP
; goto pr;libreria para manejo de la eeprom
;//////////////////////////////////////////////ESCRIBIR DATO EN EEPROM///////////////////////////////////////////////////
ESCRIBIR_DATO ;clrwdt
GIE_OFF
;BANK0 ;selecciona banco 0
movf DIR_EEPROM,W ;temporal de direccion de la eeprom de datos
;BANK1 ;selecciona banco 1
movwf EEADR ;direccion a acceder
;BANK0 ;selecciona banco 0
movf DATO_EEPROM,W ;temporal de dato de la eeprom de datos
;BANK1 ;selecciona banco 1
movwf EEDATA ;dato a grabar
bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM
bsf EECON1,WREN ;habilita escritura
;GIE0
movlw 0X55 ;valores imprencindibles para la grabacion de datos en eeprom de datos
movwf EECON2 ;"
movlw 0XAA ;"
movwf EECON2 ;"
;GIE1
bsf EECON1,WR ;inicia escritura
btfsc EECON1,WR ;comprueva si se grabo el dato
goto $-2 ;si lo ha grabado continua.en caso contrario repite la comprobacion.
GIE_ON
bcf EECON1,WREN ;deshabilitar escritura en eeprom
movf EEADR,W;DIR_EEPROM ;carga el valor de DIR_EEPROM en W
call VERIFICA ;salta a subprograma de verificacion de la correcta grabacion en eeprom de datos
;GIE1
return ;retorna
VERIFICA call LEER_DATO ;salta a subprograma de lectura de dato de la eeprom de datos
movf TEMP_EEP,W ;carga el contenido de TEMP_EEP en W
xorwf DATO_EEPROM,W ;comprueva si es el dato se ha grabado correctamente
btfsc STATUS,Z
return ;si es correcto.retorna
call ESCRIBIR_DATO ;en caso contrario,vuelve a grabar el dato
return ;retorna
;///////////////////////////////////////////LEER DATO DE MEMORIA EEPROM ///////////////////////////////////////////////////////
LEER_DATO ;BANK1
bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM
movf DIR_EEPROM,W
movwf EEADR ;escribir direccion de memoria eeprom
bsf EECON1,RD ;ORDEN DE LECTURA
LEE btfsc EECON1,RD ;espera a que se realize la lectura del dato
goto LEE
movf EEDATA,W ;carga valor de eeprom en el registro W
;BANK0 ;selecciona banco 0
movwf TEMP_EEP ;carga el valor leido de eeprom de datos al registro TEMP_EEP
return ;retorna
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : DS1307_18f2550.asm
; Funcion : gestion del reloj DS1307
;
;
; Revision : 1.0 25/10/2016 Programa para : PIC18F2550
; CPU Clock : 48 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : HSPLL_HS
; Code Prot : OFF xtal :4Mhz
;************************************************* www.ingeniopic.com **************************************************
;
LIST P=18F2550 ; Se emplea el PIC 18F2550
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE "P18F2550.INC"
CONFIG PLLDIV =12
CONFIG USBDIV = 1
CONFIG CPUDIV = OSC1_PLL2
CONFIG FOSC = HSPLL_HS ;Osc por XTAL 4mhz
CONFIG DEBUG = OFF
CONFIG PWRT = OFF
CONFIG BOR = OFF
CONFIG WDT = OFF;ON
CONFIG WDTPS = 256
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG CCP2MX= OFF
ERRORLEVEL -302
;ZONA DE ETIQUETAS
CBLOCK 0X20
HI_W_TEMP
LO_W_TEMP
HI_STATUS_TEMP
LO_STATUS_TEMP
TEMP_FSR1L
TEMP_FSR2L
TEMP_FSR2L_LO
TEMP_FSR2H_LO
TEMP_FSR1L_LO
TEMP_FSR1H_LO
TEMP_FSR2L_HI
TEMP_FSR2H_HI
HI_TEMP_STATUS
LO_TEMP_STATUS
HI_TEMP_BSR
LO_TEMP_BSR
TEMP_PCL_HI
TEMP_PCL_LO
CONT_BYTE_RTC ;contador de numero de bytes
DIR_I2C ;principio de direccion de dispositivo
DATO_I2C
ENDC
RETARDOS_VAR EQU 0X00A ;variables de la libreria "retardos.inc" hubicados en una zona de memoria accedida desde todos los bancos
EEP_VAR EQU 0X220
HI_POP_REG MACRO ;restaura registros
MOVLB 0X00 ;asegura que este seleccionado el banco0
;MOVFF TEMP_BANK_HI,BSR
movff HI_STATUS_TEMP,STATUS
movff HI_TEMP_BSR,BSR
movf HI_W_TEMP,W
movff TEMP_FSR2H_LO,FSR2H
movff TEMP_FSR2L_LO,FSR2L
movff TEMP_FSR1H_LO,FSR1H
movff TEMP_FSR1L_LO,FSR1L
movff HI_TEMP_STATUS,STATUS
ENDM
HI_PUSH_REG MACRO ;salva registros
MOVLB 0X00 ;asegura que este seleccionado el banco0
movff STATUS,HI_STATUS_TEMP
movff BSR,HI_TEMP_BSR
movwf HI_W_TEMP
movff FSR2H,TEMP_FSR2H_LO
movff FSR2L,TEMP_FSR2L_LO
movff FSR1H,TEMP_FSR1H_LO
movff FSR1L,TEMP_FSR1L_LO
movff STATUS,HI_TEMP_STATUS
ENDM
LO_POP_REG MACRO ;restaura registros
MOVLB 0X07 ;asegura que este seleccionado el banco7
movff LO_STATUS_TEMP,STATUS
movf LO_W_TEMP,W
movff LO_TEMP_BSR,BSR
movff TEMP_FSR2H_HI,FSR2H
movff TEMP_FSR2L_HI,FSR2L
movff LO_TEMP_STATUS,STATUS
ENDM
LO_PUSH_REG MACRO ;salva registros
MOVLB 0X07 ;asegura que este seleccionado el banco7
movff STATUS,LO_STATUS_TEMP
movwf LO_W_TEMP
movff BSR,LO_TEMP_BSR
movff FSR2H,TEMP_FSR2H_HI
movff FSR2L,TEMP_FSR2L_HI
movff STATUS,LO_TEMP_STATUS
ENDM
;***************Bit Definitions****************************************
#define BANK0 movlb 0x00
#define BANK1 movlb 0x01
#define BANK2 movlb 0x02
#define BANK3 movlb 0x03
#define BANK4 movlb 0x04
#define BANK5 movlb 0x05
#define BANK6 movlb 0x06
#define BANK7 movlb 0x07
#define BANK8 movlb 0x08
#define BANK9 movlb 0x09
#define BANK10 movlb 0x0A
#define BANK11 movlb 0x0B
#define BANK12 movlb 0x0C
#define BANK13 movlb 0x0D
#define BANK14 movlb 0x0E
#define BANK15 movlb 0x0F
#define GIE_HI_ON bsf INTCON,7
#define GIE_HI_OFF bcf INTCON,7
#define GIE_LO_ON bsf INTCON,6
#define GIE_LO_OFF bcf INTCON,6
#define I2C_18F 0X0750 ;direccion donde hubicaremos las rutinas de temporizacion
#define retardos 0X0950 ;direccion donde hubicaremos las rutinas de temporizacion
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;ir a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES ALTA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X08
goto INTERRUP_HI
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES BAJA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X18
goto INTERRUP_LO
ORG 0X001C
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO BANK15
clrf UCON,1
movlw b'01110000' ;activa resistencias pull-up (evitar fallo lectura BUSY LCD)
movwf INTCON2
movlw b'11111110'
movwf LATA
movlw b'11111000'
movwf TRISA
movlw 0x0F
movwf ADCON1
movlw 0x07
movwf CMCON
clrf PORTB
clrf LATB
setf TRISB
movlw b'10000001' ;configura TMR0
movwf T0CON
bsf INTCON2,TMR0IP ;alta prioridad para tmr0
bcf INTCON2,RBIP ;baja prioridad para portb
clrf TMR0
bsf RCON,IPEN ;activa prioridad de interrupciones
movf PORTB,w ;leer puerto para el posterior borrad e flag RBIF
bcf INTCON,RBIF
bsf INTCON,RBIE
GIE_LO_OFF
GIE_HI_OFF
GIE_LO_OFF
GIE_HI_OFF
call DS1307_INI
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
;antes de ejecutar la linea ESCRIBE.hay que poner los datos a grabar en la direccion ox100.ejemplo:
;0x30,0x50,0x12,0x02,0x25,0x10,0x16 = segundos,minutos,hora,(martes),dia,mes,año
PRINCIPAL ;call ESCRIBE ;escribir en el DS1307
call LEE ;leer del DS1307
rep goto rep
goto PRINCIPAL
return
;escritura de datos al DS1307.los datos deben de introducirse a partir de la direccion 0x100
ESCRIBE lfsr FSR2,0X100 ;principio de ram donde se introduciran los datos leidos del dispositivo I2C
movlw 0x00 ;principio de direccion a leer
movwf DIR_I2C
movlw .7 ;nuemro de bytes a escribir
call WRITE_RTC
return
;lectura de datos del DS1307.los datos seran hubicados a partir de la direccion 0x100
LEE lfsr FSR2,0X100 ;principio de ram donde se introduciran los datos leidos del dispositivo I2C
movlw 0x00 ;principio de direccion a leer
movwf DIR_I2C
movlw .7 ;nuemro de bytes a leer
call READ_RTC
return
;fin del programa.
;<<<<<<<<-------------------COMPROBACION DE TIPO DE INTERRUPCION DE ALTA PRIORIDAD------------>>>>>>>>>>>>>>
INTERRUP_HI HI_POP_REG
HI_PUSH_REG
retfie ;retorna y habilita interrupciones generales
;<<<<<<<<-------------------COMPROBACION DE TIPO DE INTERRUPCION DE BAJA PRIORIDAD------------>>>>>>>>>>>>>>
;evento de temporizaciones.1s aproximadamente.para la activacion/desactivacion de salidas.
INTERRUP_LO LO_POP_REG
LO_PUSH_REG
retfie ;retorna y habilita interrupciones
DS1307_INI BANK15
bsf PIE1,SSPIE ;habilita interrupciones para la camara
;bsf ODCON1,7 ;habilita open drain para RC4, SDA1
bsf TRISB,0 ;configura pins como entrada
bsf TRISB,1 ;configura pins como entrada
movlw 0x28 ; I2C master, SSPEN enabled
movwf SSPCON1 ;
movlw 0x80 ; 400Khz compat,
movwf SSPSTAT
movlw .159 ; configurar I2C a 100kHz (para fosc de 64Mhz) clock=Fosc/(4*(SSPxADD+1))
;movlw .39 ; configurar I2C a 400kHz (para fosc de 64Mhz) clock=Fosc/(4*(SSPxADD+1))
movwf SSPADD
clrf PIR1
return
org retardos
include "retardos.inc"
org I2C_18F
include "I2C_18F.inc"
end
LIST
; CBLOCK I2C_VAR
; CONT_BYTE_RTC ;contador de numero de bytes
; DIR_I2C ;principio de direccion de dispositivo
; DATO_I2C
; ENDC
;-------------------------------------------------------------------------------------------;
; SUBRUTINAS DE I2C ;
;-------------------------------------------------------------------------------------------;
;Lectura de los datos internos del DS1307
READ_RTC movwf CONT_BYTE_RTC ;numero de bytes a leer
call Start_I2C ;Llama a la subrutina de START
rcall retardo_5us
movlw 0xd0 ;modo lectura del RTC
movwf SSPBUF ;Lo carga en el Buffer de salida
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
movff DIR_I2C,SSPBUF ;Lo carga en el Buffer de salida
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
call Restart_I2C ;Llama a la subrutina de RESTART
rcall retardo_5us
movlw 0xd1 ;modo escritura del RTC
movwf SSPBUF,0 ;Lo carga en el Buffer de salida
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
Bucle_Leer call Read_I2C ;Llama a la subrutina de lectura
movff SSPBUF,POSTINC2 ;Guarda el dato en la Ram e incrementa el puntero
rcall retardo_5us
decfsz CONT_BYTE_RTC,F ;repite hasta que sea cero
bra ACK ;envia ACK y continúa leyendo
call Send_I2C_NoAck ;llama a la subrutina de ACKNOWLEDGE
rcall retardo_5us
call Stop_I2C ;Llama a la subrutina de STOP
rcall retardo_5us
return ;Retorna de la subrutina
ACK call Send_I2C_Ack ;Llama a la subrutina de ACKNOWLEDGE
rcall retardo_5us
goto Bucle_Leer
;Escritura en el DS1307 antes de la llamada a esta rutina.cargar en FSR2 el inicio de la ram donde se leeran los datos a transferir al DS1307
; y en WREG la cantidad de datos a transferir.
WRITE_RTC movwf CONT_BYTE_RTC ;numero de bytes a escribir
call Start_I2C ;Llama a la subrutina de START
rcall retardo_5us
movlw 0xd0 ;modo escritura del RTC
movwf SSPBUF ;Lo carga en el Buffer de salida
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
movff DIR_I2C,SSPBUF ;Lo carga en el Buffer de salida
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
Bucle_Escribir1 movff POSTINC2,SSPBUF ;Carga el dato de la Ram en SSP1BUF e incrementa el puntero
call Write_I2C ;Llama a la subrutina de escritura
rcall retardo_5us
decfsz CONT_BYTE_RTC,F ;repite hasta que sea cero
bra Bucle_Escribir1 ;continúa enviando datos
call Stop_I2C ;Llama a la subrutina de STOP
rcall retardo_5us
return ;Retorna de la subrutina
;retardo de 5us
retardo_5us movlw .11
call retardo_us
return
;*********************************************************************************************************
i2c_idle btfsc SSPSTAT,R_W
goto i2c_idle
reps movf SSPCON2,w
andlw 0x1F
btfss STATUS,Z
goto reps
return
Start_I2C BANK15
bsf SSPCON2,SEN ;Pone a uno el bit de START
S2 btfsc SSPCON2,SEN ;Espera a que se ponga a cero el bit de START
bra S2
S3 btfss PIR1,SSPIF ;Espera a que la condicion de START haya sido completada
bra S3 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF ;Borra la bandera de la interrupción
return ;Retorna de la subrutina
Write_I2C btfsc SSPSTAT,R_W ;Verifica que se ponga a cero el bit R/W
bra Write_I2C ;Espera a que termine de enviar el dato
W2 btfsc SSPCON2,ACKSTAT ;Espera a que reciba el bit de ACKNOWLEDGE
bra W2
BCF PIR1,SSPIF ;borra la bandera de la interrupción
return ;Retorna de la subrutina
Restart_I2C bsf SSPCON2,RSEN ;Pone a uno el bit de RESTART
R2 btfsc SSPCON2,RSEN ;Espera a que se ponga a cero el bit de RESTART
bra R2
R3 BTFSS PIR1,SSPIF ;Espera a que la condicion de RESTART haya sido completada
bra R3 ;cuando se ponga a 1 la bandera de interrupción
bcf PIR1,SSPIF ;Borra la bandera de la interrupción
return ;Retorna de la subrutina
Read_I2C bsf SSPCON2,RCEN ;Habilita la recepción de datos mediante el bit RCEN
Rea2 btfsc SSPCON2,RCEN ;Espera a que se ponga a cero el bit RCEN
bra Rea2
Rea3 BTFSS SSPSTAT,BF ;Dato disponible en SSPBUF para ser leidos?
bra Rea3 ;No, esperar
Rea4 BTFSS PIR1,SSPIF ;Espera a que la condicion de Lectura haya sido completada
bra Rea4 ;cuando se ponga a 1 la bandera de interrupción
bcf PIR1,SSPIF ;Borra la bandera de la interrupción
return ;Retorna de la subrutina
Send_I2C_Ack bcf SSPCON2,ACKDT ;Pone a cero el bit de ACKNOWLEDGE DATA
bsf SSPCON2,ACKEN ;Genera la condición de ACKNOWLEDGE Poniendo a 1 el bit ACKEN
btfss PIR1,SSPIF ;Espera a que la condicion de ACK haya sido completada
bra Rea4 ;cuando se ponga a 1 la bandera de interrupción
bcf PIR1,SSPIF ;Borra la bandera de la interrupción
return ;Retorna de la subrutina
Send_I2C_NoAck bsf SSPCON2,ACKDT ;Pone a 1 el bit de ACKNOWLEDGE DATA
bsf SSPCON2,ACKEN ;Genera la condición de NO ACKNOWLEDGE Poniendo a 1 el bit ACKEN
btfss PIR1,SSPIF ;Espera a que la condicion de No ACK haya sido completada
bra Rea4 ;cuando se ponga a 1 la bandera de interrupción
bcf PIR1,SSPIF ;Borra la bandera de la interrupción
return ;Retorna de la subrutina
Stop_I2C bsf SSPCON2,PEN ;Genera la condición de STOP poniendo a 1 el bit PEN
P2 btfsc SSPCON2,PEN ;Espera a que se ponga a cero el bit PEN
bra P2
btfss PIR1,SSPIF ;Espera a que la condicion de Stop haya sido completada
bra Rea4 ;cuando se ponga a 1 la bandera de interrupción
bcf PIR1,SSPIF ;Borra la bandera de la interrupción
return
LIST
CBLOCK RETARDOS_VAR
PDel0
PDel1
PDel2
PDel5
PDel6
PDel7
ENDC
;************************************************************** RETARDO DE 1 SEGUNDO *****************************************************
retardo_s movwf PDel0 ; 1 |11000000 'À'
PLoop0 movlw .79 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .192 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
return ; 2+2 Fin.
retardo_ms movwf PDel5 ; 1 |
PLoop1a movlw .255 ; 1 set numero de repeticion (A)
movwf PDel6 ; 1 |
PLoop2a clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel6, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2a ; 2 no, loop
decfsz PDel5, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1a ; 2 no, loop
PDelL1a goto PDelL2a ; 2 ciclos delay
PDelL2a
return ; 2+2 Fin.
;
;;----------------------------------------------- RETARDOS EN MICROSEGUNDOS -----------------------------------------
retardo_us movwf PDel7 ; 1 |
PLoop0b clrwdt ; 1 clear watchdog
decfsz PDel7, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop0b ; 2 no, loop
PDelL1b goto PDelL2b ; 2 ciclos delay
PDelL2b clrwdt ; 1 ciclo delay
return ; 2+2 Fin.