-         

Ergebnis 1 bis 6 von 6

Thema: Problem mit Frequenzmessung

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.11.2004
    Beiträge
    17

    Problem mit Frequenzmessung

    Anzeige

    Hi User,
    Ich bin dabei ein Programm zur Frequenzmessung zu schreiben, und bin dabei auf ein Problem gestoßen.
    Der Ablauf soll folgender sein:
    Es wird eine Messzeit von einer halben Sekunde vorgegeben. Innerhalb dieser Zeit, soll eine Zählvariable bei jeder einkommenden Highflanke eines Rechtecksignals, mit TTL Pegel, um eins erhöht werden. Nach ablauf der Zeit wird der Wert der Zählvariable an eine Funktion für RS232 übergeben.
    Wie kann man das Erhöhen der Zählvariable in diesem Zeitraum realisieren? Daran scheitert mein Programm noch. Ich glaube es wartet nicht, bis der vorgegebene Messzeitraum abgearbeitet ist.
    Ich programmiere übrigens in C, wäre aber auch für einen Tipp mit Assembler dankbar, denn man lernt es ja nebenbei irgendwie auch.
    Mein C Quellcode für das Problem sieht so aus:

    z=0; //Zählerwert=0
    while(messzeit()==1)
    {
    if (input==1)
    {z++;} //Zählerwert erhöhen
    }
    sendfreq(z); //Zählerwert senden

    Input ist dabei die Pegelabfrage des Pins.

    MfG TB1

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.10.2004
    Ort
    ferd. Waldmüllerg. 7/2
    Alter
    32
    Beiträge
    456
    Frage, wie schaut deine messzeit-Funktion aus? Also, ist das durch einen Timer gelöst, oder inkrementierst du darin weitere Variablen? Was für ein Datenwert hat z und was ist die maximale Frequenz, die gemessen werden soll (es könnte leicht z.b. bei einem char, als 8 bit zu einem Überlauf kommen). Wäre gut zu wissen, wie auch, ob die RS232 Sende-Funktion wirklich funktioniert (also halt, dass du statt z immer zb 0x32 an den PC sendest und es auch so ankommt.

    Ansonsten, versuch mal deine while-Schleife durch eine do-while-Schleife zu ersetzten, damit schaffst du zumindest, dass diese mindestens einmal durchlaufen wird.
    MfG
    Mobius

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    23.11.2004
    Beiträge
    17
    Bei z handelt es sich um eine 16 Bit Variable. Die Sendefunktion funktioniert in anderen Programmen zuverlassig. Die Frequenz wird im Bereich zwischen 3 KHz und 8 KHz liegen. Sollte für einen 20 MHz PIC eigentlich kein Problem sein. Das mit der Do-while Schleife probiere ich mal. Mehrfachdurchlauf sollte sich mit einer darumliegenden Endlosschleife regeln lassen. Melde mich, was draus geworden ist.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    43
    Beiträge
    2.240
    Sorry, ich arbeite mit AVRs, die haben für den Timer auch eine Funktion als Counter eingebaut, kann das evtl. der PIC auch?
    bei Deiner Funktion seh ich ein Problem bei niedrigen Frequenzen,
    weil ja Dein Programm während eines Zyklus der Eingangsspannung evtl.
    mehmals durchlaufen kann:

    input==1

    würde dann jedesmal hochzählen, ohne das ein High-Low-Wechsel erfolgte

    while(messzeit()==1) {
    while(input==1){
    }
    while(input==0){
    }
    z++;
    } ... oder so, bin in c nicht so ganz firm eher PHP ... wie man merkt
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.10.2004
    Ort
    ferd. Waldmüllerg. 7/2
    Alter
    32
    Beiträge
    456
    Jop, ein CCP(Capture-Compare-PWM)-Modul zu nutzen wäre die einfachste Möglichkeit. Leider besitzen diesen nur die PICs, die einen Timer2 (also 3 Timer) implementiert haben.
    Eine andere Möglichkeit, ein CCP zu simulieren ist, z.B.: Timer0 (oder 1 bei 16bit) zu starten und dann per I/O-Interrupt den aktuellen Wert des Timer-Registers zu überprüfen.

    Aber ich versteh schon, was du meinst ist eine Flanken-Erkennung. Hum, das würde ich eher so lösen:
    Code:
    var input_old=0;
    
    while (messzeit==1)
    {
       if(input!=input_old) //flanke erkannt
       {
          if(input>input_old) //steigende Flanke
          {
             z++;
          }
       }
       input_old=input;  //letzten Zustand speichern
    }
    Also, man kann natürlich das ganze auch in eine if-Abfrage quetschen, ich habe das aber so geschriebene, dass, die Abfrage relativ schnell ist, so lange keine Flanke erkannt wird. Die Art der Variable "input_old" muss natürlich mit der von "input" übereinstimmen.

    Das mit den Flanken hätte mir aber echt auch auffallen müssen, vor allem weil ich gerade ein C-Programm für I²C-Emulation in Dos schreib und ich da nur mit Flanken zu tun habe. Hab wohl, wie man so schön sagt, den Wald vor lauter Bäumen nimmer gesehen
    MfG
    Mobius

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    23.11.2004
    Beiträge
    17
    Hi Mobius,
    Ich hab deinen Code mal probiert, aber mein Compiler kommt damit nicht klar. Hab's umgeschrieben, half leider auch nichts.

    Vielleicht kann mir jemand mal die Initialisierung des Capture und Timer1 zeigen. Hab das zwar schon selber versucht, hat aber nicht funktioniert. Manchmal fehlt mir wahrscheinlich die Übersicht, was alles nötig ist, um das Init korrekt auszuführen.

    MfG TB1

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •