- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 13 von 13

Thema: PWM verschiedener Frequenzen Erzeugen und Messen

  1. #11
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.08.2007
    Ort
    Oberhofen im Inntal (Tirol)
    Alter
    50
    Beiträge
    377
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von MOLE
    wie man die Frequenz aus alternativer Quelle richtig bestimmen kann
    Hallo MOLE!

    Es geht sicher auch besser, aber hier mein erster Versuch:
    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 32
    $swstack = 10
    $framesize = 40
    $baud = 9600
    
    Dim Cur_freq As Long
    Dim Avg_freq As Long
    Dim Tmp As Long
    
    
    'INT0 = PD2
    Config Pind.2 = Input
    Portd.2 = 1       'PullUp
    Config Int0 = Falling
    On Int0 On_int0
    
    'TIMER0 so eingestellt dass der Interrupt jede Sekunde auslöst
    Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1
    Compare1a = 31250
    On Compare1a On_compare1a
    
    Enable Int0
    Enable Compare1a
    Enable Interrupts
    
    
    Do
       Print Str(avg_freq) + " Hz"
       Wait 2
    Loop
    
    End
    
    
    On_int0:
       Incr Cur_freq
    Return
    
    
    On_compare1a:
       Tmp = Cur_freq
       Cur_freq = 0
       If Tmp = 0 Then
          Avg_freq = 0
       Else
          Tmp = Avg_freq + Tmp
          Avg_freq = Tmp / 2
       End If
    Return
    mfg
    Gerold
    :-)

  2. #12
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    Ja werds wohl so ähnlich machen müssen, nachdem ich die Timerfunktion mit dem Input-Catch-Registern nicht hinkriege.
    Naja, vielleicht klappts ja doch noch irgendwie, oder ich find irgendwo ne Anregung.

  3. #13
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    Getreu dem Motto viele Wege führen um Rom, habe ich nun verschiedene Lösungsanzätze zum Messen der Frequenzen genutzt.
    Außerdem habe ich endlich das Timer-Capture-Register zum Messen der Frequenzen nutzen können.Der Fehler war der Befehl „Edge= Rising“ in der Config-Zeile, denn der darf dort wohl nicht sein.

    An sich funktioniert der jetzt soweit ganz schön.
    Leider nur an sich!
    Tests über Prescaler (256 und 1024) und Frequenzen von 244 Hz und 61Hz haben super funktioniert.
    Beim Prescaler 8 (mit und auch ohne Clear Timer, der die Zählschritte zwischen 256 und 512 umschaltet, also Frequenz verdoppelt) kriege ich leichte Abweichungen. Bei höheren Frequenzen noch extremer.
    Sie sind nicht nachvollziehbar und auch nicht linear (zumindest nicht für mich )
    Hier mal ein paar gemessene und reale Werte:

    Real 3,92 kHz - Mess (µC) 3,99 kHz
    Real 7,81 kHz – Mess 8,07kHz
    Real 31,37 kHz – Mess 36,36 kHz
    Real 62,5 kHz – Mess 83,333 kHz

    Der Unterschied beruht wohl darauf, dass der Timerwert dann zu klein ist (Ticks verpasst?!) und demnach errechnet sich eine falsche Frequenz.

    Demnach habe ich auch versucht, über einen Interrupt (Int1) , Bitwait und auch Pulsein die Frequenzen zu Messen. Alles mit ähnlich schlechtem Ergebnis in höheren Frequenzen.
    Nun die Frage wieso? Hat da jemand vielleicht Erfahrungen?

    Habe auch versucht einen Korrekturfaktor im Interrupt oder ähnlichem zu realisieren, was zwar an sich klappt, aber auch nicht so eindeutig. Erstens ist es schwierig einen genauen Korrekturfaktor zu bestimmen und dann geht wohl noch der Echtzeitbezug verloren, da der Faktor je nach Inhalt/Länge des Interrupts anders ist, was eigentlich nicht sein kann, da ja erst beim Verlassen des Interrupts der Timer genullt wird, bzw. jedes Mal nach dem gleichen Schritt.
    Hatte auch schon mal ein ähnliches Problem als ich einen Timer für Millisekunden nutzen wollte. Von der Rechnung hat der wunderbar auf 1ms gepasst, jede Ms in den Interrupt und globalen Zähler Hochzählen. Die darauf folgenden Rechnungen (zB Wartezeit 10000 ms zum Schalten ; nein wollte eben kein „waitms“ nutzen, sondern in der Zwischenzeit weiter das Programm bearbeiten) haben jedoch gezeigt, dass der Timer auch da nicht so genau ging und von Hand nach korrigiert werden musste.

    Anbei einmal mein Code zum Messen der Frequenzen (alle genutzten Möglichkeiten auskommentiert drin), vielleicht hat ja noch jemand eine Lösung, die auch bei hohen Frequenzen (1-100kHz noch funktioniert, oder alternativ eine Möglichkeit für einen passenden Korrekturfaktor)
    Zudem wäre es schön irgendwie neben der Frequenz auch noch die Pulsweite (für das Verhältniss) Messen zu können, muss nicht gleichzeitig kann abwechselnd realisiert werden.
    Das geht wohl auch über ein RC Glied und anschließend ADC, ist dann aber recht ungenau aufgrund der Bauteiltoleranzen (soweit habe ich das gelesen).

    Ich freue mich auf weitere Anregungen.



    Code:
    $regfile = "m32def.dat"
    $framesize = 500
    $swstack = 500
    $hwstack = 500
    $crystal = 16000000
    
    $baud = 9600
    
    Config Portd.6 = Input
    Config Portb.0 = Input
    Config Portd.3 = Input
    Config Portd.7 = Output
    Config Portb.0 = Input
    
    Dim Us As Long
    Dim Mess_frequenz1 As Word , Mess_frequenz2 As Word , Mess_frequenz As Long
    Dim Pwm_counter As Byte
    Const Led_1_value = 200
    
    Const Presc = 1
    Dim Prisc As Word
    Prisc = Presc
    
    Config Timer2 = Timer Pwm , Pwm = On , Compare Pwm = Clear Down , Prescale = Presc , Clear Timer = 0
    Compare2 = 128
    
    'Timer Config
    Config Timer1 = Timer , Capture Edge = Rising , Prescale = 8 , Noise Cancel = 1 ,       'Edge = Rising
    'Capture Interrupt
    On Capture1 Cap_int
    
    
    'Config Timer1 = Timer , Prescale = 1	'Zähler
    'Config Int1 = Rising				'Int1 – geht „Change“ auch???
    'On Int1 Irq1
    
    Enable Interrupts
    Enable Timer1
    'Enable Timer0                                               'Enable Timer0
    'Start Timer1
    Enable Timer2
    Enable Capture1
    'Enable Icp1
    'Enable Int1
    
    'Main
    '-------------------------------------------------------------------------------
    Do
     '(	'1. Möglichkeit über Bitwait und Zeit nehmen
      Bitwait Pind.6 , Set
      Mess_frequenz1 = Timer1
      Timer1 = 0
      Bitwait Pind.6 , Reset
      Mess_frequenz2 = Timer1
      Timer1 = 0
    ')
    
    '(	2. Möglichkeit über Pulsein und Wechsel
     Pulsein Mess_frequenz1 , Pind , 6 , 1
         Print "High: " ; Mess_frequenz1
     Pulsein Mess_frequenz2 , Pind , 6 , 0
          Print "Low: " ; Mess_frequenz2
    ')
    
    '      Mess_frequenz = Mess_frequenz1 + Mess_frequenz2	'Frequenz bestimmen
    '      Print "Dauer: " ; Mess_frequenz
    
    '	3. Möglichkeit über Input-Capture-Register
          Mess_frequenz = Capture1
          Mess_frequenz = 16000000 / Mess_frequenz
          Mess_frequenz = Mess_frequenz / 8
    
    
         Print "MessFrequenz: " ; Mess_frequenz
    '     Waitms 50
    
    Loop
    
    End
    
    
    '-------------------------------------------------------------------------------
    'Timer1 Capture Interrupt Routine
    Cap_int:
    '(
       Select Case Prisc
       Case 1 : Timer1 = 81
       Case 8 : Timer1 = 90
       Case 256 : Timer1 = 0
       Case 1024 : Timer1 = 0
       End Select
    ')
    
    Timer1 = 0
    
    Return
    
    
    '-------------------------------------------------------------------------------
    Irq1:
    '   If Portd.3 = 1 Then
          Mess_frequenz1 = Timer1
    '   Else
    '      Mess_frequenz2 = Timer1
    '   End If
    
       Timer1 = 0
    
    Return
    
    
    
    '-------------------------------------------------------------------------------
    Irq2:
       Mess_frequenz = Timer1
       Timer1 = 0
      ' Print "In"
    
    Return

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

Solar Speicher und Akkus Tests