Midiendo la longitud del pulso con ICP

0

Estoy tratando de medir la duración del pulso, con ICP (pin de captura de entrada) en Atmega8 , proveniente de este circuito: . PINB0 es un pin ICP en AVR.

Este es (la mayoría de) el código:

volatile uint8_t num_interrupts = 0; //number of input capture interrupts.
volatile BOOL write_glcd = FALSE; //write to LCD. 
volatile uint8_t tim1_num_ovf = 0; //number of overflowes for timer1.
volatile uint16_t test[50]; //holds time elapsed since last TIMER1_CAP interrupt

int main(void)
{
    DDRC |= (1<<PINC3);
    PORTC &= ~(1<<PINC3);
    DDRB &= ~(1<<PINB0); //icp pin as input
    PORTB |= (1<<PINB0); //pull-up on icp pin
    TIMSK = ((1<<TICIE1)|(1<<TOIE1)); //enable timer1 overflow and input capture interrupts.
    TCCR1B = (1<<CS10); //1x prescaler, input capture on falling edge.
    cli(); //disable interrupts.

    start_LC();

    while(1){
        if (write_glcd) {
            cli(); // disable interrupts

            for (uint8_t i = 0; i < num_interrupts; i++) {
                glcd_clear_y((uint8_t[]) {4, 5, 7}, 3);
                glcd_write_num_xy(test[i], FALSE, 8, 0, 4);
                //glcd_write_num_xy(((test[i] & 0xFF0000) >> 16) * (UINT16_MAX + 1UL), FALSE, 8, 0, 5);
                _delay_ms(1000);
            }

            _delay_ms(2000);
            write_glcd = FALSE;
            start_LC();
        }        
    }
void start_LC(void)
{
    PORTC |= (1<<PINC3); //pull output high, it induces some oscillations in LC tank circuit.
    num_interrupts = 0;
    write_glcd = FALSE;
    tim1_num_ovf = 0;
    _delay_ms(10); //wait for oscillations in LC tank circuit to dissipate
    TCNT1 = 0;
    sei(); //enable interrupts.
    PORTC &= ~(1<<PINC3); //induce oscillations.
}
ISR(TIMER1_OVF_vect)
{
    tim1_num_ovf += 1;
}
ISR(TIMER1_CAP_vect)
{
    test[num_interrupts] = ICR1;// | ((uint32_t)tim1_st_ovf << 16UL)); //commented out, just for now, timer1 ovf interrupts doesnt happen, so its ok.
    num_interrupts += 1;
    tim1_num_ovf = 0;
    TCNT1 = 0;
}

El problema es que obtengo algunos datos relativamente aleatorios escritos en LCD. Algo como esto:

  • 55
  • 48
  • 42
  • 39
  • 16
  • 12
  • 22
  • 65

write_glcd se establece en TIMER2_OVF ISR después de cada segundo (que se basa en el número de interrupciones de desbordamiento de TIMER2), el código no se incluye aquí.

Según tengo entendido, se suponía que estos números eran el tiempo en los tictacs del TIMER1 que toma entre las interrupciones del TIMER1_CAPT, así que entre dos bordes descendentes de la señal. Pero al medir la frecuencia en el osciloscopio, obtengo alrededor de 370 kHz (constante), entonces, ¿por qué los valores difieren tanto? Entiendo que difieren en un factor pequeño, pero esos valores por debajo de 30, simplemente no tienen sentido ...

Gracias de antemano!

P.S.

Lo siento por el mal esquema, pero no puedo usar el editor de esquemas incorporado por alguna razón ...

    
pregunta Golaž

1 respuesta

1

¿Es consciente de que es muy probable que los circuitos sintonizados L y C produzcan una serie de oscilaciones que decaen a cero y que su código debe descifrar la serie de pulsos provenientes del comparador en algo significativo?

Quizás también sepa que la energía L y C produce una onda sinusoidal decadente centrada alrededor de 0V y esto podría dañar su comparador: el LM393 tiene un voltaje de entrada absoluto de -0.3 voltios y, si se excede, podría causar daños permanentes al dispositivo. Como mínimo, arruinará la señal que espere medir.

Si desea mantener la señal lo más intacta posible (por ejemplo, en una aplicación de detección de metales), sería aconsejable colocar una resistencia en serie entre la entrada del comparador y el circuito sintonizado, luego desviarlo a aproximadamente la mitad de Vcc con la mitad de Vcc en la otra entrada del comparador.

    
respondido por el Andy aka

Lea otras preguntas en las etiquetas