Go Down

Topic: Tiempos mínimos. (Read 468 times) previous topic - next topic

pepefe

Jan 05, 2013, 12:28 pm Last Edit: Jan 05, 2013, 12:30 pm by pepefe Reason: 1
Un par de notas previas:
De programar en C estoy pez; pese a haberlo intentado en las últimas décadas nunca lo he "interiorizado" osea que es probable que tenga cagadas muy muy básicas.
Programar en código máquina si que se, lo he hecho durante años en varias plataformas.


El problema:
Mediante interrupciones para cargar lo mínimo la CPU hago lo siguiente. Un sensor hall manda un pulso que activa una salida y un tiempo después se apaga. Ambas señales van por interrupciones; una externa para inicio y una por el timer2 para el final. Parece funcionar correctamente, pero al haber añadido unas instrucciones para contar el tiempo de la amplitud del pulso salen tiempos muy grandes.
No he podido medir la amplitud real del pulso y puede que sea correcta y el "medidor" con lafunción millis() o con micros() da mas o menos lo mismo no mida bien porque las funciones del sistema sean muy lentas.
El caso es que el tiempo mínimo son 16mS y debería de ser menos.

El código:
Code: [Select]
   #include <avr/interrupt.h>
   #include <avr/io.h>
   int Inyector = 3;    //
   int LED = 13;        //Pin del led
   int PotOn=A0;
   int recarga=100;
   int RPM;
   unsigned long tOn=0;
   unsigned long tOnOld;
   unsigned long apertura;
   volatile int state = LOW;
   //
   
   ISR(TIMER2_OVF_vect) {
   digitalWrite( Inyector, LOW);
//Parar el timer 2
   TCCR2B &= ((0<<CS22) | (0<<CS21) | (0<<CS20));
   //TIMSK2 |= (0<<TOIE2) ;  //InHabilita interrupción por desbordamiento del Timer2
   apertura=millis()-tOn;
   state = !state;
   Serial.print("R=");
   Serial.print(recarga);
   Serial.print("  Ap=");
   Serial.print(apertura);
   Serial.print("mS ");
   Serial.print(RPM);
   Serial.println("rpm");
   };
   void setup() {
   //Parar el timer 2
   TCCR2B &= ((0<<CS22) | (0<<CS21) | (0<<CS20));      
   // Use normal mode
   TCCR2A |= (0<<WGM21) | (0<<WGM20);
   // Usar reloj interno. No se usa el reloj externo en arduino
   ASSR |= (0<<AS2);
   TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);  //Habilita interrupción por desbordamiento del Timer2
   //Initialize serial and wait for port to open:
   Serial.begin(9600);
   // prints title with ending line break
   Serial.println("ECU 004 (c) Felix Diaz");

     // initialize the digital pin as an output.
 pinMode(Inyector, OUTPUT);  
 pinMode (LED  , OUTPUT);
  attachInterrupt(0, inicio, FALLING); //Puede ser LOW, CHANGE, RISING Y FALLING
   }

   void loop() {
       recarga=255-analogRead(PotOn)/4;    //El potenciometro va al revés que el timer
         digitalWrite(LED, state);
       delay(100);
   }

void inicio()
{
 digitalWrite( Inyector, HIGH);
 tOnOld=tOn;
 tOn=millis();
 sei();
 //Recargar el timer:
   TCNT2=recarga;
   //Configuración del timer 2: Preescaler /1024,
   TCCR2B |= ((1<<CS22) | (1<<CS21) | (1<<CS20));
   //Resetear el preescaler
   GTCCR |= (1<<PSRASY);
 RPM=60000/(tOn-tOnOld);
}


Dado lo taruguín que soy programando en C, a ver si veis algún error gordo o algo. Es probable que tenga alguna orejada tonta.

pepefe

Pues después de un rato de estudiar el caso, parece ser que al escribir el registro del timer la primera vez no hace caso de la interrupción.
El manual de AVR dice que puede pasar si se hace con el timer en marcha, pero con los tres arduinos que tengo pasa si o si tengas o no el timer en marcha.

Go Up