-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: PWM verschiedener Frequenzen Erzeugen und Messen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28

    PWM verschiedener Frequenzen Erzeugen und Messen

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo Community,

    ich habe mal wieder eine Frage zum Basom Programmieren.
    Folgende Aufgabenstellung:
    Ich möchte mit einem ATMEGA32 (16MHZ, Fuses gesetzt, ohne Quarz arbeitet er gar nicht ) ein PWM Signal ausgeben.
    Die Frequenz und Pulsbreite sollen während der Laufzeit einstellbar sein. Versuche zur Umstellung während des Laufens waren an sich erfolgreich, indem man für die Standard PWM Routine einfach im Programm CompareX umstellt.
    Allerdings ist es mir nicht gelungen die Frequenz des PWM Signals frei einzustellen, da ich nur bestimmte Teilungen machen kann. Würde aber 1. gern Frequenzen bis 100kHz einstellen, und 2. frei einstellen können nicht nur ~32kHz, ~7Khz, etc.
    Habe es auch über einen Interrupt versucht, aber da kommt nur noch totaler Müll raus. Lass ich einfach nur Togglen, erreiche ich eine Frequenz von ~64kHz, versuche ich aber sinnvolle Teilungen (Pulsweite), oder eine andere Frequenz (zudem beeinflusst sich beides gegenseitig ) bricht die Frequenz auf unter 1Khz ein.
    Was mache ich falsch, wo kann man da was einstellen? Würde am liebsten direkt in der Timerconfig vorgeben von wo bis wo er zählen soll (wie mans auch im Interrupt macht) damit könnte ich dann die Frequenz einstellen.
    Ein Test mit einem C-Control Mega32 kann dies, sogar bis zu Frequenzen von 7,37 Mhz (Quarz 14,78Mhz), aber den will ich natürlich nicht nutzen.
    Muss doch auch für Bascom ne passende Einstellschraube geben!?

    Weitere Frage, wie kann ich die PWM Frequenz messen?
    Sollte ja eigentlich mit Timer1, ICP1 und der Capture Funktion gehen?! Hab im Programm versucht, aber hab nur Wert 0 bekommen.
    (PS: Gleiches Problem hatte ich mit der Funtkion für die Laufzeit $Time, $Date. Uhr Stand einfach Still obwohl Interrupts und Timer enabled)


    Also ich Danke euch fürs Lesen und freue mich auf hilfreiche Antworten!

    (Muss jetzt aber dringend los, deswegen entschuldige ich mich, dass das Korrekturlesen ausfällt. Antworten auf Zwischenfragen gebe ich ab Morgen wieder. THX)
    Angehängte Dateien Angehängte Dateien

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2007
    Beiträge
    594
    Hmm ich glaube folgendes:
    A - Mit der Hardware-PWM wird das so nichts
    B - Mit Bascom noch viel weniger (exakt)

    Vielleicht solltest du dir dafür etwas ASM aneignen und einen möglichst kurzen Loop schreiben, der dir einfach nur immer einen Port schaltet.
    Oder eben nen Interrupt.

    Zum messen der Frequenz einen Interrupt und und diese Funktion zum messen einer Taktdauer (hab grad vergessen, wie das heißt - findet man im Datasheet unter Interrupt)

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    Schade eigentlich. Denn erstens hab ich mich inzwischen auf Bascom eingeschossen, und Großteil vom restlichen Programm schon darin implementiert, zum anderen besitzt Bascom doch diese Routinen, zumindest zum auslesen.
    Nur arbeitet die bei mir halt nicht, also wenn jemand den Fehler sieht, bzw. weiß wie man PWM auslesen kann würde ich mich freuen.

    Und was die Interrupts angeht: hab ich ja im Programm versucht, leider weniger erfolgreich, da dabei ganz komische Sachen passieren und die Ausgabe-Frequenz total falsch ist, je nach Arbeit im Interrupt. Klar schafft er dann nicht mehr volle Geschwindigkeit wenn er dort mehr arbeiten muss, aber wenn er anstatt 1 Mhz 7 kHz oder weniger ausgibt ist das schon ein extremer Unterschied! Würd jetzt sagen der Pin kann nicht schneller als 7kHz , aber er kann sogar 63kHz.

    Nun das dann mit Assembler zu machen wäre ne weitere Möglichkeit, Basom bietet ja die Möglichkeit auch Maschienencode direkt einzugeben. Vielleicht auf diese Weise.
    Werds später mal versuchen, wobei da muss ich mir noch einiges zu anlesen, wie man die Interrupts und die passenden Register in Assembler anspricht.


    Sonst weiß hier keiner was? Komisch eigentlich da ja relativ viele Leute auch mit PWM arbeiten.

    Hier mal vergleichbarer Code zum Einstellen der PWM-Frequez aus der C-Control (War das Musterbeispiel)
    Code:
    '----------------------------------------------------------------------------------
    '----- DEMO ----- DEMO ----- DEMO ----- DEMO ----- DEMO ----- DEMO ----- DEMO -----
    '----------------------------------------------------------------------------------
    'Projektname:       PWM_Timer1.cprj
    'Benötigte Libs´s:  IntFunc_lib.cc, LCD_Lib.cc (neu ab 03.08.2007)
    'Routinen:          PWM_Timer1.cbas, LCD_start.cbas
    'Autor:             Ulli Sommer
    'Datum:             07.08.2007
    'Funktion:          Pulsweitenmodulation
    'Neue Funktionen:
    'Notitz:
    '----------------------------------------------------------------------------------
    'Variable
    
    'Hauptprogramm
    Sub main()
    
        LCD_start()                                          ' LCD Initialisieren
    
        'Timer_T1PWMX(word period,word PW0,word PW1,byte PS)
        'Periode=Period*PS/FOSC (100*64/14,7456MHz=434 µs)
    
        'Period legt die Länge des Signals fest
        'PW0 gibt an wie lange Kanal A high ist, rest der Periode ist low
        'PW1 gibt an wie lange Kanal B high ist, rest der Periode ist low
    
        '  <PW>
        '   ___
        '  |   |
        '  |   |
        ' _|   |__________________
        '
        '<---Periodenlänge------->
    
        'Über den Timer Prescaler wird das Teilungsverhältnis (Oszillatorfrequenz/ps)
        'festgelegt. (14,7456MHz/ps)
    
        'Vorteiler (prescaler)   Zeitbasis (Dauer eines Ticks)
        'ps_1    (1)   67,8 ns
        'ps_8    (2)  542,5 ns
        'ps_64   (3)   4,34 µs
        'ps_256  (4)  17,36 µs
        'ps_1024 (5)   69,4 µs
    
        'Config für Kanal A und B
        'Timer_T1PWMX(255,1,1,PS_1)
       'Timer_T0PWM(100,64)
       
       Timer_T1PWM( 147, 49, 1)  'Erster Wert für Frequenz (Anzahl der Counts), zweiter Wert Pulsweite, Dritter Wert Prescaler
    
        Do While (1)                                         ' Endlosschleife
    
        End While
    
    End Sub
    [/code]

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.08.2007
    Ort
    Oberhofen im Inntal (Tirol)
    Alter
    43
    Beiträge
    377
    Zitat Zitat von MOLE
    Schade eigentlich. Denn erstens hab ich mich inzwischen auf Bascom eingeschossen, und Großteil vom restlichen Programm schon darin implementiert
    Hallo MOLE!

    1.) Lass dir nichts einreden. Alles was du mit C machen kannst, kannst du auch mit Bascom machen. Nur eben meist ein wenig komfortabler.

    2.) Die Hardware PWM kannst du in der Frequenz nur über den Quarz, den Prescaler und die verwendeten Bits für PWM (8 | 9 | 10) einstellen. Dafür belastet PWM den Controller nicht und du kannst auch sehr hohe Frequenzen damit erzeugen.

    3.) Wenn du mehr Einfluss auf die Frequenz das Tastverhältnis nehmen möchtest, dann kannst du die PWM selber programmieren. Das ist umständlicher und belastet den µController sehr. Für andere Aufgaben ist dann nicht mehr viel Spielraum.

    Für Software-PWM gibt es mehrere Möglichkeiten.

    Wenn du dich in der MainLoop um die PWM kümmerst, dann kann es sein, dass die Frequenz oder das Tastverhältnich nicht exakt eingehalten wird, da entweder Interrupts die MainLoop unterbrechen oder du im Programm mal kurz irgendwo warten musst.

    Du kannst PWM aber auch in einem Timer-Interrupt durchführen lassen. Aber Vorsicht! Der Interrupt-Handler sollte nicht zu viel Zeit in Anspruch nehmen. Das ist kein Problem, wenn du nur einen oder zwei PWM-Kanäle brauchst. Es wird aber zu einem Problem, wenn du mehr willst.

    Alle Varianten haben ihre Vor- und Nachteile. Deshalb ist es wichtig, zu wissen, was du überhaupt damit machen möchtest. Warum willst du überhaupt dynamisch Einfluss auf die Frequenz nehmen? Was bringt dir das? Normalerweise nimmt man die Frequenz, die für die Aufgabe die Richtige ist und kümmert sich nicht mehr darum.

    Willst du hohe und genaue Frequenzen, dann nimm Hardware-PWM.

    mfg
    Gerold
    :-)

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.08.2007
    Ort
    Oberhofen im Inntal (Tirol)
    Alter
    43
    Beiträge
    377
    Hallo!

    Zum Messen der Frequenz noch etwas:

    Falls du Hardware-PWM verwendest, brauchst du die Frequenz nicht zu messen, denn diese ergibt sich automatisch aus den verwendeten Einstellungen.

    Willst du Software-PWM messen, dann empfehle ich dir dies über einen zusätzlichen µController zu erledigen, denn das Messen braucht Ressourcen -- genau so wie das Erzeugen des PWM-Signals. Das Messen könnte also dem Erzeugen des Signals im Wege stehen.
    Denn wie ich schon schrieb, ist das Erzeugen des PWM-Signals per Software eine Aufgabe die den µC ziemlich auslastet. Und das Messen belastet ihn, je nach Messmethode, noch mehr. Das Problem ist vielleicht nicht unbedingt das Messen, aber du willst diese Werte doch sicher auch irgendwie weiterverwenden/ausgeben.

    Wie ich schon schrieb, gibt es mehrere Möglichkeiten per Software ein PWM-Signal zu erstellen. Aber für verschiedene Frequenzbereiche muss man verschiedene Algorithmen verwenden. Du musst also je nach gewünschter Frequenz zwischen diesen Algorithmen hin und her schalten.

    Lohnt sich der Programmieraufwand überhaupt, einen Frequenzgenerator zu programmieren, der zwischen 1 Hz und xx Mhz einstellbar ist? Je höher die Frequenz wird, desto größer werden die einstellbaren Schritte. Usw.

    Also steht wieder die Frage im Raum, was du eigentlich damit machen möchtest.

    mfg
    Gerold
    :-)

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    Ich möchte wie Eingangs erwähnt ein PWM Signal ausgeben, das allerdings flexibel sein soll. Sprich ich möchte während der Laufzeit des Controllers die PWM Frequenz zwischen 100-100kHz einstellen können. Um die Funktion der Folgeelektronik bei den Frequenzen testen zu können.
    (Wer etwas aufpasst stellt schnell fest, dass mit Hardware PWM aufgrund 16Mhz /1/512 Zählschritte nur 31,25 kHz möglich sind, und dann dumme Zwischenschritte durch Prescaler)
    Die Möglichkeit die Zwischenschritte manuell einstellen zu können würde ja schon zur gewünschten Funktion führen, und auch wie beim C-Control Frequenzen bis zu einigen MHz ermöglichen.

    Das ganze soll zu Testzwecken verwendet werden um die Folgeelektronik auf Funktion zu prüfen. Die Frequenz gibt somit die Arbeitsfrequenz vor, die getestet werden soll.
    [Alles nur zur Fehlersuche im Schadensfall, nicht zum Betrieb, weitere Sicherheitsmaßnahmen gibt es natürlich auch!]


    Auf der anderen Seite soll das von externer Stelle erzeugte PWM Signal überwacht werden können, um zu sehen ob dieses richtig ausgegeben wird. Diese Funktion bietet Bascom ja sogar über das Interrupt Catch Register (Pin ICP1)!
    Code:
    Config Timer1 = Counter , Edge = Falling , Capture Edge = Rising , Noise Cancel = 1 , Prescale = 8
    Config Portd.6 = Input
    W = Capture1

    Alles nur zur Fehlersuche bei Ausfall der Folgeelektronik.

    Weiterhin hätte der Controller während Ausgabe, ODER des Einlesens des PWM Signals nichts besonderes mehr zu tun, außer Tastatur Überwachung zum Beenden der Funktion (Esc Taste), und eventuell auch eine kurze Displayausgabe währenddessen oder danach, Rechenleistung wäre aber frei.


    Handling per Timerinterrupt habe ich versucht, kamen aber Falsche Frequenzen bei raus, und variieren wie gesagt extrem je nach Ausführung im Interrupt, wobei zB Toggle oder einfaches if/Else 63kHz schaffen, differenziertes if-Else (1 Takt High, 2 Takte low) die Frequenz in unter 1kHz einbrechen lassen.
    Also wenn du ein passendes Muster für einen solchen Interrupt hättest würde ich es gerne sehen, verwenden, anpassen.
    Mein Testbeispiel ist ja in der Bas-Datei (Erster Eintrag) Da sind die Möglichkeiten drin.
    Vielleicht sieht dort ja auch jemand einen Fehler und dann geht es ja richtig?!

    Möglich wäre zur Not auch die Alternative es mit einem externen Baustein zu regeln, also zB über I2C Frequenz und Pulsweite vorgeben, und der erzeugt das PWM Signal, und optimaler Weise könnte er auch PWM Signale einlesen, also Frequenz und Pulsweite.
    Natürlich ist dies nicht die schönste Lösung, da der Controller das ja auch machen könnte aber wenn gar nix mehr geht......


    PS:Und man braucht nicht mehrere Routinen für unterschiedliche Frequenzen, sondern kann für den Timer den Prescaler und Timervorgabe während der Laufzeit ändern, ebenso den Parameter für die Pulsweite (entspricht der Leistung). Kann man alles während der Laufzeit über Parameter ändern und funktioniert auch.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.08.2007
    Ort
    Oberhofen im Inntal (Tirol)
    Alter
    43
    Beiträge
    377
    Hallo MOLE!

    Ich möchte dich auf zwei Threads verweisen, welche auf verschiedene Software-PWM-Arten eingehen. Die Quellcodes verstecken sich meist hinter den Links.

    - http://www.roboternetz.de/phpBB2/viewtopic.php?p=352156
    - http://www.elektronik-projekt.de/thr...?threadid=4866

    Die Arbeit, die Quellcodes raus zu suchen und direkt zu verlinken, tue ich mir jetzt nicht an. ;-)

    mfg
    Gerold
    :-)

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    Hast Recht, da sind noch einige Möglichkeiten die ich mal antesten werde und EINIGE... weiterführende Links. Werd mich mal da durchlesen und einiges ausprobieren. Wird aber wohl trotzdem bis Montag dauern bis ich soweit bin, da ich die nächsten Tage unterwegs bin und keine Zeit dazu finde. Dennoch Danke und ich melde mich erneut mit Ergebnissen.
    Immerhin hab ich jetz neue Anregungen

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.01.2008
    Beiträge
    164
    ....Muss jetzt aber dringend los, deswegen entschuldige ich mich, dass das Korrekturlesen ausfällt. Antworten auf Zwischenfragen gebe ich ab Morgen wieder. THX).....

    du solltest bei dem stress den dun hast, das hobby aufgeben.

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2007
    Beiträge
    28
    So hab es jetzt endlich mal geschafft die PWM Frequenz flexibel einlesbar zu gestallten.
    Momentan über Eingabe am Terminal (1. Wert die Frequenz, 2. Wert die Leistung, wobei 100% Leistung 50% Pulsweite sind)

    Code:
    $regfile = "m32def.dat"
    $framesize = 500
    $swstack = 500
    $hwstack = 500
    $crystal = 16000000
    
    $baud = 9600
    
    Dim Freq As Word , Pw As Single
    Dim Pulsweite As Word
    Dim Frequenz As Long
    
    Config Portd.4 = Output
    Config Timer1 = Pwm , Compare B Pwm = Clear Down , Compare A Pwm = Clear Up ,       ' CompareB für PWM, CompareA =0
    Tccr1b = 17                                                 '1 für Prescaler 1, anderes Bit?
    'Tccr1a = &B00100001                                         'See datasheet for details.
    'Tccr1b = &B00010001                                         'See datasheet for details.
    Compare1b = 65535
    
    Enable Interrupts
    
    
    
    Do
    
    If Ischarwaiting() = 1 Then
    
       Input Frequenz Noecho
       Input Pulsweite Noecho
       Frequenz = 8000000 / Frequenz                            '80 ergibt 100kHz, Umrechnung für Frequenz in Freq-Wert
       Freq = Frequenz                                          'Wieder as 2 Byte Word
    
       Ocr1ah = High(freq)                                      'Frequenz high-Byte
       Ocr1al = Low(freq)                                       'Frequenz low-Byte, zählt x Timerimpulse 80=100kHz
    
       If Pulsweite > 100 Then Pulsweite = 100                  'maximale Leistung bei 50% PW, höhere Werte kürzen
       Pw = Freq / 200                                          '50% PW für 100% Leistung
       Pw = Pulsweite * Pw                                      'x% Leistung
       Pulsweite = Round(pw)                                    'in 2 Byte Word
    
       Enable Timer1
    
       If Pulsweite = 0 Then
          Pulsweite = 65535                                     'bei Leistung 0, Ausschalten (5V)
          Disable Timer1
       End If
    
       Compare1b = Pulsweite
    
    
    End If
    
    Loop
    Bin aber noch immer auf der Suche, wie man die Frequenz aus alternativer Quelle richtig bestimmen kann. Zur Not halt mit INT0 Interrupt, wobei dann das auswerten zur Zeit schwieriger wird.
    Vielleicht fällt mir oder jemand anderem ja noch was ein. Wäre zumindest schön das über den Input Capture Pin un die passende Funktion zu handeln.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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