Drehzahlmessung

Gast #411605
Lesenswert?

Ich will die Drehzahl von einem Lüfter messen. Ich bewerkstellige dies
mit dem Input Capture Interrupt auf einem AT MEGA 644.Das funktioniert
auch ganz gut.
Allerdings hängt er wenn der Lüfter steht(Signal des Lüfters ist dann
high).
Das UP Drehzahlermittlung wird von main aufgerufen und die Drehzahl
anschließend in main seriell audgegeben.

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

uint32_t abs_Zaehler=0;
uint8_t Ueberlauf=0;
uint8_t Ueberlauf_alt=0;
uint32_t Zaehler[2];
uint8_t i=0;
uint8_t p=0;
uint32_t Drehzahl1;

int Drehzahlermittlung(void)
{
    i=0;
    p=0;
    Drehzahl1=0;
    Zaehler[0]=0;
    Zaehler[1]=0;
    Ueberlauf=0;
    Ueberlauf_alt=0;
    abs_Zaehler = 0;

    OCR1A = 11520;
    TIMSK1 |= (1<<ICIE1)|(1<<OCIE1A);
    TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10);

    PORTC |= (1<<PC4);
    do
    {
   if(i==2)
        {
          abs_Zaehler= ( (Zaehler[1] - Zaehler[0])+((Ueberlauf-
          Ueberlauf_alt)*11520) );
          Drehzahl1 = ( (60*115200)/(abs_Zaehler) );
          return Drehzahl1;
          p=1;
        }
  else
  {
          Drehzahl1 = 0;
  }
     }while( (p |= 1) || (Ueberlauf >= 2) );

     if( (p==0)&&(Ueberlauf >= 3) )
  {
    Drehzahl1 = 0;
    return Drehzahl1;
  }
     PORTC &= ~(1<<PC4);
}

ISR(TIMER1_CAPT_vect)
{
  Zaehler[i] = ICR1;
  if(i==0)
  {
    Ueberlauf_alt = Ueberlauf;
  }
  i++;
}

ISR(TIMER1_COMPA_vect)
{
  Ueberlauf++;
}
Gast #411608
Lesenswert?

Habe ich der Übersichtlichkeit weggeleassen.

ISR(TIMER1_COMPA_vect)
//tritt auf wenn der Counter 11520 (OCR1A) erreicht

ISR(TIMER1_CAPT_vect)
// kopiert Zählerstand bei Capture Event in Variable.
// bei erstem Auftreten wird der Stand des Überlaufzählersin
//Überlauf_alt gespeichert

int Drehzahlermittlung(void)
//OCR1A = Counter Obergrenze
//TIMSK1 Input Capture Interrupt enable und Counter Interrupt enable
//(wenn Counter Obergrenze erreicht)
//TCCR1B CTC(Clear Counter on Compare Match) Mode4 Prescaler 64
//(Fcpu=7,3728MHz

//if Schleife, falls Capture event 2 mal aufgetreten ist
// berechnet den absoluten Zähler aus Differenz der beiden
//Counterwerte + Eventuelle Counterüberlaufe*der Counterobergrenze
// Drehzahl wird mit der Counterfrequenz berechnet. (1/min!)
//Drehzahl wird an main zurückgegeben und seriell ausgegeben

//falls Capture event noch nicht 2mal aufgetreten, dann Drehzahl =0

//In der do while Schleife wird gewartet bis Capture event 2 mal
//aufgetreten ist und die Drehzahl berechnet wurde. Im Fall, dass der
//Lüfter steht wird gewartet bis der Counter 2 Mal übergelaufen ist
//(Da dann keine ISR auftritt

Ich hoffe das macht meine Absicht deutlich
Gast #411617
Lesenswert?

>If Schleife

Gibt es nicht. Es handelt sich dabei um eine Abfrage und keine
Schleife. Schleifen können eine Abfrage zwecks
Abbruchbedingungserfüllungprüfung haben...

p |= 1

Danach ist p auf jeden Fall ungleich 0.
Meinst du vielleicht p!= 1?
Gast #411627
Lesenswert?

@FrankW: Daran lag, das Häkchen bei Erase Device before programming muss
ich versehentlich weggeclickt haben.
Danke

Aber um Grundproblem: Das Programm hängt weiterhin, wenn der Lüfter
steht.

Ist das der richtige interrupt auf den ich warte. Tritt der Counter1
Output Compare A Match auf, wenn mein Counter den Wert in OCR1A
erreicht hat?
Gast #411628
Lesenswert?

>Ist das der richtige interrupt auf den ich warte

Eigentlich schon...
Vielleicht ist aber auch der Overflow-Interrupt...
Teste es doch mit einer LED, die du im Overflow-Interrupt umschaltest.
Das Flackern sollte man schon erkennen können.
Gast #411630
Lesenswert?

ICh habe das Problem eingrenzen können. Der Drehzahl 0 Fall tritt nicht
auf, da Ueberlauf nicht wächst. (Habe es nach der do ahile Schleife
abgefragt).
Hat jemand eine Idee wie ich es anstatt lösen kann.

Ich brauche eine Konstruktion, die wartet bis der Capture Interrupt 2
mal aufgetreten ist, aber maximal bis zB 200ms(wenn der Lüfter steht)
Gast #411635
Lesenswert?

Ich glaube, dass ganze hängt mit der Masse zusammen. Halte ich die Masse
des Lüfters mit der meiner Schaltung getrennt, bekomme ich auch eine
Ausgabe wenn der Lüfter steht, allerdings nichts sinnvolles, sogar
negative Werte.

Da fällt mir überhaupt auf, darf man 2 returns in einem Programm
haben??
Gast #2160011
Lesenswert?

Hi,

ich habe so ziemlich das gleiche Problem wie du. da hier seit langer 
zeit nichts mehr geschrieben wurde, geh ich davon aus, dass dein problem 
erledigt ist.
könntest du mir vllt. den final funktionierenden code zusenden?

danke und grüße

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren