Autor Tema: Problema con TImers en PIC18F452  (Leído 1610 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado rone17

  • PIC10
  • *
  • Mensajes: 6
Problema con TImers en PIC18F452
« en: 03 de Noviembre de 2017, 15:44:54 »
Acudo ante ustedes para solicitar su ayuda acerca de este pic 18f452, estoy intentando usar el TIMER0 y el TIMER1 como contadores independientes que detecten un flanco de bajo a alto, con ellos quiero crear dos variables de 32 bits, el problema es que el pic se esta reseteando cuando dejo contando con cualquiera de los 2 contadores, al paso de un tiempo se resetea el equipo, y me manda el tipo de reseto, MCLR_FROM_RUN, no se como quitar este error y evitar que se este reseteando el pic agradezco su ayuda de ante mano,  mi codigo es el siguiente.

Leyendo el datasheet se puede resetear por sobreflujo, pero  utilizando el fuse ,NOSTVREN, se quita este reseteo ahora lo que no entiendo, por eso puse al inicio del programa que tipo de reseteo se genera es el tipo de reseteo que se esta generando que es MCLR_FROM_RUN, que se da cuando se oprime el boton de reset en el pin 1 del pic.

ahora dejo el programa sin hacer nada sin mandar pulsos en los contadores y no se reseta el pic, al momento de comenzar a mandar pulsos a los contadores despues de un rato me manda el reseteo no se que estoy haciendo mal agradeceria mucho su ayuda



#include <18F452.h>
#device ADC=10
#include <stdlib.h>
#fuses HS
#fuses NOPROTECT
#fuses OSCSEN
#fuses NOBROWNOUT
#fuses NOWDT
#fuses NOPUT
#fuses NOSTVREN
#fuses NODEBUG
#fuses NOLVP
#fuses NOWRT
#fuses NOWRTD
#fuses NOWRTB
#fuses NOWRTC
#fuses NOCPD
#fuses NOCPB
#fuses NOEBTR
#fuses NOEBTRB

#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, RCV=PIN_C7)
//--------------------------------------------
#byte T0CON = 0xFD5
 //Definicion de Constantes
  #define NUM_PULSES_0 0x00
  #define NUM_PULSES_1 0x0000

  //Variables Globales
//  static long CntRight=0,CntLeft=0;
//  int32 gasometro=0,odometro;
//    int16  gas1=0,gas2=0;
    int8   g4=0,g3=0,g2=0,g1=0;
    int16  odo1=0,odo2=0;
    int32  gasometro=0,odometro=0;
  //Esta interrupcion es llamada en forma automatica por el TIMER0 cuando se desborda(0xFF).
 
   #INT_TIMER0
   void timer0(){
   g3++;                     //EN ESTA FUNCION TRANFORMAMOS EL CONTADOR DE 8 BITS A UN CONTADOR DE 32 BITS
//--------------------
    if(g3==0){               //CON LA AYUDA DE 4 VARIABLES DE 8 BITS
       g2++;
        if(g2==0){
           g1++;
        }
    }
//--------------------

  gasometro=make32(g1,g2,g3,g4);     //FUNCION make32 CONVIERTE 4 VARIABLES DE 8 BITS A UNA DE 32 BITS Y LA ASIGNA A LA VARIABLE1
//   gasometro++;
   printf("\n\rSOBREFLUJO TIMER0 gasometro:%lu ",gasometro);
   set_timer0(NUM_PULSES_0);
   }

   //Esta interrupcion es llamada en forma automatica por el TIMER1 cuando se desborda(0xFFFF).
   #INT_TIMER1
   void wave_timer1(){
   odo1++;                            //EN ESTA FUNCION TRANFORMAMOS EL CONTADOR DE 16 BITS A UN CONTADOR DE 32 BITS
   odometro=make32(odo1,odo2);       //FUNCION make32 CONVIERTE 2 VARIABLES DE 16 BITS A UNA DE 32 BITS Y LA ASIGNA A LA VARIABLE2   
   printf("\n\rSOBREFLUJO TIMER1 odometro:%lu ",odometro);
   set_timer1(NUM_PULSES_1);
   }

    //Inicializa interrupciones
void inicializa_interrupciones(){
    set_timer1(NUM_PULSES_1);                  //inicializamos el valor con el que inicia el contador del Timer1
    setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);    //configuramos el Timer1 como contador y preescalador de 1.
    enable_interrupts(INT_TIMER1);             //Habilitamos la interrupcion para cuando se desborde el Timer1
   
    set_timer0(NUM_PULSES_0);                  //Inicializamos el valor con el que inicia el contador del Timer0
    setup_timer_0(RTCC_INTERNAL|RTCC_EXT_L_TO_H|RTCC_8_BIT|RTCC_DIV_1);
    enable_interrupts(INT_TIMER0);             //Habilitamos la interrupcion para cuando se desborda el Timer0
    enable_interrupts(GLOBAL);                 //Habilitamos las interrupciones del Pic si no no servirian las interrupcciones de los Timers
    }

  void main(){
  ////
switch ( restart_cause() ) {

   case WDT_TIMEOUT:
                    printf("\n\rWDT_TIMEOUT");
                    break;

   case MCLR_FROM_SLEEP:
                   printf("\n\rMCLR_FROM_SLEEP");
                   break;
   case MCLR_FROM_RUN:
                    printf("\n\rMCLR_FROM_RUN");
                    break;

   case NORMAL_POWER_UP:
                    printf("\n\rNORMAL_POWER_UP");
                    break;
   case BROWNOUT_RESTART:
                    printf("\n\rBROWNOUT_RESTART");
                    break;
         
   case WDT_FROM_SLEEP:
                    printf("\n\rWDT_FROM_SLEEP");
                    break;

   case RESET_INSTRUCTION:
                    printf("\n\rRESET_INSTRUCTION");
                    break;
   default:    break;                 

}

//////////////////////////////////////////////////

  inicializa_interrupciones();
 
  while(1){
  g4=get_timer0();                             //Leemos el contenido del contador del Timer0
  gasometro=make32(g1,g2,g3,g4);     //FUNCION make32 CONVIERTE 4 VARIABLES DE 8 BITS A UNA DE 32 BITS Y LA ASIGNA A LA VARIABLE1
  odo2=get_timer1();                             //Leemos el contenido del contador del Timer1
  odometro=make32(odo1,odo2);
   
  }
  }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con TImers en PIC18F452
« Respuesta #1 en: 03 de Noviembre de 2017, 16:37:12 »
Primero que nada no crees mas de 1 mensaje con lo mismo.

Segun el codigo parece ser que el reset provino desde el pin del MCLR. esta bien conectada la resistencia al pin ese ?

Desconectado rone17

  • PIC10
  • *
  • Mensajes: 6
Re:Problema con TImers en PIC18F452
« Respuesta #2 en: 04 de Noviembre de 2017, 01:31:47 »
Si tengo conectado un boton al MCLR, y funciona correctamente
Si fuera falla dentro del hardware se reiniciaria aun si el programa no le mandara pulsos, pero no se reinicia, el reinicio se hace cuando mando pulsos y el programa comienza a mostrar los mensajes de desborde, pero al cabo e un tiempo se reinicia y el contador se regresa a cero por que las variables e reinician     

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con TImers en PIC18F452
« Respuesta #3 en: 04 de Noviembre de 2017, 09:20:31 »
Un boton solo? Y la resistencia + capcitor estan?

Acerca de tu programa:

- Porque usar 4 variables de 8bits y no directamente una de 32?, veo que lo hiciste antes asi por los comentarios.
- Nunca uses un printf dentro de una interrupcion!
- gasometro esta siendo modificado en ambos lados, tanto en la interrupcion como en el programa principal, siendo gasometro una variable de 32 bits, estas pidiendo que ocurra un problema. Imaginate que a mitad del "make32" ocurre una interrupcion y vos haces otro make32 sobre la misma variable, cuando vuelva va a continuar donde lo dejo.
- No se cual es tu urgencia de obtener los ultimos valores del timer, si cuando entre a la interrupcion (es decir paso a 0 el timer) vas a enviar los resultados.
« Última modificación: 04 de Noviembre de 2017, 11:30:40 por KILLERJC »

Desconectado rone17

  • PIC10
  • *
  • Mensajes: 6
Re:Problema con TImers en PIC18F452
« Respuesta #4 en: 04 de Noviembre de 2017, 12:12:30 »
Si tengo un capacitor y una resistencia en el boton, el printf es solo informativo para saber cuando ocurre la interrupcion, estoy deacuerdo que en el programa principal si hago lo siguiente deberia de funcionar sin depender de las 4 variables o de 2 variables de 16 bits directamente una varible de 32 bits como en el siguiente ejemplo cada que ocurra la interrupcion se incrementa en una la variable, ahora este codigo funciona bien en un pic 16f887 u 16f877a, en la misma tarjeta donde coloco el pic, el problema es que esto es solo el inicio de lo que estoy generando mi programa completo es mucho mas grande y no cabe en los pic 16f, por eso cambie a uno 18f

como estaba en un principio viendo que los contadores funcionaran bien es decir si realmente contaran hasta donde deberian contar es decir con una variable de 32 bits 4294967295, surge el problema del reinicio y es con los dos contadores con cualquiera, tengo alambrado un 555 para mandar pulsos, lo dejo en los contadores y se reinicia, en el siguiente cogido que te dejo

#include <18F452.h>
#device ADC=10
#include <stdlib.h>
#fuses HS
#fuses NOPROTECT
#fuses OSCSEN
#fuses NOBROWNOUT
#fuses NOWDT
#fuses NOPUT
#fuses NOSTVREN
#fuses NODEBUG
#fuses NOLVP
#fuses NOWRT
#fuses NOWRTD
#fuses NOWRTB
#fuses NOWRTC
#fuses NOCPD
#fuses NOCPB
#fuses NOEBTR
#fuses NOEBTRB

#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, RCV=PIN_C7)

  #define NUM_PULSES_0 0xff
  #define NUM_PULSES_1 0xffff

    int32  gasometro=0,odometro=0;
   #INT_TIMER0
   void timer0(){
   gasometro++;
   printf("\n\rgasometro:%lu ",gasometro);
   set_timer0(NUM_PULSES_0);
   }

   //Esta interrupcion es llamada en forma automatica por el TIMER1 cuando se desborda(0xFFFF).
   #INT_TIMER1
   void wave_timer1(){
   odometro++;       //FUNCION make32 CONVIERTE 2 VARIABLES DE 16 BITS A UNA DE 32 BITS Y LA ASIGNA A LA VARIABLE2   
   printf("\n\rodometro:%lu ",odometro);
   set_timer1(NUM_PULSES_1);
   }

     //Inicializa interrupciones
void inicializa_interrupciones(){
    set_timer1(NUM_PULSES_1);                  //inicializamos el valor con el que inicia el contador del Timer1
    setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);    //configuramos el Timer1 como contador y preescalador de 1.
    enable_interrupts(INT_TIMER1);             //Habilitamos la interrupcion para cuando se desborde el Timer1
   
    set_timer0(NUM_PULSES_0);                  //Inicializamos el valor con el que inicia el contador del Timer0
    setup_timer_0(RTCC_INTERNAL|RTCC_EXT_L_TO_H|RTCC_8_BIT|RTCC_DIV_1);
    enable_interrupts(INT_TIMER0);             //Habilitamos la interrupcion para cuando se desborda el Timer0
    enable_interrupts(GLOBAL);                 //Habilitamos las interrupciones del Pic si no no servirian las interrupcciones de los Timers
    }

  void main(){
  ////
switch ( restart_cause() ) {

   case WDT_TIMEOUT:
                    printf("\n\rWDT_TIMEOUT");
                    break;

   case MCLR_FROM_SLEEP:
                   printf("\n\rMCLR_FROM_SLEEP");
                   break;
   case MCLR_FROM_RUN:
                    printf("\n\rMCLR_FROM_RUN");
                    break;

   case NORMAL_POWER_UP:
                    printf("\n\rNORMAL_POWER_UP");
                    break;
   case BROWNOUT_RESTART:
                    printf("\n\rBROWNOUT_RESTART");
                    break;
         
   case WDT_FROM_SLEEP:
                    printf("\n\rWDT_FROM_SLEEP");
                    break;

   case RESET_INSTRUCTION:
                    printf("\n\rRESET_INSTRUCTION");
                    break;
   default:    break;                 

}

//////////////////////////////////////////////////

  inicializa_interrupciones();
 
  while(1){
   
  }
  }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con TImers en PIC18F452
« Respuesta #5 en: 04 de Noviembre de 2017, 12:30:40 »
Te podrias fijar con el programador que version de silicon tenes? para buscar los errata.... Estoy viendo que ese PIC tiene demasiados problemas y no simples de resolver.

Por que el PIC tiene estos resets:

a) Power-on Reset (POR)
b) MCLR Reset during normal operation
c) MCLR Reset during SLEEP
d) Watchdog Timer (WDT) Reset (during normal
operation)
e) Programmable Brown-out Reset (BOR)
f) RESET Instruction
g) Stack Full Reset
h) Stack Underflow Reset

Los del Stack, lo desahbilitas con los FUSES
Los del BOR,WDT tambien
La instruccion RESET no lo deberia usar el compilador.
El POR tampoco si la ension es correcta.
Y finalmente el MCLR que no se puede deshabilitar. Y como decis tenes bien conectado.

Entonces lo unico que queda Si ninguna de las causas que puede generar un reset esta habilitado o no ocurre, es que sea el PIC.

Desconectado rone17

  • PIC10
  • *
  • Mensajes: 6
Re:Problema con TImers en PIC18F452
« Respuesta #6 en: 04 de Noviembre de 2017, 20:05:52 »
Ok gracias por responder voy a probar cambiando de pic, y la fuente de alimentacion pero lo haria hasta el dia lunes depeniendo, de la que ocurra ya responere para ver si logro resolver la situacion gracias por tus respuestas   

Desconectado rone17

  • PIC10
  • *
  • Mensajes: 6
Re:Problema con TImers en PIC18F452
« Respuesta #7 en: 06 de Noviembre de 2017, 14:20:24 »
GRACIAS POR TU AYUDA YA PUDE RESOLVER EL PROBLEMA, EL PIC ESTABA DAÑADO LO CAMBIE Y YA FUNCIONA