-         

Ergebnis 1 bis 5 von 5

Thema: Nach Reset falsche Berechnung!?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    18.05.2008
    Beiträge
    26

    Nach Reset falsche Berechnung!?

    Anzeige

    Hallo!
    Ich habe auf einem Mega16 mit dem RN-Control Board unter Bascom eine Drehzahlmessung (und Drehgradientenmessung) programmiert (s.u.). Das Programm funktioniert auch soweit. Das einzige Problem ist, dass wenn man den Reset-Taster betätigt, während eine Frequenz am Interrupt anliegt, viel zu große Werte raus kommen, und zwar immer die gleichen, bei der jeweiligen Frequenz. Das geschieht nicht, wenn man Reset betätigt während keine Frequenz anliegt. Nach dem Starten des Programms kann dann die Frequenz verändert werden, was auch richtig angezeigt wird. Teilweise tritt dieser Fehler auch einfach so auf, bei höheren Frequenzen. Und dann kommt man nicht mehr auf einen vernünftigen Wert zurück, ohne die Ferquenz auf Null zu fahren und dann Reset zu drücken.
    Sollte der Controller bei einem Reset das Programm nicht von ganz vorne starten?? Wenn das so wäre müsste auch bei anliegender Frequenz ein richtiger Wert angezeigt werden, oder??
    Hat jemand ne Idee, wo der Fehler liegen könnte?


    Hier mein Programm:
    Code:
    '###################################################
    'LVA_Drehzahlmessung.BAS
    
    'Diese Programm ermittelt über die Signale einer Lichtschranke
    'die Drehzahl am Motorenprüfstand 1 des LVA an der Fachhochschule Köln.
    'Die ermittelte Drehzahl und der Drehzahlgradient werden an D/A-Wandler gegeben,
    'die eine analoge Spannung ausgeben, für die Weiterverarbeitung in der folgenden
    'Regelungselektronik.
    
    'Autor: Christian Hungenberg
    '#######################################################
    
    
    
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000                                         'Angabe der Quarzfrequenz
    $baud = 9600
    
    
    Config Int0 = Falling                                       'Der Interrupt wird bei fallendem Flankensignal aktiviert
    Config Timer1 = Timer , Prescale = 256                      'Timer 1 (16-bit Timer)
    
    
    Config Spi = Soft , Din = Pinc.5 , Dout = Portc.1 , Ss = None , Clock = Portc.0       'Konfiguration der Software SPI
    Config Portc.2 = Output                                     'Ausgang für CS1
    Config Portc.3 = Output                                     'Ausgang für CS2
    
       Portc.2 = 1                                              'CS1 auf High
       Portc.3 = 1                                              'CS2 auf High
    
    Dim Pointer As Byte                                         'zeigt dei aktuelle Speicherstelle für die Impulse an
    Dim Array(24) As Byte                                       '24 Speicherstellen für Impulse
    Dim Impulszaehler As Long                                   'Zaehlt die Impulse der Lichtschranke waehrend 10ms (dies ist die Timerzeit)
    Dim Impulse As Long                                         'in dieser Variablen werden die gezaehlten Impulse für die Berechnung gespeichert
    Dim Drehzahl_alt As Single                                  'zur Berechnung des Gradienten speichtert diese Variable den vorangegangenen Drehzahlwert
    
    Dim Drehzahl_neu As Single                                  'Drehzahl in 1/min, als Dezimalwert
    Dim Umdpm1 As Byte
    Dim Umdpm2 As Byte
    Dim Umdrehungenprominute As Word At Umdpm1 Overlay          'enthaelt den aktuellen Drehzahlwert in 1/min, als ganzzaligen Wert fuer DAC
    
    Dim Drehgradient As Single                                  'für die Berechnung des Gradienten als Dezimalwert
    Dim Grad1 As Byte
    Dim Grad2 As Byte
    Dim Gradient As Word At Grad1 Overlay                       'enthaelt den Drehzahlgradienten in U/s2, als gangzzahligen Wert fuer DAC
    Dim I As Integer
    Dim Syncro As Byte                                          'synchronisiert die Ausgabe mit der Berechnung
    
    
    Pointer = 1                                                 'Pointer zeigt auf die erste Speicherstelle
    Impulszaehler = 0
    Impulse = 0
    Drehzahl_neu = 0
    Syncro = 0
    
    
    On Int0 Irq0                                                'bei fallenden Flanken wird der Interrupt ausgeloest und ruft Irq0 auf
    Enable Int0
    
    On Timer1 Timer_irq                                         'beim Ueberlaufen des Timers wird die Routine Timer_irq aufgerufen
    Enable Timer1
    
    Enable Interrupts
    
    
    
    Do
       If Syncro = 1 Then
          Drehzahl_neu = Impulse * 2.5                          'Berechnung der Drehzahl: Imp/(BZ*100)*60    Imp=1; BZ=0,24
          Drehgradient = Drehzahl_neu - Drehzahl_alt            'Berechnung der Drehzahländerung für Gradienten
          Drehgradient = Drehgradient * 10                      'Gradient = Drehzahländerung * Kerwert der Zeiteinheit (1/0,01s)
          Drehzahl_alt = Drehzahl_neu                           'Speichern der neuen Drehzahl als alte fuer naechste Berechnung der Drehzahlaenderung
          Drehzahl_neu = Drehzahl_neu * 0.4096                  'Umrechnung von Drehzahl 0...10.000 auf Binaerzahl 0...4096  (10.000/4096)^-1
          Umdrehungenprominute = Round(drehzahl_neu)
    
             Portc.2 = 0                                        'CS1 auf LOW
                Spiinit
                Spiout Umdpm2 , 1                               ' Bit 15 - BIT 8
                Spiout Umdpm1 , 1                               ' Bit 7 - BIT 0
             Portc.2 = 1                                        'CS1 auf High
    
       If Drehgradient > 0 Then
          Drehgradient = Drehgradient * 2.048                   'Umrechnung von Drehzahlgradient 0...2.000 auf Binärzahl 0...4095 (2.000/4096)^-1
          Gradient = Round(drehgradient)
          Else
          Gradient = 0
          End If
    
             Portc.3 = 0                                        'CS1 auf LOW
                Spiinit
                Spiout Grad2 , 1                                ' Bit 15 - BIT 8
                Spiout Grad1 , 1                                ' Bit 7 - BIT 0
            Portc.3 = 1                                         'CS1 auf High
        'Print Impulse
        'Print Impulszaehler
        'Print Drehzahl_neu
    
       Syncro = 0
       End If
    
    Loop
    
    End
    
    
    
    Irq0:                                                       'Pro Impuls (Markierung auf Scheibe) ein Aufruf
       Incr Impulszaehler
    Return
    
    
    
    
    Timer_irq:                                                  'wird beim Ablauf der Berechnungszeit aufgerufen
       Impulse = Impulse + Impulszaehler                        'addiert die Impulse der neuen 10ms
       Impulse = Impulse - Array(pointer)                       'subtrahiert die Impulse der 10ms-Zeiteiheit vor 240ms
       Array(pointer) = Impulszaehler                           'speichert die Impulse der aktuellen 10ms-Zeiteinheit in den aktuellen Speicherplatz
       Impulszaehler = 0                                        'resetet den Impulszaehler
    
       If Pointer = 24 Then                                     'hier wird der Pointer um den Wert "1" hoch gesetzt, nach 24 fängt er von vorne an
          Pointer = 1
          Else
          Incr Pointer
       End If
    
       Timer1 = 64911                                           'laed den timer vor, dies definiert die Timerzeit
       Incr Syncro                                              'fuer die Sychronisierung der Ausgabe mit der Berechnung
    Return

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo,
    ich habe mir dein Programm jetzt nicht genauer angesehen. Aber könnte es sein, dass der µC schon einen Interrupt durch die extern anliegende Frequenz bekommt, bevor er nach einem Reset in die Hauptschleife kommt? Und könnte es deshalb sein, dass da etwas anders abläuft, als du es dir vorstellst?
    Vielleicht kannst du das mal checken.

    Gruß

    Rolf

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    18.05.2008
    Beiträge
    26
    Hallo!
    Erst mal danke für die Antwort! Es ist gut möglich, dass der uC schon einen Interrupt bekommt, da die Frequenz ja auch während des Reset anliegt. Dann kann es auch gut sein, dass Interrupts ausgelöst werden wenn das Programm noch gar nicht in der Hauptschleife ist. Nach meinem Verständnis müsste dann aber meine Zählvariable (Impulszaeher) einfach beim ersten mal eine zu gro0e Zahl anzeigen. Sie wird aber bei jedem Durchlauf Null gesetzt und müsste doch demnach beim zweiten Durchlauf schon richtig sein, oder nicht? Auch wenn ich die Frequenz am Interrupt bei Auftreten des Fehlers auf Null stelle, dann wird der Ausgabewert nicht Null was er nach der Berechnung eigentlich müsste.
    Gruß Christian

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2007
    Beiträge
    594
    Interrupt erst aktivieren, wenn alles andere eingestellt ist?

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    43
    Beiträge
    2.240
    hat er, der SEI kommt erst direkt vor der mainloop,
    sollte gehen. der SPIINIT ist falsch platziert fällt mir
    gerade auf ... sollte aber damit auch nix zu tun haben.
    würd ihn dennoch gleich hinter die Config SPI hängen,
    ist da sinnvoller aufgehoben und muss auch nur einmal
    ausgeführt werden, beschleunig auch etwas das progrämmchen.
    ... hat aber auch nicht direkt mit dem problem zu tun.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

Berechtigungen

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