Autor Tema: pic16f877A se resetea de forma inesperada  (Leído 2813 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cidtepole

  • PIC10
  • *
  • Mensajes: 5
pic16f877A se resetea de forma inesperada
« en: 26 de Mayo de 2009, 15:05:15 »
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
 

 

 

Desconectado sander

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 624
Re: pic16f877A se resetea de forma inesperada
« Respuesta #1 en: 27 de Mayo de 2009, 00:27:58 »
Saludos cidtepole, bienvenido al foro, por lo que comentas puede que  tengas un problema con las interrupciones, he revisado rapidamente el codigo y  note que cuando guardas y recuperas algunos registros en la interrupcion haces lo siguiente para el STATUS

Código: ASM
  1. movf    STATUS,W   ; Almacenar STATUS en W
  2.    movwf    tempStatus    ; Salvar STATUS
  3.  
  4. ;Al recuperar
  5.  movf    tempStatus,W    ; Recover STATUS
  6.    movwf    STATUS       ; Restore in register

El problema con la instruccion movf es que afecta a la bandera Z , por lo que existe el riesgo que guardes un valor incorrecto para la bandera Z, si te fijas haces comparaciones de la bandera Z en la rutina que marcaste con rojo, entonces al salir de la interrupcion estas comparaciones pueden estar dandote resultados erroneos. sustiye esa forma de guardar y recuperar por la siguiente:

Código: ASM
  1. swapf    STATUS,W   ; Almacenar STATUS en W
  2.    movwf    tempStatus    ; Salvar STATUS
  3.  
  4. ;Al recuperar
  5.  swapf    tempStatus,W    ; Recover STATUS
  6.    movwf    STATUS       ; Restore in register

La instruccion swapf no afecta banderas.

Saludos
La electrónica es el arte de manipular señales eléctricas que transportan información
Jan Davidse

Visita mi blog
Visita mi canal de youtube

Desconectado cidtepole

  • PIC10
  • *
  • Mensajes: 5
Re: pic16f877A se resetea de forma inesperada
« Respuesta #2 en: 27 de Mayo de 2009, 15:45:10 »
Gracias Sander por tu ayuda. Ya hice el cambio pero sigo con el mismo problema. Encontre tmb un error en mi codigo en una direccion y ya lo corregi; habia pensado ilusionado que eso era todo el problema pero no, sigo con lo mismo. El error estaba en las ultimas tres  lineas marcadas en rojo:

  bcf      tcpServerFlags,ejecutado
   bcf      tcpServerFlags,comando   
   return

en lugar de tcpServerFlags debi haber utilizado bcf tareasServer,comando, pero como te digo el problema persiste y aun no doy con la solucion.
Saludos y espero mas comentarios.

Desconectado cidtepole

  • PIC10
  • *
  • Mensajes: 5
Re: pic16f877A se resetea de forma inesperada
« Respuesta #3 en: 27 de Mayo de 2009, 20:18:27 »
Pues fijense que hice una aplicacion en C# donde simulo el modem y envio las respuestas a traves del puerto serie para el pic.
Y que creen que paso. :shock: el programa no se resetea y tmb corre a la perfeccion. No se porque con el moden se resetea en ese punto.