Hallo!
Ich bin gerade dabei die Drehzahl eines Motors zu erfassen.( siehe unter Sensor GP1A038 RNControl Rnkeylcd) Die Genauigkeit der Meßergebnisse laßt jedoch zu wünschen. Einige Änderungen an der Hardware haben das Ergebnis verbessert, doch nun bin ich auf ein anderes Problem gestoßen, das ich mir nicht erklären kann.
Dazu habe ich unten die Meßsoftware eingefügt, die um alles angespeckt ist, was nicht zum Timer prüfen notwenig ist. Das hat das Ergebnis schon verbessert.
Programmablauf
- Timer 1soll alle 0,5 sec einen Interrurt auslößen
- währen dieser Zeit wird der Zähler Z hochgezählt
Do
Z = Z + 1
If Timer1interrupt = 1 Then Ausgabe_nach_timer1int
Loop
- Kommt der Interrupt wird der Zählerwert auf das RNkeylcd ausgeben.
Da nichts anderes passiert ( auch Meßfühler ist abgezogen) sollte Z immer gleich sein. +/- 1 ist ok. ( Anzeige 10840/10841) Aber in mehr oder weniger regelmäßigen Abständen schwanken die Werte von max 10791 ... 10841.
Nun ist die Frage, braucht der Timer1 länger zum Höchzähler, also bis zum Auslösen des Timerinterrupts, was auch die Schwankungen der Drehzahllmessung im Originalprogramm erklären würde,
oder werden beim Durchlaufen der Schleife hin und wieder noch andere Aufgaben vom Prozessor ausgeführt, so das die Schleifendurchläufe sinken.
andreas
Code:'########################################################################## 'Probe Timer1.BAS ' 'Test 27.06.08 ' Hardware RN-Contreol + RNkeylcd '##########################################################################` ' --------------- RN-Control Anweisungen ------------------- $regfile = "m32def.dat" $hwstack = 64 $framesize = 64 $swstack = 64 $crystal = 16000000 'Quarzfrequenz '$baud = 9600 ' --------------- RN-Control Hardwareconfiguration ---------- Config Scl = Portc.0 'Ports fuer IIC-Bus Config Sda = Portc.1 Config Int0 = Rising ', Nosave ' Interupt0 für steigende Flanke def ' . Nosave speichert register nicht Config Timer1 = Timer , Prescale = 256 ' Vorteiler vom Timer1 wird auf 256 gestellt ' --------------------- Variablendeklaration ---------------- Dim Impulseprominute As Long Dim Impulseprosekunde As Integer Dim K As Integer Dim Le As Byte Dim Rnkeylcd_befehl As String * 4 Dim Text As String * 80 Dim Timer1interrupt As Byte 'Dim Umdrehungenprominute As Integer Dim Zaehlerirq0 As Integer Dim Z As Integer ' --------------------- Konstantendeklarationn -------------- Const Markierungenproscheibe = 120 'Scheibe für GP1S23 hat 120 Markierungen Const Rnkeylcd_slaveid_write = &H40 'I2C SlaveAdresse Const Rnkeylcd_slaveid_read = &H41 Const Timervorgabe = 34286 'Timervoreinstellung um bei Vorteiler 256 und Takt 16 MHz 'Auslösung alle 0,5 sec ' -------------------- I2cbus init ---------------------------- Wait 1 'Warte bis LCD bereit I2cinit 'I2C bus init ' ---------------------- Routinendeklaration ------------------ Declare Sub Ausgabe_nach_timer1int() Declare Sub Rnkeylcd_cursorpos(byval Spalte As Byte , Byval Zeile As Byte) Declare Sub Rnkeylcd_lcd_ausgabe() Declare Sub Rnkeylcd_lcd_loeschen() ' ---------------------- Hauptprogramm ------------------------ Zaehlerirq0 = 0 'Zähler für Striche auf der Codescheibe auf 0 On Int0 Irq0 ' bei INTO Routine Irg0 aufrufen Enable Int0 'Interupt INT0 einschalten On Timer1 Timer_irq ' wenn Timer1 interrupt auslöst Routine Timer_irq aufrufen Enable Timer1 'Timer1 ein Enable Interrupts ' alle Interrupts einschalten Rnkeylcd_lcd_loeschen Timer1interrupt = 0 Z = -32768 Do Z = Z + 1 If Timer1interrupt = 1 Then Ausgabe_nach_timer1int Loop End ' ---------------------------------------------------------------------------- Sub Ausgabe_nach_timer1int() Timer1interrupt = 0 Text = " " 'Impulseprominute = Impulseprosekunde * 60 'Umdrehungenprominute = Impulseprominute / Markierungenproscheibe Text = "Zähler : " + Str(z) Rnkeylcd_cursorpos 2 , 2 Rnkeylcd_lcd_ausgabe Z = -32768 End Sub Sub Rnkeylcd_lcd_ausgabe() Le = Len(text) I2csend Rnkeylcd_slaveid_write , Text , Le End Sub Sub Rnkeylcd_cursorpos(byval Spalte As Byte , Byval Zeile As Bit Byte) ' Cursor auf Pos Rnkeylcd_befehl = Chr(27) + Chr(79) + Chr(spalte) + Chr(zeile) I2csend Rnkeylcd_slaveid_write , Rnkeylcd_befehl , 4 End Sub Sub Rnkeylcd_lcd_loeschen() 'Local Rnkeylcdbefehl As String * 2 Rnkeylcd_befehl = Chr(12) I2csend Rnkeylcd_slaveid_write , Rnkeylcd_befehl , 1 End Sub ' ---------------------- Interruptroutinen ------------------------------- Irq0: 'Pro Impuls (Markierung auf Scheibe) ein Aufruf Incr Zaehlerirq0 Return Timer_irq: 'Pro Sekunde zwei Aufrufe Timer1 = Timervorgabe 'Impulseprosekunde = Zaehlerirq0 Zaehlerirq0 = 0 Timer1interrupt = 1 Return 'programmlänge 1278 dec







Zitieren

Lesezeichen