Hola a todos envio un cordial saludo esperando que se encuentren bien. Soy nuevo en el foro y desde hace unos dias he estado involucrado en un proyecto que consiste en el control de un modem para comunicacion TCP/IP. El modem se configura por puerto serial y el microcontrolador por medio del modulo USART es el encargado de hacer estas configuraciones para que se pueda establecer una conexion TCP.
El proyecto es simple consiste en que el pic actue como host del modem donde este ultimo se monta como servidor y se conecta a una red de area local permitiendo al microcontrolador la capacidad de enviar datos sobre una red. El modem permite una comunicacion transparente TCP por su puerto serial despues de que se hayan realizado las configuraciones necesarias.
Una aplicacion cliente en una computadora envia comandos al pic para ejecutar ciertas tareas(como apagar un foco).
Casi todo funciona excepto por algo raro que aun no le encuentro explicacion y es por eso que escribo en este foro.
Cuando yo envio un comando para apagar un foco lo hace bien. Si quiero que el modem suspenda la comunicacion y despues la vuelva a reiniciar lo hace bien. En el momento en que le mando un comando para que configure una nueva IP lo hace, pero aqui es donde surge el problema, ya que el pic de forma inesperada se resetea y mi aplicacion cliente ya no puede conectarse a la tarjeta modem del pic. Ya cheque el BROnw y esta en OFF, tambien el perro guardian esta en off. Ademas simulo el programa en PIC Simulator y corre a la perfeccion, tambien ya cheque el codigo y todo luce bien pero talvez yo ya este ciclado y no pueda dar con el error y es por eso que pido su ayuda y comentarios.
No quisiero perder la fe en los microcontroladores de microchip.
A continuacion muestro el codigo he indico en que parte se resetea al programa en letras de color rojo.
__CONFIG 0x1F39
LIST P=16F877A ;Se indica el modo de procesador
INCLUDE <P16f877A.inc> ;se incluye la definicion de los
;registros internos
INCLUDE <configuracion.inc>
;#DEFINE retardo_rapido
cblock 0x20
tcpStatus ;estado iniSocket ==>001
;estado cerrando Socket==>010
;estado ejecutando comando ==>011
tcpServerFlags
; 7 6 5 4 3 2 1 0 <= tcpServerFlags bits
; | | | | | | | |
; | | | | | | | |___bandera que indica el estado del Socket abierto o cerrado====>0,abierto
; | | | | | | |____bandera que indica si se ejecuto un comando=============>1,ejecutado
; | | | | | |_____bandera que indica si se recivio respuesta del modem=======>2,contesto
; | | | | |______ Waiting for data===================================>3,conectado
; | | | |________Estado de la corriente===============================>4,corriente
; | | |__________ ===============================>5,
; | |___________ ===============================>6,
; |____________ ===============================>7,
tareasServer
; 7 6 5 4 3 2 1 0 <= tareasServer bits
; | | | | | | | |
; | | | | | | | |___Ejecutar comando================================>0,comando
; | | | | | | |____Borrar buffer =================================>1,borrar
; | | | | | |_____Encender Rele 1 =================================>2,toglear
; | | | | |______ Encender Rele 2 =================================>3,
; | | | |________Encender Rele 3 ==================================>4,
; | | |__________ ==================================>5,
; | |___________ ==================================>6,
; |____________ ==================================>7,
; Variables para comunicacion
errorFlags
indiceTx
indiceRx
char
indiceCarga
indiceBufferRX
; Almacen temporal usado por el manejador de interrupcion
tempW
tempStatus
tempPclath
tempFsr
;Variable animacion
luces
distancia
cont_Ciclos
;Variables auxiliares
hold
toglearRele
endc
;=======================================
; Punteros de los Buffers
;=======================================
bufferRX equ 0xA0 ;Buffer de Recepcion de datos
bufferCMD equ 0x50 ;Buffer para almacenar un comando AT
bufferTemp equ 0x20 ;Buffer para almacenar comandos AT
abierto equ 0x00
ejecutado equ 0x01
contesto equ 0x02
conectado equ 0x03
corriente equ 0x04
comando equ 0x00
borrar equ 0x01
toglear equ 0x02
;**********************************************************************
; 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 ; Inicio en el Vector de Reset
goto ISR ; Va a la primera instruccion del
; programa
;**********************************************************************************************
; MAIN
;**********************************************************************************************
Inicio
iniUSART
banco1 ;Configuramos los puertos
clrf TRISB ;Puerto B como salida
movlw 0xB
movwf TRISA ;Puerto A pines A5-A0 salida A0,A1,A3
banco0
;////////////////////////////////////////////////////////////////////////////////////////
; Configuramos el ADC A0,A1,A3 como estradas
; analogicas A2,A4 y A5 como digital
;////////////////////////////////////////////////////////////////////////////////////////
bsf STATUS,RP0 ; Seleccionamos el Banco1 para configurar el ADC
movlw 0x84
movwf ADCON1 ;Configuramos el ADC
bcf STATUS,RP0 ; Seleccionamos el Banco0
movlw 0x41
movwf ADCON0
;////////////////////////////////////////////////////////////////////////////////////////
; Inicializamos variables
;////////////////////////////////////////////////////////////////////////////////////////
clrf indiceTx ;Inicializamos el indice para el posicionamiento de los caracteres que se envian
clrf indiceRx ;y reciven en RAM
clrf toglearRele
movlw 0x04 ;Inicializamos variable que indica el estado del Servidor (Default)
movwf tcpStatus
clrf tcpServerFlags
call animacion
clrf PORTB
;////////////////////////////////////////////////////////////////////////////////////////
; Iniciar modo escucha
;////////////////////////////////////////////////////////////////////////////////////////
openSocket ;Punto de inicio
call iniSocket
btfss tcpServerFlags,contesto
goto $-1
bcf tcpServerFlags,contesto
btfss tcpServerFlags,abierto
goto openSocket
movlw 0x02 ;Cambio al estado de posible cierre de Socket
movwf tcpStatus
;////////////////////////////////////////////////////////////////////////////////////////
; Ciclar y monitorear
;////////////////////////////////////////////////////////////////////////////////////////
loopMain
btfsc tareasServer,comando
call ejecutar
btfsc tareasServer,borrar
call clrBuffer
btfsc tareasServer,toglear
call toggle
call ReadA_D
btfsc tcpServerFlags,abierto ;Ciclar y checar si por algun motivo se cierra el socket
goto loopMain
goto openSocket
;**********************************************************************
; Interrupcion
;**********************************************************************
ISR
movwf tempW ; Salvar W
movf STATUS,W ; Almacenar STATUS en W
movwf tempStatus ; Salvar STATUS
movf PCLATH,W ; Almacenar PCLATH en W
movwf tempPclath ; Salvar PCLATH
clrf PCLATH ; Select program memory page 0
movf FSR,W ; Store FSR in W
movwf tempFsr ; Save FSR value
banco0
; Test for received data interrupt
btfsc PIR1,RCIF ; Test bit 5
bsf STATUS,RP0 ; Bank 1 if RCIF set
btfss PIE1,RCIE ; Test if interrupt is enabled
goto IntExit ; Go if not enabled
banco0
; Test for overrun and framing errors.
; Bit 1 (OERR) of the RCSTA register detects overrun
; Bit 2 (FERR) of the RCSTA register detects framing error
btfsc RCSTA,OERR ; Test for overrun error
goto OverErr ; Error handler
btfsc RCSTA,FERR ; Test for framing error
goto FrameErr ; Error handler
;////////////////////////////////////////////////////////////////////////////////////////
; En este punto no se detecto ningun error
; Received data is in the USART RCREG register
movf RCREG,w ; Recivo caracter y lo cargo en el registro de trabajo
call AddChar
;////////////////////////////////////////////////////////////////////////////////////////
; Clear error flags
clrf errorFlags
goto IntExit
OverErr ; Error responses to be made by main code
bsf errorFlags,0 ; Bit 0 is overrun error
; Reset system
bcf RCSTA,CREN ; Clear continuous receive bit
bsf RCSTA,CREN ; Set to re-enable reception
goto IntExit
FrameErr
bsf errorFlags,1 ; Bit 1 is framing error
movf RCREG,W ; Read and throw away bad data
;interrupt handler exit
IntExit
banco0
movf tempFsr,w ; Recupera valor del FSR
movwf FSR ; Restaurar en registro
movf tempPclath,w ; Recover PCLATH value
movwf PCLATH ; Restore in register
movf tempStatus,W ; Recover STATUS
movwf STATUS ; Restore in register
swapf tempW,F ; Swap file register in itself
swapf tempW,W ; Restore in register
retfie
;**********************************************************************
; Tablas
;**********************************************************************
tabla
ADDWF PCL,F ; se incrementa el contador de programa
DT "AT#LTCPSTART=1",0X0D,0X0A
tabla2
ADDWF PCL,F ; se incrementa el contador de programa
DT "Pulso recivido",0X0D,0X0A
tabla3
ADDWF PCL,F ; se incrementa el contador de programa
DT "Foco Encendido",0X0D,0X0A
tabla4
ADDWF PCL,F ; se incrementa el contador de programa
DT "CMD",0X0D,0X0A
tabla5
ADDWF PCL,F ; se incrementa el contador de programa
DT "Foco Apagado",0X0D,0X0A
eco
ADDWF PCL,F ; se incrementa el contador de programa
DT "eco",0X0D,0X0A
ATW
ADDWF PCL,F ; se incrementa el contador de programa
DT "AT&W",0X0D,0X0A
IPconfig
ADDWF PCL,F ; se incrementa el contador de programa
DT "AT#IPADDR=",0X22
GWconfig
ADDWF PCL,F ; se incrementa el contador de programa
DT "AT#IPGATEWAY=",0X22
NMconfig
ADDWF PCL,F ; se incrementa el contador de programa
DT "AT#IPNETMASK=",0X22
;**********************************************************************
; Agregar caracteres y programar tareas
;**********************************************************************
AddChar
movwf char
movlw 0x0D
xorwf char,W
btfsc STATUS,Z
goto CarrieReturn
movlw 'F'
xorwf char,W
btfsc STATUS,Z
goto ON_OFFRele
movlw 'R'
subwf char,W
btfsc STATUS,Z
goto CLR
movlw 'E'
xorwf char,W
btfsc STATUS,Z
goto E
movlw 'e'
xorwf char,W
btfsc STATUS,Z
goto ECO
movlw 'D'
xorwf char,W
btfsc STATUS,Z
goto CMD
movlw 'a'
xorwf char,W
btfsc STATUS,Z
goto WaitingFordata
agregar
movf indiceRx,W
addlw bufferRX ;Puntero del Buffer +indice
movwf FSR
movf char,W
movwf INDF ;Guardamos el caracter en el buffer
incf indiceRx,F
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; CARRY RETURN
;////////////////////////////////////////////////////////////////////////////////////////
CarrieReturn
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movf INDF,W ;Checo si el caracter es la letra K
xorlw 0x4B
btfss STATUS,Z
goto agregar
decf FSR,F ;Nos posicionamos en el caracter indice-1
movf INDF,W ;Checo si el caracter es la letra O
xorlw 0x4F
btfss STATUS,Z
goto agregar
movlw 0x01
xorwf tcpStatus,W ;Estoy en el estado de apertura de Socket
btfss STATUS,Z ;no voy al sigiente OK
goto OKclosed
bsf tcpServerFlags,abierto ;Si estoy en el estado de apertura
movlw 0x05 ;realizo las tareas necesarias
movwf PORTB ;indico que se puede establecer una conexion
bsf tcpServerFlags,contesto ;el modem si contesto
call clrBuffer ;Limpio el Buffer
goto fin
OKclosed
movlw 0x02
xorwf tcpStatus,W
btfss STATUS,Z ;Estoy en el estado de cierre de Socket
goto OKcomando
movlw 0x04
movwf PORTB
bcf tcpServerFlags,conectado
bcf tcpServerFlags,abierto
goto fin
OKcomando
movlw 0x03
xorwf tcpStatus,W
btfss STATUS,Z ;Estoy en el estado de ejecucion de comando
goto $+3
bsf tcpServerFlags,ejecutado
bsf tcpServerFlags,contesto
;call clrBuffer
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; ON_OFFRele
;////////////////////////////////////////////////////////////////////////////////////////
ON_OFFRele
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movlw 0x31 ;Checamos si llego un '1'
xorwf INDF,W
btfsc STATUS,Z
goto uno
movlw 0x32 ;Checamos si llego un '2'
xorwf INDF,W
btfsc STATUS,Z
goto dos
movlw 0x33 ;Checamos si llego un '3'
xorwf INDF,W
btfsc STATUS,Z
goto tres
goto agregar
uno
movlw 0x04
movwf toglearRele
bsf tareasServer,toglear
goto fin
dos
movlw 0x10
movwf toglearRele
bsf tareasServer,toglear
goto fin
tres
movlw 0x20
movwf toglearRele
bsf tareasServer,toglear
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; CLR
;////////////////////////////////////////////////////////////////////////////////////////
CLR
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movlw 'L'
xorwf INDF,W
btfss STATUS,Z
goto agregar
decf FSR,F ;Nos posicionamos en el caracter indice-2
movlw 'C'
xorwf INDF,W
btfss STATUS,Z
goto agregar
bsf tareasServer,borrar
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; ERROR
;////////////////////////////////////////////////////////////////////////////////////////
E
btfsc tcpServerFlags,abierto
goto agregar
bsf tareasServer,borrar
bsf tcpServerFlags,contesto
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; ECO
;////////////////////////////////////////////////////////////////////////////////////////
ECO
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movf INDF,W ;Checo si el caracter es la letra c
xorlw 0x63
btfss STATUS,Z
goto agregar
decf FSR,F ;Nos posicionamos en el caracter indice-1
movf INDF,W ;Checo si el caracter es la letra o
xorlw 0x6F ;
btfss STATUS,Z
goto agregar
clrf indiceTx
movf indiceTx,W
call eco ;Se carga el caracter que se va enviar
call SerialSend;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x05
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
call clrBuffer
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; WaitingFordata
;////////////////////////////////////////////////////////////////////////////////////////
WaitingFordata
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movf INDF,W ;Checo si el caracter es la letra c
xorlw 0x74
btfss STATUS,Z
goto agregar
decf FSR,F ;Nos posicionamos en el caracter indice-1
movf INDF,W ;Checo si el caracter es la letra o
xorlw 0x61 ;
btfss STATUS,Z
goto agregar
bsf tcpServerFlags,conectado
bsf tareasServer,borrar
goto fin
;////////////////////////////////////////////////////////////////////////////////////////
; CMD
;////////////////////////////////////////////////////////////////////////////////////////
CMD
movf indiceRx,W
addlw bufferRX-1;Puntero del Buffer +indice
movwf FSR
movlw 0x4D ;Checamos si llego una 'M'
xorwf INDF,W
btfss STATUS,Z
goto agregar
decf FSR,F ;Nos posicionamos en el caracter indice-2
movlw 0x43
xorwf INDF,W
btfss STATUS,Z
goto agregar
clrf indiceTx
movf indiceTx,W
call tabla4 ;Se carga el caracter que se va enviar
call SerialSend;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x05
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
movlw 0x02 ;me cambio al estado de cerrando socket
movwf tcpStatus
bsf tareasServer,comando
fin
return
;**********************************************************************
; Abrir Socket
;**********************************************************************
iniSocket
movlw 0x01 ;Cambio al estado de apertura
movwf tcpStatus
clrf indiceTx
movf indiceTx,W
call tabla ;Se carga el caracter que se va enviar
call SerialSend ;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x0F
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
return
;**********************************************************************
; Transmitir Datos
;**********************************************************************
SerialSend
banco0 ; Select bank 0
btfss PIR1,TXIF; Checar si el transmisor esta ocupado
goto $-1 ; esperar hasta que se desocupe
movwf TXREG ; y despues transmitir el dato
return
;**********************************************************************
; Imprime mensaje en el puerto serie
;**********************************************************************
printF
clrf indiceTx
movf indiceTx,W
call tabla2 ;Se carga el caracter que se va enviar
call SerialSend;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x10
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
return
;**********************************************************************
; Cambiar el estado de los reles
;**********************************************************************
toggle
btfsc toglearRele,2
call puertob1
btfsc toglearRele,4
call puertob2
btfsc toglearRele,5
call puertob3
movwf PORTB
movf toglearRele,W
xorwf PORTA,F
call printF
call clrBuffer
bcf tareasServer,toglear
return
;**********************************************************************
; puertob1
;**********************************************************************
puertob1
movlw '1'
movwf PORTB
return
;**********************************************************************
; puertob2
;**********************************************************************
puertob2
movlw '2'
movwf PORTB
return
;**********************************************************************
; puertob3
;**********************************************************************
puertob3
movlw '3'
movwf PORTB
return
;**********************************************************************
; Borrar Buffer
;**********************************************************************
clrBuffer
movlw bufferRX ; Start of RAM buffer
movwf FSR ; Load indirect register
loopBorrar
clrf INDF ; Zero out the buffer
incf FSR,F ; Increment to next byte
movlw 0xD2 ; bufferRX+50
xorwf FSR,W
btfss STATUS,Z
goto loopBorrar
clrf indiceRx
bcf tareasServer,borrar
return
;**********************************************************************
; Ejecutar Comandos
;**********************************************************************
ejecutar
movlw 0x0A
movwf PORTB
btfsc tcpServerFlags,abierto ; Antes de ejecutar los comandos para configurar la IP, GATEWAY y NETMASK
goto $-1 ; aseguramos que el Socket se cierre o se desconecte el cliente
movlw 0x03 ; Me cambio al estado de ejecutando
movwf tcpStatus
;////////////////////////////////////////////////////////////////////////////////////////
; Formamos el comando a partir de los caractes en la
; tabla IPconfig y los datos que llegaron en el buffer de
; recepcion(bufferRX)
;////////////////////////////////////////////////////////////////////////////////////////
clrf indiceCarga
clrf indiceBufferRX
; movlw bufferCMD ; Apuntamos a la primera posicion del Buffer donde se va alojar la instruccion
; movwf FSR ; que se va a ejecutar
;cicloLoadCMD1
; movf indiceCarga,W ; Cargamos el n-esimo caracter en el registro W
; call IPconfig
; movwf INDF ; W==>bufferCMD
; xorlw 0x22
; btfsc STATUS,Z ; Si el caracter son comillas pasar al siguiente ciclo
; goto cicloLoad2
; incf FSR,F ; bufferCMD++
; incf indiceCarga,F ; indiceCarga++
; goto cicloLoadCMD1
cicloLoad2
;incf indiceCarga,F ; indiceCarga++
movlw bufferRX
addwf indiceBufferRX,W ; bufferRX+indiceBufferRX
movwf FSR ; Apuntamos a bufferRX+indiceBufferRX
movf INDF,W ; Lo que hay en bufferRX+indiceBufferRX lo cargo al regitro de trabajo
movwf hold ; y lo paso a hold
movlw 'X'
xorwf hold,W
btfsc STATUS,Z ; Checo si en hold se cargo 'X' y si es asi cargo el resto de los caracteres
goto loadRest ; a bufferCMD si no, sigo copiando los caracteres al buffer de envio
movlw bufferCMD
addwf indiceCarga,W
movwf FSR ; Apuntamos a bufferCMD+indiceCarga
movf hold,W
movwf INDF ; hold==>bufferCMD+indiceCarga
incf indiceBufferRX,F
incf indiceCarga,F ; indiceCarga++
goto cicloLoad2
loadRest
movlw bufferCMD
addwf indiceCarga,W
movwf FSR ; Load indirect register
;movlw 0x22
;movwf INDF
;incf FSR,F
movlw 0x0D
movwf INDF
incf FSR,F
movlw 0x0A
movwf INDF
incf FSR,F
movlw 'X'
movwf INDF
enviarCMD
movlw bufferCMD ; Start of RAM buffer
movwf FSR ; Load indirect register
cicloEnvio
movf INDF,W
call SerialSend
incf FSR,F ; Increment to next byte
movf INDF,W
xorlw 'X'
btfss STATUS,Z
goto cicloEnvio
btfss tcpServerFlags,contesto
goto $-1
bcf tcpServerFlags,contesto
btfss tcpServerFlags,ejecutado
goto enviarCMD
bcf tcpServerFlags,ejecutado
bcf tcpServerFlags,comando
guardar
clrf indiceTx
movf indiceTx,W
call ATW ;Se carga el caracter que se va enviar
call SerialSend;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x06
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
btfss tcpServerFlags,contesto
goto $-1
bcf tcpServerFlags,contesto
btfss tcpServerFlags,ejecutado
goto guardar
bcf tcpServerFlags,ejecutado
bcf tcpServerFlags,comando
return
;**********************************************************************
; Read A/D
;**********************************************************************
ReadA_D
bsf ADCON0,GO ;Se inicia una lectura
nop
nop
nop
btfsc ADCON0,GO
goto $-1
btfss tcpServerFlags,conectado
goto salir_read
btfsc tcpServerFlags,corriente ;Checamos el estado apagado(0)/encendido(1)
goto encendido
goto apagado
apagado ;Se inicia en el estado de foco apagado
btfsc ADRESH,1; ;Si el bit 1 de ADRESH es '1' indica que el dato del ADC es mayor a 2V
goto mensaje_on ;y se envia un mensaje
btfss ADRESH,0; ;Si el bit 0 de ADRESH es '0' indica que el dato del ADC es menor a 2V
goto salir_read ;por lo tanto no se cambia de estado y se sale de la rutina
movlw 0x9A ;Se carga al registro de trabajo con el valor 154
banco1
subwf ADRESL,W ; ;154-ADRESL==>W
banco0
btfsc STATUS,C ;Si fue negativo el resultado C=1 y por lo tanto 154<ADRESL
goto mensaje_on ;y si 154<ADRESL el valor del ADC es mayor a 2V
goto salir_read
encendido
btfsc ADRESH,1;
goto salir_read
btfss ADRESH,0;
goto mensaje_off
movlw 0x9A ;154
banco1
subwf ADRESL,W ;
banco0
btfss STATUS,C
goto mensaje_off
bcf STATUS,C
goto salir_read
mensaje_on
bcf STATUS,C
bsf tcpServerFlags,corriente
clrf indiceTx
movf indiceTx,W
call tabla3 ;Se carga el caracter que se va enviar
call SerialSend ;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x10
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
goto salir_read
mensaje_off
bcf tcpServerFlags,corriente
clrf indiceTx
movf indiceTx,W
call tabla5 ;Se carga el caracter que se va enviar
call SerialSend ;Se envia el caracter
incf indiceTx,F ;Se incrementa el indice del siguiente caracter que va hacer enviado
movlw 0x0E
xorwf indiceTx,W
btfss STATUS,Z
goto $-7
salir_read
return
;**********************************************************************
; Animacion
;**********************************************************************
animacion
clrf cont_Ciclos
movlw 0x7
movwf luces
Bucle_animacion
clrf distancia
movf luces,W
movwf PORTB
rlf luces,F
#ifdef retardo_rapido
call Retardo_50micros
#else
call Retardo_100ms
#endif
incf distancia,F
movlw 0x05
xorwf distancia,W
btfss STATUS,Z
goto $-8
clrf distancia
movf luces,W
movwf PORTB
rrf luces,F
#ifdef retardo_rapido
call Retardo_50micros
#else
call Retardo_100ms
#endif
incf distancia,F
movlw 0x05
xorwf distancia,W
btfss STATUS,Z
goto $-8
incf cont_Ciclos,F
movlw 0x05
xorwf cont_Ciclos,W
btfss STATUS,Z
goto Bucle_animacion
return
INCLUDE <Retardos.inc>
END