Autor Tema: Timer 0 y 1  (Leído 2729 veces)

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

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Timer 0 y 1
« en: 08 de Enero de 2007, 20:47:34 »
Hola gente.

Tengo un problemita, nunca use 2 timers juntos y realmente estoy un poco trabado en este momento logre que funcionen los 2 pero no se realmente que es lo que estoy haciendo y el inconveniente que veo es que uno trabaja bastante mas lento que el otro.

Lo que yo necesito es que entre al timer cada 50ms. Alguien podria darme una mano. Les pongo el codigo. Esto mueve 2 motores paso a paso y se le cambian las velocidades con unos botones pero lo que mas importa es la parte de las interrupciones de Timers y las configuracion inicial.

#include <16F873A.h>

#use delay (clock=4000000)
#fuses XT,NOWDT,NOLVP
#define INTS_PER_SECOND 1000 // (4000000/(4*4*250)) (4*Divisor*Interrupciones)
                     //       0          1          2           3          4         5           6          7         8            9
byte CONST Display2[] = {0b11111111,0b00001100,0b01011011,0b01011110,0b01101100,0b01110110,0b01110111,0b00011100,0b01111111,0b01111110};
int Boton=0;
int Funcion=1;
int Sea=1;
int8 Timer0 = 0, Timer1 = 0;
byte stepper1 = 0, stepper2 = 0;
   int speed1 = 20;
   int speed2 = 20;

byte const Motor[4] = {0b1100, 0b0110, 0b0011, 0b1001};

drive_stepper1(int speed, char dir, byte steps) {
      speed = 0;
      delay_ms(speed);
      set_tris_c(0xf0);

      if(stepper1 == 0) {
         output_bit(PIN_C4,1);
         output_bit(PIN_C5,1);
         output_bit(PIN_C6,0);
         output_bit(PIN_C7,0);
      }else if(stepper1 == 1) {
         output_bit(PIN_C4,0);
         output_bit(PIN_C5,1);
         output_bit(PIN_C6,1);
         output_bit(PIN_C7,0);
      }else if(stepper1 == 2) {
         output_bit(PIN_C4,0);
         output_bit(PIN_C5,0);
         output_bit(PIN_C6,1);
         output_bit(PIN_C7,1);
      }else if(stepper1 == 3) {
         output_bit(PIN_C4,1);
         output_bit(PIN_C5,0);
         output_bit(PIN_C6,0);
         output_bit(PIN_C7,1);
      }
      stepper1++;
      if(stepper1==4)
         stepper1=0;

}

drive_stepper2(int speed, char dir, byte steps) {
      speed = 0;
      delay_ms(speed);
      set_tris_a(0xf0);

      if(stepper2 == 0) {
         output_bit(PIN_A0,1);
         output_bit(PIN_A1,1);
         output_bit(PIN_A2,0);
         output_bit(PIN_A3,0);
      }else if(stepper2 == 1) {
         output_bit(PIN_A0,0);
         output_bit(PIN_A1,1);
         output_bit(PIN_A2,1);
         output_bit(PIN_A3,0);
      }else if(stepper2 == 2) {
         output_bit(PIN_A0,0);
         output_bit(PIN_A1,0);
         output_bit(PIN_A2,1);
         output_bit(PIN_A3,1);
      }else if(stepper2 == 3) {
         output_bit(PIN_A0,1);
         output_bit(PIN_A1,0);
         output_bit(PIN_A2,0);
         output_bit(PIN_A3,1);
      }
      stepper2++;
      if(stepper2==4)
         stepper2=0;

}

#INT_TIMER0
clock_isr0() {                  // the RTCC (timer0) overflows (255->0).
   if(Timer0++ == 20) {
      drive_stepper1(speed1, 'D', 0);   
      Timer0 = 0;
   }
}

#INT_TIMER1
clock_isr1() {                      // the RTCC (timer0) overflows (255->0).
   if(Timer1++ == 20) {
      drive_stepper2(speed1, 'D', 0);   
      Timer1 = 0;
   }
}

void main(void) {

   set_timer0(0);
   set_timer1(0);
   setup_timer_0(T1_INTERNAL|T1_DIV_BY_1);   // setup interrupts
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   // setup interrupts
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   if((int) read_eeprom(1) > 6)   
      write_eeprom(1,1);
   if((int) read_eeprom(2) > 6)   
      write_eeprom(2,1);

   speed1 = ((int) read_eeprom(1)) * 20;       
   speed2 = ((int) read_eeprom(2)) * 20;       


   set_tris_b(0x00);
   while(true) {
      do {
         if(!input(PIN_C0)) {
            Boton = 1;
         }
         if(!input(PIN_C1)) {
            Boton = 2;
         }
         if(!input(PIN_C2)) {
            Boton = 3;
         }
         if(!input(PIN_C3)) {
            Boton = 4;
         }
         restart_wdt();      // Puesta a cero del temporizador watchdog
      }while(!input(PIN_C0)||!input(PIN_C1)||!input(PIN_C2)||!input(PIN_C3));
      delay_ms(30);         // Antirebotes


      if(Boton==1) {
         if(Sea==1)
            Sea=2;
         else
            Sea=1;
         Funcion = (int) read_eeprom(Sea);       
      }
      if(Boton==2) {
         Funcion++;
         if(Funcion==7)
            Funcion--;
      }
      if(Boton==3) {
         Funcion--;
         if(Funcion==0)
            Funcion++;
      }
      if(Boton==4) {
         write_eeprom(Sea,Funcion);
         if(Sea==1)
            speed1 = Funcion * 20;
         else
            speed2 = Funcion * 20;
      }

      output_b(Display2[Funcion]);
      do{
         restart_wdt();      // Puesta a cero del temporizador watchdog
         drive_stepper1(speed1, 'D', 0);
         drive_stepper2(speed2, 'D', 0);
      }while(input(PIN_C0)&&input(PIN_C1)&&input(PIN_C2)&&input(PIN_C3));
      delay_ms(30);         // Antirebotes
   }
}


Muchas gracias.
Pablo

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Timer 0 y 1
« Respuesta #1 en: 09 de Enero de 2007, 08:23:49 »
Mira bien la hoja de datos, encontraras que el timer0 es de 8 bits (0-255) y el timer1 es de 16 bits (0-65535).
Ademas tienen prescalers diferentes, por lo tanto si los configuras igual por supuesto el timer1 sera mas lento que el timer0 !! :mrgreen: :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: Timer 0 y 1
« Respuesta #2 en: 09 de Enero de 2007, 14:47:28 »
Ah, gracias. Es que soy solo un aficionado hago cosas para mi, pero no se nada de electronica.
Muchas gracias por el dato.

Pablo

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
Re: Timer 0 y 1
« Respuesta #3 en: 09 de Enero de 2007, 15:04:02 »
Pablo, no entiendo para que queres usar los dos timers, como dice MGLSOFT, no son iguales, de cualquier modo para usar el timer0 para una interrupcion cada 50 ms con un cristal de 4 mhz, tenes que prescalar el timer en 256 asi:  

Código: [Seleccionar]

setup_counters(RTCC_INTERNAL,RTCC_DIV_256);


y al salir de la rutina de interrupcion cargas 196.


Código: [Seleccionar]
#INT_TIMER0

clock_isr()   {

  set_timer0 (196);

}
 


Esto no te da 50 mS exactos, si no 50,176 mS (256x256x196)/1000, esto a 4 mhz, para

mas presicion, podes usar el timer1, asi:



Código: [Seleccionar]

setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);




Código: [Seleccionar]

#INT_TIMER1

clock_isr()   {

  set_timer1 (15536);

}



Aca tenes 50 mS exactos,

espero que te ayude.



« Última modificación: 09 de Enero de 2007, 15:09:59 por pikman »
saludos
PikMan

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: Timer 0 y 1
« Respuesta #4 en: 09 de Enero de 2007, 18:42:06 »
Excelente, muchas gracias.
El problema es que tengo que manejar 2 motores paso a paso al mismo tiempo y cuando esta en uno de los pasos uno de los motores el otro no tiene tension y pierde fuerza, por eso se me ocurrio que era la mejor forma que cada uno funcionara en un timer independiente.
Si podes responderme esta otra duda te lo agradeceria mucho.
En el pic 16f873 la pata AN4 se usa para un clock externo y no se que es lo que tengo que configurar para que pueda utilizarla como salida, configure set_tris pero creo que hay algo mas.

Gracias.
Pablo

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
Re: Timer 0 y 1
« Respuesta #5 en: 09 de Enero de 2007, 19:25:49 »
Bueno, la verdad es que no me queda claro el tema, deberian andar los dos iguales, el problema con AN4 es que es una salida de colector abierto, lo que significa que no va poner un 1 logico ( 5 v) de ninguna manera, o deberias usar un transistor que active un PNP, te recomendo usar otra salida..

saludos
PikMan

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: Timer 0 y 1
« Respuesta #6 en: 09 de Enero de 2007, 19:38:19 »
Ups, no me quedan mas patas.
Puedo con una sola pata prender 2 leds.
Osea, por ejemplo lo que necesito es indicar cual de los motores esta en funcionamiento, no se , cuando este en 0 que prenda uno y cuando esta en 1 prenda el otro. Esto es posible?

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
Re: Timer 0 y 1
« Respuesta #7 en: 09 de Enero de 2007, 20:02:13 »
Si podes, pone un led entre el pin y +5Vcc y otro led entre el mismo pin y masa, entonces cuando el pin este en 1 encendera el led que esta a masa y cuando el pin este en 0 encendera el led que esta a +5Vccc y si queres apagarlos configura el pin como entrada, usando  output_float(PIN_CX); donde X es el pin que maneja los leds, entonces podes conseguir que el pin tenga tres estados, y bueno asi te ahorras un pin...

saludos
PikMan

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: Timer 0 y 1
« Respuesta #8 en: 09 de Enero de 2007, 20:29:46 »
Muchas gracias de verdad.
No caso una de electronica pero gracias a uds pude hacer unas cuantas cosas para mi hobby que es el acuarismo.

Lo acabo de probar en el proteus y funciona perfecto.

Un abrazo
Pablo

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Timer 0 y 1
« Respuesta #9 en: 10 de Enero de 2007, 19:42:39 »
Buenisimo lo del LED Ariel !! :-/ :-/

Esa es una de las lecciones del Maestro Pikman !! :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
Re: Timer 0 y 1
« Respuesta #10 en: 10 de Enero de 2007, 21:07:27 »
Gracias MARCOS, no es para tanto che, un master se admira del otro :mrgreen: :mrgreen:
saludos
PikMan


 

anything