Medir la frecuencia de una onda cuadrada con captura de entrada Atmega328 avr

0

Actualmente estoy midiendo la frecuencia de una onda cuadrada utilizando la captura de entrada en el atmega328p. Una vez que detecta la frecuencia, tengo el código iluminando un LED por encima de un cierto corte (es decir, alrededor de 150 hz) y uno abajo.

volatile uint8_t flag;

volatile unsigned int capture1, capture2, CaptOvr;

volatile unsigned long T1Ovs, timer0_ovflow;


volatile  long ticks;
volatile double period;
unsigned long int frequency;
float Ttime;

void timer1_init(void)
{

  // Starting timer 1 in normal mode
//  TCCR1B= 0x00;
  TCCR1A = 0x00;
  // setting interrupt flag register to 0.
  //TIFR1=0x00;
  // timer 1 setup without any pre scalars, and enabling
  //input capture on rising edge
  TCCR1B =  (1<< ICES1);
  TCCR1B |=(1<<CS12)|(1<<CS10);

  // setting the timer/counter i/o locations to 0.
  //TCNT1H=0x00;
  //TCNT1L=0x00;
  // enabling input capture
 TIMSK1|=(1<<ICIE1)|(1<<TOIE1);
  // enabling global interrupt
  sei();
}


ISR (TIMER1_CAPT_vect)
{

 if (flag==0)
 {

    capture1 = ICR1;
    //setting overflow_counter to 0.
   T1Ovs=0;
    //doubleOverflowError=0;
 }
else if (flag==1)
 {
    capture2 = ICR1;

  //saving the value of overflow_counter to total_overflow
   CaptOvr = T1Ovs; 
  }
  flag++;
}

ISR(TIMER1_OVF_vect)
{
    T1Ovs++;
}


void setup() {
  // put your setup code here, to run once:
 // initialize timer
  Serial.begin(9600);
    timer1_init();
    //timer0_init();
   DDRD = (1<<PORTD7)|(1<<PORTD6);//|(1<<PORTD5);
   PORTD = (0<<PORTD7)|(0<<PORTD6);//|(0<<PORTD5);
}

void loop() {
  // put your main code here, to run repeatedly:
  //flag = first_capture;

      //while (flag != wait);


   if (flag==2)
      {

      flag=0;

        ticks = (capture2 - capture1) + (CaptOvr * 0x10000L);
       // T1Ovs=0;
       // Ttime= ((256*ticks)/16000000);
          frequency = (16000000/ticks)/1024;
   // frequency= (1/Ttime);

Serial.println ((frequency));

      if ((frequency>=100))
      {
          PORTD = (1<<PORTD7);
          //PORTD=(0<<PORTD6);

      }
    else if ( (frequency<100))
      {
        PORTD = (1<<PORTD6)|(0<<PORTD5);
      //  PORTD=(1<<PORTD6);
        }

      }       


}

así que ahora, quiero encender un tercer led que se encenderá cuando no se envíe ninguna señal al pin de interrupción (y se apagará cuando se envíe una señal). Esta es la parte en la que estoy actualmente atascado. Cualquier sugerencia o ayuda sería muy apreciada.

    
pregunta Abcde

2 respuestas

1

Use otro temporizador y configúrelo para que caduque después de un período igual al período de la frecuencia más baja que intenta detectar. Por ejemplo, supongamos que desea que el LED de "no señal" se encienda cuando la frecuencia de entrada sea inferior a 1 Hz. A continuación, establezca el período de este nuevo temporizador en 1 segundo. Cada vez que se detecte un borde, reinicie el contador de este temporizador para que caduque en 1 segundo. De esta manera, el temporizador nunca caducará mientras obtengas bordes más de una vez por segundo. Pero cuando no obtiene una ventaja dentro de un segundo, este temporizador caducará y en el ISR del temporizador podrá encender el LED de "no señal".

    
respondido por el kkrambo
0

Esto se ve muy Arduino'y, pero el concepto es el mismo para cada controlador.

Piense en un período de tiempo en el que espere al menos una transición, supongamos 1 segundo. Con la función millis () , debería poder obtener la cantidad de milisegundos desde que se inició su dispositivo.

Ahora, agregue una variable, llamémosla time_last_signal

Cuando detecte una transición, actualice time_last_signal con el valor actual de millis () .

En su bucle, verifique continuamente si la diferencia entre el valor actual de millis () y su valor de time_last_signal es mayor que 1000 [ms]. Si ese es el caso, no ha recibido una transición por más de 1 y debe encender ese LED. Tan pronto como reciba la próxima transición, apague el LED (puede hacer eso en cada transición, el estado del pin no cambiará realmente).

    
respondido por el Tom L.

Lea otras preguntas en las etiquetas