-
        

Ergebnis 1 bis 8 von 8

Thema: Drehzahlmesserprogramm funktioniert nur bis 7000 U/min HILFE

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    25.07.2007
    Beiträge
    18

    Drehzahlmesserprogramm funktioniert nur bis 7000 U/min HILFE

    Anzeige

    Hallo !

    Ich habe hier ein Programm für einen Drehzahlmesser gefunden.
    Benutze einen Mega 32 und 16 MHz Quartz.

    Meine Frequenz liegt zwischen 20Hz und 200Hz.

    Der Quellcode zeigt mir Frequenzen bis 117MHz (7000 U/min) richtig an.

    Ab dann springt die Anzeige zurück auf 6000 und die Zählung wird fortgesetzt.

    Woran kann denn das liegen ?

    Wenn ich mir nur das Timerergebnis anzeigen lasse stimmt dieses über den ganzen Bereich. Der Fehler muss also in der Berechnung oder den Variablen liegen oder ?

    Danke für eure Antwort.

    Gruß

    Hier der Code:

    '-------------------------------------------------------------------
    ' Drehzahlmesser mit
    ' Messung der Periodendauer mit Timer1
    '-------------------------------------------------------------------
    $regfile = "m32def.dat" 'Mega32
    $crystal = 16000000 '16 MHz Quarz

    Config Pind.6 = Input
    Portd.6 = 1

    Dim Impulse As Byte
    Dim D As Long
    Dim W As Long
    Dim W1 As Long
    Dim W2 As Long
    Dim W3 As Long
    Config Timer1 = Timer , Prescale = 64 , Capture Edge = Rising

    Config Lcd = 16 * 2 , Chipset = Dogm162v5
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5

    Waitms 50

    Gosub Dog

    On Ovf1 Overflow
    On Icp1 Steigende_flanke
    Enable Icp1
    Enable Ovf1

    Enable Interrupts




    Main:

    D = 0
    W3 = 0

    Impulse = 0

    Cls
    Cursor Off

    Locate 1 , 1

    Lcd "Drehzahl"

    Locate 2 , 1

    Lcd D

    Lcd " UpM "


    Tcnt1l = 0
    Tcnt1h = 0


    Do

    nop

    Loop

    End


    Steigende_flanke:

    Disable Icp1
    Disable Ovf1

    W3 = Timer1

    Timer1 = 0

    W2 = W2 + W3

    Incr Impulse

    If Impulse = 6 Then

    W1 = W2 * 400

    W = W1 / 60


    D = 600000000 / W

    Locate 2 , 1

    Lcd D

    Lcd " UpM "

    W = 0
    W2 = 0
    W3 = 0
    D = 0
    Impulse = 0

    Else

    End If

    Enable Icp1
    Enable Ovf1

    Return


    Overflow: ' Timer1 Ueberlauf, bei Stillstand.

    Disable Icp1 ' Zahler auf Null setzen.
    Disable Ovf1

    D = 0

    Locate 2 , 1

    Lcd D

    Lcd " UpM "

    W = 0
    W2 = 0
    D = 0

    Enable Icp1
    Enable Ovf1
    Timer1 = 0
    Return




    ' ---------------------- LCD DOG162 Initialisieren -----------------------------

    Dog:
    Portb = &B00000011 : Gosub Enbl : Waitms 2 ' dummy Funktion Set
    Portb = &B00000011 : Gosub Enbl : Waitms 2 ' dummy Funktion Set
    Portb = &B00000011 : Gosub Enbl : Waitms 2 ' dummy Funktion Set
    Portb = &B00000010 : Gosub Enbl : Waitms 1 ' dummy Funktion Set
    Portb = &B00000010 : Gosub Enbl : Waitms 1 ' Funktion Set 1
    Portb = &B00001001 : Gosub Enbl : Waitms 1 ' Funktion Set 2
    Portb = &B00000001 : Gosub Enbl : Waitms 1 ' Bias 1
    Portb = &B00001100 : Gosub Enbl : Waitms 1 ' Bias 2
    Portb = &B00000101 : Gosub Enbl : Waitms 1 ' Power/Icon/Contrast 1
    Portb = &B00000010 : Gosub Enbl : Waitms 1 ' Power/Icon/Contrast 2 Contrast =38
    Portb = &B00000110 : Gosub Enbl : Waitms 1 ' Follower control 1
    Portb = &B00001001 : Gosub Enbl : Waitms 1 ' Follower control 2
    Portb = &B00000111 : Gosub Enbl : Waitms 1 ' Contrast Set 1
    Portb = &B00000000 : Gosub Enbl : Waitms 1 ' Contrast Set 2 Contrast =38
    Portb = &B00000000 : Gosub Enbl : Waitms 1 ' Display On 1
    Portb = &B00001100 : Gosub Enbl : Waitms 1 ' Display On 2
    Portb = &B00000000 : Gosub Enbl : Waitms 1 ' Clear Display 1
    Portb = &B00000001 : Gosub Enbl : Waitms 2 ' Clear Display 2
    Portb = &B00000010 : Gosub Enbl : Waitms 1 ' Funktion Set 1
    Portb = &B00001000 : Gosub Enbl : Waitms 1 ' Funktion Set 2
    Portb = &B00000000 : Gosub Enbl : Waitms 1 ' Entry Mode Set 1
    Portb = &B00000110 : Gosub Enbl : Waitms 1 ' Entry Mode Set 2
    Portb = &B00000000
    Return
    Enbl: ' Enable ein
    Set Portb.4
    Waitus 400 ' Enable aus
    Reset Portb.4
    Return
    Rw:
    Set Portb.5
    Waitus 400
    Reset Portb.5
    Return

    End

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    25.07.2007
    Beiträge
    18
    Problem hat sich erledigt.

    Habs geschafft.

    Habe die Capture ISR wie folgt geändert:

    Code:
    Steigende_flanke:
    
    Disable Icp1
    Disable Ovf1
    
     W = Timer1
    
       Timer1 = 0
    
    Incr Impulse
    
       If Impulse = 6 Then
    
    
             D = 15000000 / W
    
    
          Locate 2 , 1
    
          Lcd D
    
          Lcd " UpM     "
    
           W = 0
           D = 0
              Impulse = 0
    
            Else
    
            End If
    
           Enable Icp1
          Enable Ovf1
    
         Return

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,

    wenn du schon Capture verwendest könntest du auch das Capture-Register auslesen, dann wirds evtl. etwas genauer, da dort der Wert des Timers gesichert wird, als das Event aufgetreten ist. Man hat dann die Zeit erst andere Sachen zu erledigen, bzw. als erstes den Timer auf 0.

    Dann musst Du in der ISR auch die beiden ISR's nicht disablen, da in dieser Zeit sowieso keine weitere auftreten kann, evtl. am Ende der ISR diese Flags zurücksetzen falls doch eine aufgetreten sein sollte. Aber zumindest kann man sich am Anfang die Zeit sparen.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    25.07.2007
    Beiträge
    18


    Dachte ich hätte es schon richtig gemacht ?

    Wie würde deine Lösung dann aussehen ?

    Sorry aber bin neu auf dem Gebiet und freue mich immer über jede Lösung die ich finde.

    So ganz perfekt ists noch ned. Ich will eigentlich die Drehzahl immer nur in Hunderter Werten haben.

    Die Lösung hab ich aber noch ned gefunden. Weißt du das vielleicht abhilfe ?

    Gruß Tommy

    EDIT:

    So oder ?

    Code:
    Steigende_flanke:                                           'ISR für Capture Ereignis
    
    'Disable Icp1
    'Disable Ovf1
    
       Timer1 = 0
    
     W = Capture1
    
    
                                                                'Timer löschen
    
    Incr Impulse
    
       If Impulse = 6 Then                                      'Damit die Anzeige ruhiger wird nur jeden 6.Impuls messen
    
    
             D = 3750000 / W                                    ' bei Prescaler 256 und 16Mhz
                                                                ' 60000000 µs / 16µs = 3750000
                                                                ' geteilt durch die Counts gibt Drehzahl
    
             Select Case D:                                     'Schaltblitz ab 10500 U/min
                Case 0 To 10499 : Led = 0
                Case 10500 To 12000 : Led = 1
             End Select
    
          Locate 2 , 1
    
          Lcd D
    
          Lcd " UpM     "
    
           W = 0
           D = 0
              Impulse = 0
    
            Else
    
            End If
    
           'Enable Icp1
          'Enable Ovf1
          W = 0
    
         Return

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Wenn jeder gleich alles richtig machen würde, gäbs wohl keine Foren wie dieses hier

    Hab nur noch ein paar Tipps:
    Die LCD-Sachen aus der ISR rauslassen, das dauert sonst viel zulange,
    bau das ins Hauptprogramm, und mit einem Waitms 500, oder so, dazwischen.
    So in etwa:
    Code:
    ' Hauptschleife
    Do
        Disable Interrupts
        ' LCD-zeugs ...
    
        Enable Interrupts
        Waitms 500
    Loop
    Die Interrupts kann man hier ruhig kurz anhalten (wegen der langen Variablen), denn sollte in dieser Zeit in IRQ auftreten, merkt sich das Capture-Register den Timer-Wert, und gleich nach dem aktivieren wird die ISR aufgerufen.

    Ansonsten könnt's schon was werden.

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    25.07.2007
    Beiträge
    18
    da hast recht ja.

    Werd ich probieren.

    Mit den Zahlen auf hunderter anzeigen weißt au ned zufällig an rat ?

    Mal was andres. Dieser Drehzahlmesser soll zusammen mit andren Sachen auf einem Screen angezeigt werden.

    Unter andrem lese ich geschwindigkeit vom GPS und welcher gang eingelegt ist über gangsensor aus und zeige es zusammen mit der drehzahl an.

    Wenn mir nun dauernd ein interrupt vom capture das andre unterbricht ist das doch schlecht oder ?

    Gibts ne andre Möglichkeit die Drehzahl zu messen ohne interrupt oder ...

    Gruß Tommy

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Wenn du nur auf hundert genau haben willst, einfach den Wert /100, und zwei nullen hinten dranhängen.

    Drehzahlmessen ohne Interrupt wird wohl schlecht gehen, man braucht ja ein definiertes Ergeignis (Zeit) damit man sich den Rest ausrechnen kann.

    Du musst nur die ISR's so kurz wie möglich halten (evtl. auch die Berechnungen rausnehmen), und alle Ausgaben im Hauptprogramm machen. Dann klappts auch mir dem restlichen Programm.

    Und, je schneller die Anzeige aktualisert wird, desto schlechter wird es das zu erkennen falls sich der Wert jedesmal ändern sollte, deswegen kann das ruhig im Hauptprogramm erledigt werden.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    25.07.2007
    Beiträge
    18
    Okay, ich werde mal alle routinen zu einem Proggi zusammen basteln und dann probieren wie es klappt.

    Ja, natürlich. Ich depp ....

    Geteilt durch hundert und dann "00" anstellen. TS TS TS

    Ich mach schon zulange....

    Danke dir...

    Gruß Tommy

Berechtigungen

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