TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: pablo en 24 de Octubre de 2008, 09:48:13

Título: Timer y delay juntos no?
Publicado por: pablo en 24 de Octubre de 2008, 09:48:13
Hola gente:
Me estoy enloqueciendo con un una practica que estaba intentando hacer con un servo.
Estoy armando un PWM con timer para hacer girar el servo para un lado 1 segundo y luego para el otro.
Si lo hago de esta forma funciona, pero todo lo tengo que hacer dentro del timer.

Código: [Seleccionar]
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT

#define DERECHA 5
#define IZQUIERDA 25


int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;

#int_RTCC
void reloj(void) {
   if(cant==0) {
      output_bit(PIN_B6,1);
   }
   if(cant==GIRO) {
      output_bit(PIN_B6,0);
   }
   cant++;
   if(cant==225) {
      cant=0;
   }   
   cant2++;
   if(cant2==20000) {
      cant2=0;
      if(GIRO==5)
         GIRO=25;
      else
         GIRO=5;
   }
   Set_timer0(247);
}

void main(void) {
   setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);

   enable_interrupts(int_RTCC);
   enable_interrupts(global);
   while(true) {
}

Ahora el tema es que si pongo un delay dentro del programa principal es como si se fuera de este y no volviera a entrar.
Estoy trabadicimo y no se cual es el problema.
Puedo poner delay dentro de un while principal cuando tengo configurado un timer no??
El timer esta configurado para que entre cada 0.1ms.

Codigo que no funciona.

Código: [Seleccionar]
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT

#define DERECHA 5
#define IZQUIERDA 25


int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;

#int_RTCC
void reloj(void) {
   if(cant==0) {
      output_bit(PIN_B6,1);
   }
   if(cant==GIRO) {
      output_bit(PIN_B6,0);
   }
   cant++;
   if(cant==225) {
      cant=0;
   }   
   Set_timer0(247);
}

void main(void) {
   setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);

   enable_interrupts(int_RTCC);
   enable_interrupts(global);
   while(true) {
      delay_ms(1000);
      if(GIRO==5)
         GIRO=25;
      else
         GIRO=5;
   }
}

Desde ya les agradesco mucho.
Saludos.
Pablo
Título: Re: Timer y delay juntos no?
Publicado por: maunix en 24 de Octubre de 2008, 11:37:56
Mientras se ejecuta el delay_ms(1000) la interrupción continua ocurriendo, si quieres que te funcione el código de esa forma, apaga la interrupción antes del delay y al salir vuelvela a encender.

Saludos
Título: Re: Timer y delay juntos no?
Publicado por: pablo en 24 de Octubre de 2008, 11:57:30
Lo que yo necesito es que mientras haga el delay diga corriendo la interrupccion porque de esta forma sigue girando hasta llegar a una posicion determinada.
Si mal no entiendo tengo que hacer esto?
Si es asi sigue sin funcionar.

GRacias.

Código: [Seleccionar]
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT

#define DERECHA 5
#define IZQUIERDA 25


int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;

#int_RTCC
void reloj(void) {
   if(cant==0) {
      output_bit(PIN_B6,1);
   }
   if(cant==GIRO) {
      output_bit(PIN_B6,0);
   }
   cant++;
   if(cant==225) {
      cant=0;
   }   
   Set_timer0(247);
}

void main(void) {
   setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);

   enable_interrupts(int_RTCC);
   enable_interrupts(global);
   while(true) {
      disable_interrupts(int_RTCC);
      delay_ms(1000);
      enable_interrupts(int_RTCC);
      if(GIRO==5)
         GIRO=25;
      else
         GIRO=5;
   }
}
Título: Re: Timer y delay juntos no?
Publicado por: PalitroqueZ en 24 de Octubre de 2008, 16:19:29
Hola

una pregunta: ¿el timer es de uso exclusivo para el retardo de 1S?

porque no sacas toda la rutina de reloj(void) y creas una base de tiempos  y después trabajas con banderas afuera en el bucle principal.

Título: Re: Timer y delay juntos no?
Publicado por: Giovanny en 24 de Octubre de 2008, 18:23:28
hasta donde tengo entendido, el delay_ms y el delay_us lo que hace son loops de ciclos nop.
lo que quiere decir, que mientras se lleva a cabo el delay, el pic esta muerto. si estoy mal
acepto correciones.

Te sugiero que ya que usas un pic poderoso como el 18f4550, uses una interrupcion para
mover el motor . y otra para un conteo de 1 segundo.

en lo posible recomiendo no colocar mucho codigo dentro de las interrupciones.
solo cambio de banderas o incrementos.
Puedes cambiar la susecion de if { } , por un switch, y asi ahorras unas instrucciones.
Código: [Seleccionar]
#int_RTCC
void reloj(void) {
   switch(cant){
      case 0:
          output_bit(PIN_B6,1);
      break;
   
      case GIRO:
         output_bit(PIN_B6,0);
         cant++;
      break;
   
      case 225:
         cant=0;
      break;
   }
   Set_timer0(247);
}

saludos a todos. !
Título: Re: Timer y delay juntos no?
Publicado por: maunix en 24 de Octubre de 2008, 21:24:37
Lo que yo necesito es que mientras haga el delay diga corriendo la interrupccion porque de esta forma sigue girando hasta llegar a una posicion determinada.
Cada cuanto se ejecuta tu interrupción? puede que se ejecute todo varias veces y tu aún no te has enterado que ocurrió.  Lo que sucede es que no uso ese compilador y por ende no puedo probar tu codigo así que te voy tirando ideas nomás.

hasta donde tengo entendido, el delay_ms y el delay_us lo que hace son loops de ciclos nop.
lo que quiere decir, que mientras se lleva a cabo el delay, el pic esta muerto. si estoy mal
acepto correciones.

En general las rutinas de delay de los compiladores C, hacen eso, un bucle de nops o de una variable descontándose N veces hasta lograr el tiempo pactado.  El pic no se muere, para nada, está haciendo eso, contando ciclos.  Incluso si fueran nops, no estaría "muerto", estaria contando nops y las interrupciones seguirían estando y actuando.

Título: Re: Timer y delay juntos no?
Publicado por: pablo en 26 de Octubre de 2008, 13:43:48
La interrupcion se ejecuta cada 0.1ms. El servo trabaja con giro a la derecha manteniendo 0.5ms en alto y 20ms en 0, para la izquierda 2.5ms en 1 y 20ms en 0.
Lo pruebo con el proteus y le pongo un breakpoint despues del delay de la funcion principal y no vuelve mas.
Es como si el delay fuera eterno.
Como la interrupcion sigue funcionando si o si cada 0.1ms el servo se posiciona en forma normal pero al no volver al programa principal no puedo cambiar el estado de posicion.
Con respecto a los consejos de como programar en la interrupcion (programar lo menos posible) lo voy a tener en cuenta.
Ahora averiguo que son nops asi me pongo a tono con lo que me comentan.

Abrazo y gracias.