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







Zitieren
Lesezeichen