Hallo Allerseits,

ich habe ein kleines Problem beim Auswerten einer Drehzahl mittels Drehgeber. Vielleicht vorab noch etwas zu dem was ich machen will:
Ich möchte einen Reglkreis aufbauen. Also Motor mit PWM über Mikrocontroller regeln. Istdrehzahl soll mit einem Drehgeber (50 Pulse pro Umdrehung) ermittelt werden.

Nun zum eigentlichen Problem. Ich komme mit der Drehzahlerfassung nicht ganz klar. Ich habe ein Programm geschrieben, was mit eigentlich die Drehzahl in min-1 auf dem Display anzeigen soll. Jedoch wird wahllos etwas ausgegeben. Mit einem Oszi konnte ich die Drehzahl rechnerisch ermitteln. Diese lag fast dreimal so hoch wie der Wert den der MC auf dem Display ausgibt.
Ich vermute, dass die Timerfrequenz hier eine große Rolle spielt. Aber vielleicht habt ihr ja einen Rat an was es liegen könnte.

Anbei mein Quelltext:

Code:
 $regfile = "m8def.dat"                                     
 $framesize = 32                                           
 $swstack = 32                                              
 $hwstack = 32
 $crystal = 8000000                                         'Quarz: 8 MHz
 $baud = 9600                                               'Baudrate der UART: 9600 Baud

'*******************Counter für Drehzahlerfassung****************************************************************************

Config Timer2 = Timer , Prescale = 64 , Capture Edge = Rising

'*******************PWM initialisieren (Port B1)****************************************************************************

Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Up , Prescale = 64
Config Adc = Single , Prescaler = Auto
Start Adc                                                   ' ADC aktivieren
'*******************LCD initialisieren**************************************************************************************

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

'*******************Ports initialisieren************************************************************************************

Config Portb.4 = Output                                     'Display
Config Portb.5 = Output                                     'Display
Config Portc.2 = Output                                     'Display
Config Portc.3 = Output                                     'Display
Config Portc.4 = Output                                     'Display
Config Portc.5 = Output                                     'Display

'*******************Variablendeklaration************************************************************************************

Dim S As String * 4                                         'Stringempfang von 4 Stellen
Dim W As Word                                               'Wert vom ADC
Dim X As Word
Dim Drehzahl As Word                                        'Drehzahlwert in min-1
Dim Tcount As Word                                          'Timercount-gesamtzählschritte (overflow+ccount=
Dim Ccount As Word                                          'Timer2 Wert
Dim Overflowc As Word                                       'Overflowzähler
X = 0
Ccount = 0

'*******************Interrupt Routinen & Initialisierung der ser. Schnittstelle************************************************************************************

On Icp1 Oncapture                                           'Interrupt-Routine
On Ovf1 Onoverflow                                          'Interrupt-Routine
Enable Icp1                                                 'Capture-Interrupt
Enable Ovf1                                                 'Overflow-Interrupt
On Urxc Onrxd                                               'Serielle Schnittstelle aktivieren
Enable Urxc
Enable Interrupts                                           'Interrups aktivieren


'*******************Hauptprogramm************************************************************************************

Do
   W = Getadc(0)                                            'Wert vom ADC einlesen
   Compare1a = W                                            'Wert vom ADC an PWM übergeben

   If Len(s) = 4 Then                                       'String ausgeben wenn 4 Zeichen empfangen
         S = ""
   End If

    If Tcount <> 0 Then
      Drehzahl = 150000 / Tcount                            'Umrechnungsfaktor (60min/50 Pulse/ 8us  Zählfrequenz)
    End If

Cls                                                         'Ausgabe Display
Locate 1 , 1
Lcd "OF" ; Overflowc
Locate 1 , 8
Lcd "C" ; Ccount
Locate 2 , 8
Lcd "T" ; Tcount
Locate 2 , 1
Lcd "N:" ; Drehzahl

Loop

'*******************Interrupt Service Routinen ***************************************************************************
 Oncapture:                                                 'Timer Interrupt auf ICP1
    Ccount = Timer2                                         'Erst Wert sichern
    Timer2 = 0                                              'Sofort Timer-Reset
    X = Overflowc * 256                                     'Überlauf * 8bit Timerstellen
    Tcount = X + Ccount                                     'Tcount aus Überlauf und Restzeit vom Timer zusammenbauen
    Overflowc = 0                                           ' Overflow Variable zurücksetzen
    Return

Onoverflow:                                                 'Timerüberlauferkennung
   Incr Overflowc
Return

Onrxd:
   S = S + Chr(udr)                                         'String zusammenbauen
Return

End
Das Prinzip der Messung ist die Zeiterfassung zwischen 2 Flanken.
Zu Testzwecken lasse ich die Variablenwerte alle auf dem Display erscheinen. Das soll später natürlich nicht sein.

Ich hoffe ihr könnt mir helfen.

Gruß Andy