Autor Tema: Problemas con el TMR1  (Leído 2581 veces)

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

Desconectado rfjhh

  • PIC10
  • *
  • Mensajes: 14
Problemas con el TMR1
« en: 12 de Abril de 2018, 13:12:47 »
Buenas tardes
Estoy haciendo un controlador y quiero establecer el tiempo de muestreo con el TMR1. Sin embargo, el período de muestreo no es uniforme.
El código de prueba es el siguiente:

#include<16f887.h>
#use delay (clock = 8MHz)
#fuses INTRC_IO, NOWDT, NOBROWNOUT, NOLVP, NODEBUG
#use fast_io(c)
#bit TMR1ON=0x10.0 //Identificador para el bit TMR1ON del T1CON
#bit TMR1E = 0x8c.0
int1 b_10ms = 1;

void main()
{
   set_tris_c(0x77);      // 11110111
   setup_adc_ports( NO_ANALOGS );
   setup_oscillator(OSC_8MHZ);
   delay_ms(1000);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   output_low(PIN_B1);
   setup_timer_0(T0_INTERNAL | T0_DIV_32);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(45534);//
      for(;;)
      {
         output_bit(PIN_C7, b_10ms); // Visualizo b_10ms en PIN_C7
         while(!b_10ms){};
         output_bit(PIN_C7, b_10ms);
         b_10ms = 0;   
   }
}

#int_timer1   // rutina de interrupción por desborde de TMR1
void clock_isr()
{
   TMR1E = 0;
   TMR1ON = 0;   
   b_10ms = 1;
   set_timer1(45534);
   TMR1ON = 1;
        TMR1E = 1;
}

Supuestamente debo obtener pulsos cada 10 ms pero esto no sucede, el período es aleatorio.

Espero sus comentarios

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Problemas con el TMR1
« Respuesta #1 en: 12 de Abril de 2018, 13:54:24 »
Buenas tardes
Estoy haciendo un controlador y quiero establecer el tiempo de muestreo con el TMR1. Sin embargo, el período de muestreo no es uniforme.
El código de prueba es el siguiente:
.........................
Supuestamente debo obtener pulsos cada 10 ms pero esto no sucede, el período es aleatorio.

Yo copypasteo ese código , lo simulo con el Proteus y los pulsos resultan perfectamente regulares de 10ms.


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas con el TMR1
« Respuesta #2 en: 12 de Abril de 2018, 15:49:05 »
No hay necesidad de detener el Timer y luego activarlo, tambien la interrupcion.

Si queres que sea aun mas uniforme el tiempo podes usar el CCP del micro. Pero como dijo Eduardo2 el codigo no presenta nada que haga que sea "uniforme"

Desconectado rfjhh

  • PIC10
  • *
  • Mensajes: 14
Re:Problemas con el TMR1
« Respuesta #3 en: 12 de Abril de 2018, 16:58:07 »
¿Cómo lo hago con CCP?

En efecto, si sale bien definido si pongo el selector de tiempo del osciloscopio en 5 ms. Si lo pongo en 10 o más hace locuras.
Ahora lo voy a probar en físico.

Gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas con el TMR1
« Respuesta #4 en: 13 de Abril de 2018, 11:46:28 »
No uso CCS, pero te voy a explicar masomenos como funciona..

Vas a tener que activar el CCP en modo Compare (con reset). Este utiliza el TMR1 y un registro del CCP. Tambien vas a utilizar unicamente la interrupcion del CCP y no del Timer1

Lo que hace es que cuando el contenido del Timer1 es igual al contenido del registro del CCP, se genera la interrupcion y solo resetea el Timer1. Todo esto por Hardware. Entonces no hay demora en actualizar el Timer1 al valor correcto como lo tenes recargando el TMR1 en la interrupcion.

Tambien cargas el valor necesario, suponete que necesitas 1000 ciclos, en el TMR1 debias cargar 65535 - 1000, con el uso de CCP como cuenta desde 0 al numero, solo necesitas cargar 1000.
En la interrupcion no tenes que recargar ningun valor, solo actuar con lo que tengas que hacer.

Para configurar todo necesitas:

Configurar el Timer1: preescaler y activarlo
Configurar el CCP en modo compare, con reset del tmr1, cargar el valor de igualdad, activar la interrupcion del CCP

Y ya estaria, solo necesitas la funcion de interrupcion del CCP y hacer lo que debas hacer adentro y no tocar ni el CCP, ni el Timer de nuevo

Solo para darte una idea, ya que no conosco si es INT_CCP1 o si las funciones son las correctas, pero aproximadamente deberia ser asi:

Código: C
  1. #INT_CCP1
  2. void interrupcion_ccp(void)
  3. {
  4.     output_toggle(PIN_B0);
  5. }
  6.  
  7. void main(void)
  8. {
  9.  
  10.       //Resto de configuracion
  11.      setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  12.      setup_ccp1(CCP_COMPARE_RESET_TIMER);
  13.      set_pwm1_duty(1000); // Fijamos la cantidad de ciclos que debe comparar
  14.  
  15.     enable_interrupts(INT_CCP1);
  16.     enable_interrupts(GLOBAL);
  17.  
  18.     while(1)
  19.    {
  20.    }
  21. }


 

anything