Autor Tema: problema con timers (solucionado)  (Leído 3364 veces)

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

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
problema con timers (solucionado)
« en: 24 de Marzo de 2009, 07:10:41 »
Hola,

tengo un programa de funcionamiento de un motor. Recibo la velocidad por i2c, la proceso y se la envio mediante pwm a la etapa de potencia del motor.

A su vez, necesito leer los datos de un encoder, lo cual lo hago periodicamente cada 122Hz.

Es decir, uso TIMER0, TIMER1 y TIMER2.

todo funciona bien por separado, pero al juntarlo me sale algun tipo de colision, puesto que el motor se me queda a una velocidad fija y no varía. supongo que no actualiza el valor de "pwm1" de forma correcta.

si deshabilito la linea de configuracion de timer0 en el main para no leer el encoder, todo funciona correctamente, pero es totalmente necesario el uso de esa linea, por lo que recurro a vosotros.

el codigo es el siguiente:

Código: [Seleccionar]

#include <16F886.h>
#include <i2c_config.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT, NOLVP
#use delay(clock=4000000)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa1, FORCE_HW)

#define INTS_PER_SECOND 72     // (20000000/(4*256*256))

BYTE array[4];

BYTE pwm1;
BYTE pwm2;


long time=1,flancos=0;

#int_rtcc                         
void clock_isr()
{
   long value1,value2;

output_high(PIN_B1);

if(time==1)
{
value1=get_timer1();
time=2;
}
else
  {
value2=get_timer1();
flancos=value2-value1;
time=1;
}

   output_low(PIN_B1);
}


#INT_SSP
void ssp_interupt ()
{
    BYTE state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
  array[state] = i2c_read();

if(state == 2){                     //Second received byte is data
            if (array[0]==0x01){

if( bit_test(array[1],7)){
          pwm1 = 0;
    pwm2 = array[state];
                                  }
else{
    pwm2 = 0;
    pwm1 = array[state];
  }
       }
      }
}
   if(state >= 0x80)                     //Master is requesting data
  {
      i2c_write(0x01);
   }
}

void main ()
{
   enable_interrupts(INT_SSP);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_ccp2(CCP_PWM);   // Configure CCP1 as a PWM

   setup_timer_0( RTCC_INTERNAL | RTCC_DIV_32);              ///SI COMENTO ESTA LINEA, TODO FUNCIONA OK
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); //use low power 32kHz crystal
   setup_timer_2(T2_DIV_BY_1, 255, 1);
   
   set_timer1(0);

   pwm1 = 0;
   pwm2 = 0;
   
   while (TRUE){

set_pwm1_duty(pwm1);
              set_pwm2_duty(pwm2);
}
}


me podeis echar una mano??

muchas gracias
« Última modificación: 31 de Marzo de 2009, 18:24:48 por pirraca »

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
Re: problema con timers
« Respuesta #1 en: 27 de Marzo de 2009, 06:20:00 »
He probado a cambiar el orden de las interrupciones, para conseguir mas prioridad en la de la adquisicion de datos del I2C, pero todo sigue igual...

Tambien he probado a hacer el enable de las interrupciones justo antes del while(1) dentro del main...

alguna idea?

muchas gracias por anticipado!

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: problema con timers
« Respuesta #2 en: 27 de Marzo de 2009, 08:16:33 »
yo estoy haciendo un controlador de acuario con un ds1307
Y creo que deben de estar desactivadas las interrupciones cuando se trasmite los datos por i2c, por lo menos a mi me pasa por que el timer0 esta habilitado en mi proyecto... 
no se si en tu caso te tocara desactivar antes  y despues de la trasmision L/E
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
Re: problema con timers
« Respuesta #3 en: 27 de Marzo de 2009, 09:33:13 »
yo estoy haciendo un controlador de acuario con un ds1307
Y creo que deben de estar desactivadas las interrupciones cuando se trasmite los datos por i2c, por lo menos a mi me pasa por que el timer0 esta habilitado en mi proyecto... 
no se si en tu caso te tocara desactivar antes  y despues de la trasmision L/E

si esto es cierto, tengo un problemón, ya que envio datos por el i2c constantemente...

voy a ver si puedo apañar algo asi como me dices

muchas gracias

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: problema con timers
« Respuesta #4 en: 27 de Marzo de 2009, 21:26:44 »
problemon.... para nada....

#INT_SSP
void ssp_interupt ()
{

   disable_interrupts(global);                                       //desabilita todo tipo de interrupciones, justo antes de  enviar o recibir  por i2c

    BYTE state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
     array[state] = i2c_read();

   if(state == 2){                     //Second received byte is data
            if (array[0]==0x01){

         if( bit_test(array[1],7)){
                     pwm1 = 0;
                pwm2 = array[state];
                                  }
         else{
                pwm2 = 0;
                pwm1 = array[state];
           }
             }
         }
   }
   if(state >= 0x80)                     //Master is requesting data
  {
      i2c_write(0x01);
   }

    enable_interrupts(global);                           //vuelve a habilitar las interrupciones despues de enviar o recibir por i2c
}
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: problema con timers
« Respuesta #5 en: 28 de Marzo de 2009, 13:51:49 »
Otra posible solucion podria ser trabajar el micro con mayor velocidad, quizas en 20 MHZ quede bien.

Otra cosa, primero modifica tus interrupciones y despues habilitas todo, no al reves:
Código: [Seleccionar]
   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_ccp2(CCP_PWM);   // Configure CCP1 as a PWM

   setup_timer_0( RTCC_INTERNAL | RTCC_DIV_32);              ///SI COMENTO ESTA LINEA, TODO FUNCIONA OK
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); //use low power 32kHz crystal
   setup_timer_2(T2_DIV_BY_1, 255, 1);
   
   set_timer1(0);

   pwm1 = 0;
   pwm2 = 0;

   enable_interrupts(INT_SSP);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   While (TRUE)

Y... Porque usas el Timer0 no entiendo,  el encoder de tu motor no te entrega pulsos? Porque no usas el Intext ? :S


Suerte.
« Última modificación: 28 de Marzo de 2009, 13:56:51 por jeremylf »

Desconectado fujcanin

  • PIC10
  • *
  • Mensajes: 2
Re: problema con timers
« Respuesta #6 en: 28 de Marzo de 2009, 20:20:44 »
Otra posible solucion podria ser trabajar el micro con mayor velocidad, quizas en 20 MHZ quede bien.

Otra cosa, primero modifica tus interrupciones y despues habilitas todo, no al reves:
Código: [Seleccionar]
   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_ccp2(CCP_PWM);   // Configure CCP1 as a PWM

   setup_timer_0( RTCC_INTERNAL | RTCC_DIV_32);              ///SI COMENTO ESTA LINEA, TODO FUNCIONA OK
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); //use low power 32kHz crystal
   setup_timer_2(T2_DIV_BY_1, 255, 1);
   
   set_timer1(0);

   pwm1 = 0;
   pwm2 = 0;

   enable_interrupts(INT_SSP);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   While (TRUE)

Y... Porque usas el Timer0 no entiendo,  el encoder de tu motor no te entrega pulsos? Porque no usas el Intext ? :S


Suerte.

es mejor esa solucion, pero creo que no solucionará mucho

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: problema con timers
« Respuesta #7 en: 28 de Marzo de 2009, 20:29:09 »
el 16f886 solo tiene dos contadores de 8bits o uno de 16.... el cual se consigue utilizando los dos timer 0 y el 2
asi es normal que no te funcione...
revisate las caracteristicas

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en026562
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
Re: problema con timers
« Respuesta #8 en: 29 de Marzo de 2009, 07:30:41 »
el 16f886 solo tiene dos contadores de 8bits o uno de 16.... el cual se consigue utilizando los dos timer 0 y el 2
asi es normal que no te funcione...
revisate las caracteristicas

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en026562

estas son las caracteristicas en cuanto a timers se refiere el 886:



ahora te pregunto:

¿No quiere decir esto que 886 dispone de 3 timers/counter timer0, timer1 y timer2?

yo así lo entiendo, aunque seguro que lo entiendo mal debido a mi inexperiencia

muchas gracias!
« Última modificación: 29 de Marzo de 2009, 07:41:50 por pirraca »

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: problema con timers
« Respuesta #9 en: 29 de Marzo de 2009, 08:05:57 »
He estado mirando el Datasheet del 16F886 y no he encontrado nada que apoye lo que dice ppyote.

Aparentemente el 16F886 tiene, como todos los de su familia, dos Timers de 8 bits, TMR0 y TMR2 y uno totalmente independiente y asociado a las enhacements del ECCP de 16 bits que es TMR1.

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: problema con timers
« Respuesta #10 en: 29 de Marzo de 2009, 15:57:57 »
pues no se.... estare equivocado... pero me suena mucho lo de timer0 + timer 2 = timer1 en la fanilia de los 16f
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: problema con timers
« Respuesta #11 en: 29 de Marzo de 2009, 16:51:51 »
Hasta ahora los 16F con los que he trabajado todos tenían los tres Timers independientes y en la forma en que expuse en mi anterior post, los Timer0 y Timer2 de 8 bits y el Timer1 de 16 bits: el 16F88, el 16F877A, el 16F876A, el 16F628A ...

Unos modelos tienen clock externo, counter, para uno u otro de los timers o para varios de ellos, otros asocian el ECCP a uno de los 8 bits o al de 16 bits, los hay con posibilidades de mas o menos pre-scalers, post-scalers o divisores pero todos tienen la misma estructura. Y además el Timer1 es posible configurarlo para que funciones como 16 bits o como 8 bits.

El único que conozco que no cumple con esto y al que casi no considero de esta familia es el antidiluviano y obsoleto 16F84.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: problema con timers
« Respuesta #12 en: 29 de Marzo de 2009, 17:43:03 »
de eso me suena entonces.... el 16f84... yo hasta hace menos de 3 meses entaba utilizandolo, despues migre al 16f628a por eso que me sonaba algo de la utilizacion del timer 0 y el timer 2 que conjuntamente habilitaban el timer1....
ahora ya me lo has dejado claro, gracias por la aclaracion y perdon por hablar de lo que no se tiene conocimiento...
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
Re: problema con timers
« Respuesta #13 en: 30 de Marzo de 2009, 04:42:42 »
de eso me suena entonces.... el 16f84... yo hasta hace menos de 3 meses entaba utilizandolo, despues migre al 16f628a por eso que me sonaba algo de la utilizacion del timer 0 y el timer 2 que conjuntamente habilitaban el timer1....
ahora ya me lo has dejado claro, gracias por la aclaracion y perdon por hablar de lo que no se tiene conocimiento...

Muchas gracias ppyote, no te preocupes que no pasa nada, asi le he metido un repasillo al datasheet! jejeje

muchas gracias a redpic tambien por su ayuda

sigo pruebas y os voy contando avances

saludos

Desconectado pirraca

  • PIC10
  • *
  • Mensajes: 11
Re: problema con timers
« Respuesta #14 en: 30 de Marzo de 2009, 07:24:16 »
He realizado unas modificaciones en el código para ver si tocando los registros directamente hacia algo...

el código actual es el siguiente:

Código: [Seleccionar]
#include <16F886.h>
#include <i2c_config.h>

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT, NOLVP
#use delay(clock=20000000)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0, FORCE_HW)


//#bit SEN = 0x91.0
//#bit CKP = 0x14.4


BYTE array[4];

static BYTE pwm1;
static BYTE pwm2;


long time=1,flancos=0;




#INT_SSP
void ssp_interupt ()
{
BYTE state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
  array[state] = i2c_read();

  if(state == 2){                     //Second received byte is data
         if (array[0]==SPEED){

if( bit_test(array[1],7)){
      pwm1 = 0;
    pwm2 = array[state];
             }
else{
pwm2 = 0;
    pwm1 = array[state];
}

  }
}

}
   if(state >= 0x80)                     //Master is requesting data
  {
      i2c_write(0x01);
   }

}


#int_rtcc                          // This function is called every time// the RTCC (timer0) overflows (255->0).
void clock_isr()
{
   static long value1,value2;

output_high(PIN_B1);

if(time==1)
{
value1=get_timer1();
time=2;
}
else
  {
value2=get_timer1();
flancos=value2-value1;
time=1;
}

   output_low(PIN_B1);


}



void main ()
{
  //BYTE pwm1_old, pwm2_old;
   

   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_ccp2(CCP_PWM);   // Configure CCP1 as a PWM

   output_bit(129.7, 1);
   output_bit(129.6, 1);
   output_bit(129.5, 0);
   output_bit(129.4, 0);
   output_bit(129.3, 0);
   output_bit(129.2, 1);
   output_bit(129.1, 0);
   output_bit(129.0, 0);    //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);

   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_1, 255, 1);

   set_timer1(0);

   pwm1 = 0;
   pwm2 = 0;
   
  enable_interrupts(INT_SSP);
 
  enable_interrupts(INT_RTCC);
   
enable_interrupts(GLOBAL);

   while (TRUE){


set_pwm1_duty(pwm1);

  set_pwm2_duty(pwm2);

}
}

Como veis, he cambiado la configuracion del TMR0 para hacerla de modo que toco sus registros directamente.

El resultado ha sido esperanzador pero no determinante, pues ahora el motor se mueve segun le dicta el i2c, pero soy incapaz de hacer funcionar la interrupcion del TIMER0 en la cual se cogen los datos del encoder... :(



sigo con pruebas y os seguiré contando el desarrollo



EDITO: esto que he hecho no sirve para nada, no se cambia el valor del registro, por eso funciona correctamente el motor, por que la interrupcion del timer0 no afecta ni esta configurada.

« Última modificación: 30 de Marzo de 2009, 07:59:56 por pirraca »