¿Cómo podemos medir las señales sinusoidales en atmega8?

1

¿Cómo se mide la frecuencia de la señal en ATmega? En particular, ¿cómo se mide la frecuencia de la señal (senoidal) en ATmega8?

    
pregunta Dana Sorani

2 respuestas

1

Muestra valores usando un ADC con una frecuencia mínima que necesita para que sea dos veces (más es mejor ;-) la frecuencia con la que espera que se encuentre su seno). Luego realice una FFT (consulte aquí también). Dependiendo de la rapidez / frecuencia con la que necesite hacer esto, esto debería ser posible en la familia atmega.

Ese aquí parece realmente impresionante para ser honesto

    
respondido por el Tom L.
3

Suponiendo que solo está interesado en medir la frecuencia de la sinusoidal, diría que la convierta en pulsos de onda cuadrada (por ejemplo, con un optoacoplador) y luego use los temporizadores para medir la onda cuadrada.

Hay varias formas de medir la frecuencia, pero la más precisa es mediante el uso de la unidad de captura de entrada, consulte esta publicación.

Otra alternativa que dará resultados bastante precisos pero no tan precisos como el método anterior es usar el temporizador 1 como una puerta para que el temporizador 0 mida los pulsos en una ventana específica (por ejemplo, 100 ms) y luego use matemáticas para obtener la señal frecuencia. Para hacer esto, configura el temporizador 0 para que use los pulsos de señal externos como fuente de reloj, esto es lo que quiero decir:

// sample for mega88
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/power.h>

#define ENABLE_TIMER1    TCCR1B=(1<<CS11) | (1<<CS10);
#define DISABLE_TIMER1    TCCR1B=0x00;
#define ENABLE_TIMER0    TCCR0B=(1<<CS02) | (1<<CS01) | (1<<CS00);
#define DISABLE_TIMER0    TCCR0B=0x00;
#define RESET_TIMERS    TCNT1 = 53036; TCNT0=0x00; timer0_ovf=0; timer1_ovf=0;

volatile unsigned char timer1_ovf;
volatile unsigned int timer0_ovf;
uint32_t frequency;

// Timer 0 overflow interrupt service routine
ISR(TIMER0_OVF_vect)
{
    timer0_ovf++;  // overfloaw counter , will be used in calculations later
}

// Timer1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
    DISABLE_TIMER1
    DISABLE_TIMER0
    timer1_ovf = 1;      // flag that measure has finshed
}


uint32_t measure_frequency(void)
{

    RESET_TIMERS
    _delay_ms(1);

    ENABLE_TIMER1
    ENABLE_TIMER0

    while(timer1_ovf != 1);  // wait for flag

    // measure window is 0.1sec, to convert to sec multiply with 10
    return (((TCNT0 + (256UL * timer0_ovf)) * 10));

}

void main(void)
{
    // Crystal Oscillator division factor: 1
    clock_prescale_set(clock_div_1);   

    // Timer/Counter 0 initialization
    // Clock source: T0 pin Rising Edge
    // Mode: Normal top=0xFF
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A = (0 << COM0A1) | (0 << COM0A0) | (0 << COM0B1) | (0 << COM0B0) | (0 << WGM01) | (0 << WGM00);
    TCCR0B = (0 << WGM02) | (1 << CS02) | (0 << CS01) | (0 << CS00);
    TCNT0 = 0x00;
    OCR0A = 0x00;
    OCR0B = 0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 125,000 kHz
    // Mode: Normal top=0xFFFF
    // OC1A output: Disconnected
    // OC1B output: Disconnected
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer Period: 0,52429 s
    // Timer1 Overflow Interrupt: On
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (0 << COM1B1) | (0 << COM1B0) | (0 << WGM11) | (0 << WGM10);
    TCCR1B = (0 << ICNC1) | (0 << ICES1) | (0 << WGM13) | (0 << WGM12) | (0 << CS12) | (0 << CS11) | (0 << CS10);
    TCNT1 = 53036;  // 65536-12500 = 53036  , overflow at 100ms
    ICR1H = 0x00;
    ICR1L = 0x00;
    OCR1AH = 0x00;
    OCR1AL = 0x00;
    OCR1BH = 0x00;
    OCR1BL = 0x00;

    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0 = (0 << OCIE0B) | (0 << OCIE0A) | (1 << TOIE0);

    // Timer/Counter 1 Interrupt(s) initialization
    TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (1 << TOIE1);

    // Global enable interrupts
    sei();

   frequency = measure_frequency();  // measure frequency and store to variable

    while(1)
    {
        // Place your code here

    }
} 
    
respondido por el alexan_e

Lea otras preguntas en las etiquetas