-
        

Ergebnis 1 bis 2 von 2

Thema: Timer 1 Genauigkeit

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    03.12.2007
    Beiträge
    19

    Timer 1 Genauigkeit

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    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

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.254
    Hallo asunn,

    vorweg: ich kann dir versichern, daß die Timer der Atmegas genau sind.

    Ich habe dein angehängtes Programm nur überflogen.
    Wenn du willst, daß man sich damit beschäftigt, solltest du es besser formatiern und kommentieren. Nicht jeder hat Lust, sich durch deine auskommentierten Vorversuche zu navigieren.

    Wo ist die Baudratenfestlegung?

    Z ist ein Integer. Weißt du, wie weit der Wertebereich bei diesem geht?

    Deine Do-Loop- Schleife macht nur das Zählen, bei dem Wertebereich von Z kann ich mir mehrere Überläufe pro Timer1-Interrupt vorstellen.

    Gruß, Michael

Berechtigungen

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