-
        

Ergebnis 1 bis 7 von 7

Thema: Periodendauermessung Overlayvariable Verständnisproblem

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    37
    Beiträge
    61

    Periodendauermessung Overlayvariable Verständnisproblem

    Anzeige

    Hallo,

    ich habe da ein kleines Verständnisproblem was den Overlayvariable machen. Ich habe eine sehr schönes Worddokument im WWW entdeckt wo einige Beispiele zum Bascom programmieren drin sind. Allerdings checke ich den Code nicht so ganz. (Was macht der Programmierer da?).

    Das Grundprinzip ist der Periodendauermessung ist mir klar.
    Warten bis Eingang = 0: definierter Beginn
    Warten bis Eingang = 1
    Zähler starten
    Warten bis Eingang = 0
    Warten bis Eingang = 1
    Zähler stop
    Zähler auslesen und Wert ggf. umrechnen

    Code:
    'Testprogramm für T-Messung über Timer0/Int0
    'Messwerte:
    'Tsoll     Tmess   /us
    '10        keine Reaktion (Int nicht schnell genug)
    '100       98
    '1000      998/999
    '10000     10010 
    '100000    100041
    '1000000   1000424
    
    
    '---------------------------------------------------
    $regfile = "2313def.dat"
    $crystal = 8000000
    $baud = 2400
    
    
    'Periodendauermessung benutzt Int0 und Timer0
    Config Pind.2 = Input
    On Int0 Int0serv
    Config Int0 = Rising
    Enable Int0
    
    'Timer0 für Periodendauermessung
    Config Timer0 = Timer , Prescale = 8                        'Timer-CLK = 8MHz -> TCLK = 1us
    Enable Timer0                                               'Overflow alle  256us
    On Timer0 Timer0overflow
    
    Enable Interrupts
    '-----------------------------------------------------
    
    'Variablen Periodendauermessung
    Dim T As Long At &H60                                       'Periodendauer
    Dim Tvaluel As byte At &H60 Overlay                         'Periodendauer low byte
    Dim Tvalueh As word At &H61 Overlay                         'Periodendauer high word
    Dim T0overflowctr As Word                                   'Zähler für Timer1Overflow
    
    T = 0
    
    '--------------------------------------------------------------------
    Do
    
          Print "T=";
          print T;
          print "us"
    
         waitms 1000
    
    Loop
    '---------------------------------------------------------------------
    
    Int0serv:                                                   'Impulsflanke Lichtschranke
    'Periodendauermessung
     'Werte der alten Periodendauermessung übernehmen:
        Stop Timer0
        Tvaluel = Timer0                                        'Low word von T
        Tvalueh = T0overflowctr                                 'High word von T
    
     'neue Periode messen:
         Timer0 = 0
         Start Timer0
         T0overflowctr = 0
    
    Return
    
    '-----------------------------------
    
    Timer0overflow:
       Incr T0Overflowctr                                       'wieder auf 1.Flanke warten
    return
    '-------------------------------------------

    Allerdings kapier ich nicht, wie und vor allem warum die T-Variable aus zwei Overlayvariablen zusammengesetzt, die man sich aus den zwei Subroutinen holt, und wie dabei das Ergebnis stimmen kann? Kann mir das vielleicht jemand erklären?

    Viele Grüße

    R.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Timer0 ist ein 8-bit Timer, d.h., wenn du ihn ohne Startwert laufen lässt, dann erreicht er nach 256 Schritten einen Overflow. Dies ist der Moment wo die ISR "Timer0overflow". Timer0 selber ist jetzt 0.
    In der Variable T0Overflowctr zählst du nun die Anzahl der Aufrufe, also die Anzahl der Overflows.
    Wenn du die Zeitnahme nun zu irgendeinem Zeitpunkt anhälst, ergibt sich die Zeitdauer aus der Anzahl der Overflows * 256 + den aktuellen Wert von Timer0. Also

    T = T0Overflowctr* 256 + Timer0

    Die Overlay Technik erlaubt dir nun, in T das Ergebnis zu bekommen, ohne es tatsächlich auszurechnen. Anstelle der Multiplikation mit 256 könntest du auch so etwas machen:
    T = T0Overflowctr
    shift T, left, 8
    Du verschiebst also die Bits von T0Overflowctr in T an höherwertige Stellen. Mit dem Overlay schreibst du praktisch direkt auf diese höherwertigen Stellen.
    T reicht im Speicher von Zelle &H60 bis &H63, da T ein Long-Typ ist. Das niegriedwertigste Byte (LSB) steht in &H60, in &H61 das nächst höherwertige. Und genau da wird T0Overflowctr (über Tvalueh) hingeschrieben. Timer0 wird dann noch (über Tvaluel) auf das LSB geschrieben.

  3. #3
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die sache mit dem Overlay wird gemacht, um schnell den 8 Bit wert aus dem Timer 0 und den 16 Bit Wert von den gezählten Überläufen zusammenzustzen zu einer Zeit mit 24 Bit Auflösung, die dann in einer 32 Bit langen variable Steckt. Das wird gemacht statt so etwas zu schreiben wie: zeit = timer + 256 * ZahlDerÜberläufe
    Die Multiplication ist ja einfach ein Verschieben um 1 Byte.

    Im Prinzip kann das so funktionieren, allerdings nicht immer:
    Wenn man Pech hat, gibt es gerade an Anfang in der Interruptroutine, noch vor dem Timer0 Stop einen Überlauf von Timer0. Da man sich noch in der ISR befindet wird dieÜberlauf ISR aber nicht mehr ausgeführt und der Überlaufzähler ist folglich um einen zu klein. So wie es aussieht ist das bei dem Beispielwert für 1s passiert, sonst wäre der Fehler nicht so groß. Wenn man will könnte man den Fall noch abfangen, indem man das Interruptflag abfragt.

    Für eine wirklich genaue Messung sollte man aber lieber Timer1 und die ICP-Funktion nutzen.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    37
    Beiträge
    61
    Danke für die Antworten. Aber ich glaube ich stecke nicht so tief im programmieren drin wie Ihr. Im Klartext ich verstehe nur spanische Dörfer. Ich freu mich ja quasi schon wenn eine Lampe blinkt.

    Aber nun Spass bei Seite.
    Das die Overlayroutinen die höheren Bits verschieben ist mir klar. Soweit konnte ich noch folgen.

    Ich zähle also mit T0overflowctr die Überlaufe und nehme das zum schalten des 2^8 Bits in der Longvariable T, da sich ja bei jedem Überlauf den der Timer0 erfasst das "2^8 Bit" um 1 erhöht und somit Dezimalzahl 256 zu meinem Longwert T dazuaddiert wird. Verstehe ich das richtig?

    Das Ergebnis ist schließlich die Periodendauer in µs.

    Was ist die ICP-Funktion mit Timer1 wieso ist die Messung da genauer?

  5. #5
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das mit dem Overlay scheint ja schon richtig verstanden. Das Zählen der Overflows gibt einfach weitere höherwertige Bits zu den 8 von der Timer Hardware.

    Man kreigt nur dann die Zeiten in µs wenn der Timer mit 1 MHz läuft.

    Die ICP Funktion von Timer1 ist genau dazu da genaue Zeitmessungen zu machen. Wenn die gewählte Flanke auftritt, wird in Hardware der Zählerstand in extra Register kopiert und ggf. ein Interrupt ausgelöst. Man kann da die Zeit bis auf 1 Taktzyklus genau messen, denn die eigentliche Messung (= kopieren des Zählerstandes) macht die Hardware.

    Mit den Interrupt so wie im Beispiel oben, hat man immer noch eine nicht ganz konstante Verzögerung bis der Interrupt auslöst. Meistens sind es nur +-2 Zyklen, aber wenn mal Interrupts gesperrt werden, oder wenn gerade ein Overflow kommt, kann es deutlich länger werden.

    Bei Timer1 hat man außerdem gleich 16 Bits in Hardware. Für Einige Anwendungen kann das reichen. Damit wird dann auch die Programmierung einfacher, vor allem wenn man das Zählen der Überläufe richtig machen will.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    37
    Beiträge
    61
    Dann hab ich wieder was gelernt. Ein guter Tag quasi.

    Wenn ich also den Timer1 benutze um in der Interruptroutine den Stand zu zählen, wie kann ich dann Wert den das ICP erhält dann auslesen? Da gibts doch sicher ne Varibale die mir den Zugriff aufs ICP ermöglicht bzw. den Interrupt ausslöst? Wie programmiere ich denn sowas?

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn die Zeiten nicht so groß sind, oder die Auflösung nicht so hoch sein muß, kommt man eventuell auch mit den 16 Bit aus, und muß gar nicht von Hand die Auflösung erweitern.
    Wie weit die ICP direkt von Bascom unterstützt wird, weiss ich nicht. Eventuell wird man das mit direktem Zugriff auf die Registsr machen müssen, so wie in C. Ein Beispiel in C ist hier :
    http://www.rn-wissen.de/index.php/Timer/Counter_(Avr)#Input_Capture
    Nicht erschrecken wegen der Länge, etwa die Hälfte ist die Ausgabe und hat mit dem Timer nicht viel zu tun.

Berechtigungen

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