xmega timer mit schnellerem Takt als Systemtakt?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • xmega timer mit schnellerem Takt als Systemtakt?

      Hi!
      sorry für den komischen Titel, mir ist keine bessere Beschreibung in den Sinn gekommen. Ich suche nach einer Möglichkeit ein spezielles, digitales Signal an einem Pin zu erzeugen. Das sieht z.B. so aus:

      20000 µS LOW
      2 µS HIGH
      100 µS LOW
      2 µS HIGH
      ... dann wieder von vorne

      Ich nutze eine XMEGA16A4U dafür mit einem 16 MHz Quarz und 64 MHz Systemtakt an 3.3V. Konfiguration des Systemtaktes:

      BASCOM Source Code

      1. $regfile = "xm16A4def.dat"
      2. $crystal = 64000000
      3. $hwstack = 256
      4. $swstack = 256
      5. $framesize = 256
      6. $lib "xmega.lib"
      7. Dim A As Byte
      8. Out &H52 , &B10101011
      9. Out &H50 , &B00001000
      10. Out &H55 , &B11000100
      11. Out &H34 , &HD8
      12. Out &H41 , &B00000000
      13. While A.3 = 0
      14. A = Inp(&H51)
      15. Wend
      16. Out &H50 , &B00011000
      17. While A.4 = 0
      18. A = Inp(&H51)
      19. Wend
      20. Out &H34 , &HD8
      21. Out &H40 , &B00000100
      22. Out &H34 , &HD8
      23. Out &H42 , &B00000001
      Display All

      Die 2 µS Zeiten zu toggeln wird relativ knapp in Bascom. Nun habe ich hier gelesen, dass es wohl die Möglichkeit gibt, einen Timer mit einem "Prescale kleiner als 1" laufen zu lassen, also dem Timer eine schnellere Taktquelle als die Systemclock zur Verfügung zu stellen. Dazu finde ich in der Bascom Hilfe und im Netz leider nichts. Ist das denn möglich? Nach was muss ich hier suchen? Danke für eure Tipps!
    • Hallo Willa,
      deine eigentliche Frage kann ich dir leider nicht beantworten, da ich keine Erfahrung mit XMEGA habe.
      Für einen Mega würde ich das so machen:

      BASCOM Source Code

      1. $regfile = "m16def.dat"
      2. $hwstack = 48
      3. $swstack = 48
      4. $framesize = 48
      5. $crystal = 4000000
      6. Config Portd.5 = Output
      7. Config Timer1 = Pwm , Prescale = 8 , Compare_a_pwm = Clear_up , Pwm = 9
      8. Icr1 = 50
      9. Ocr1a = 0
      10. Tccr1b.wgm12 = 1
      11. Tccr1b.wgm13 = 1
      12. On Compare1a Cmp1a_isr
      13. Enable Compare1a
      14. Enable Interrupts
      15. Do
      16. Loop
      17. End
      18. Cmp1a_isr:
      19. If Icr1 = 50 Then Icr1 = 10000 Else Icr1 = 50
      20. Return
      Display All
    • Sehe ich das richtig?

      Einfach alle 20ms 2 Pulse ausgeben mit 2µs länge und 100µs Abstand?

      Was muss der Controller sonst noch erledigen?

      Ich würde einfach einen Interrupt alle 20ms aufrufen und die Pulse ausgeben

      ISR:
      Set Port.n
      Waitus 2
      Toggle Port.n ' nach 2µs löschen
      Waitus 100
      Toggle Port.n ' nach 100µs setzen
      Waitus 2
      Toggle Port.n
      Return

      Nur mal so als Vorschlag.
    • Hi, leider bekomme ich hier wohl keine Email-Benachrichtigungen bei Antworten :(
      Danke für die Tipps! Das Timing soll per UART geändert werden können, daher fällt waitus leider raus. Das funktioniert zwar auch mit Variablen, aber dann ist das Timing sehr ungenau. Aber der Tipp mit dem PWM ist gut, ich wusste gar nicht, dass man das PWM im Interrupt umkonfigurieren kann. Das mache ich bisher zwar auch mit normalen Timern, aber die gehen nur bis 4 µS als kürzester Puls, dann verschluckt sich der Code (ist quasi ein Software PWM per Hardwaretimer). Im xmega sieht der Code mit dem PWM dann so aus:

      BASCOM Source Code

      1. $regfile = "xm16A4def.dat"
      2. $crystal = 64000000
      3. $hwstack = 256
      4. $swstack = 256
      5. $framesize = 256
      6. $lib "xmega.lib"
      7. 'Systemtakt konfigurieren
      8. Dim A As Byte
      9. Out &H52 , &B10101011
      10. Out &H50 , &B00001000
      11. Out &H55 , &B11000100
      12. Out &H34 , &HD8
      13. Out &H41 , &B00000000
      14. While A.3 = 0
      15. A = Inp(&H51)
      16. Wend
      17. Out &H50 , &B00011000
      18. While A.4 = 0
      19. A = Inp(&H51)
      20. Wend
      21. Out &H34 , &HD8
      22. Out &H40 , &B00000100
      23. Out &H34 , &HD8
      24. Out &H42 , &B00000001
      25. 'PWM konfigurieren
      26. Config Tcd0 = Pwm , Prescale = 1 , Comparea = Disabled , Compareb = Disabled , Comparec = Disabled , Compared = Enabled , Event_source = Off , Event_action = Off , Event_delay = Disabled , Resolution = 16
      27. Tcd0_per = 128 'PWM period
      28. Tcd0_ccd = 64 'pwm count
      29. On Tcd0_ovf Interrupt
      30. Enable Tcd0_ovf , Med
      31. Enable Interrupts
      32. Do
      33. Loop
      34. End
      35. Interrupt:
      36. If Tcd0_per = 128 Then
      37. Tcd0_per = 256
      38. Else
      39. Tcd0_per = 128
      40. End If
      41. Return
      Display All
      Damit ergibt sich ein Doppelpuls mit sehr präzisem 1 µS an, 1 µS aus, 1 µS an, 3 µS aus (nur mal als Beispiel). Für meine Anwendung muss ich allerdings die Signale auf verschiedenen Pins und untereinander synchronisiert ausgeben. Das funktioniert wunderbar mit normalen Timern, wird aber mit PWM nicht gehen denke ich...

      Unbenannt.JPG
    • Willa wrote:

      Hi, leider bekomme ich hier wohl keine Email-Benachrichtigungen bei Antworten
      Ich glaube das kannst du in deinem Profil einstellen.

      Willa wrote:

      Das mache ich bisher zwar auch mit normalen Timern, aber die gehen nur bis 4 µS als kürzester Puls, dann verschluckt sich der Code (ist quasi ein Software PWM per Hardwaretimer)
      Wahrscheinlich dauert es zu lange, alle Register zu pushen, da müsstest du mit der Option Nosave machen
      On Interrupt xy Nosave

      Dann musst du aber unbedingt alle in der ISR verwendeten Register Pushen und Poppen.


      Willa wrote:

      Für meine Anwendung muss ich allerdings die Signale auf verschiedenen Pins und untereinander synchronisiert ausgeben
      Du meinst, du willst den 1µs und den 3µs Puls auf verschiedenen Pins ausgeben?
      Der Timer hat mehrere Compare Outputs, so viele verschiedene Pins könntest du nutzen.
      Allerdings weiß ich wieder nicht, wie das beim XMEGA geht. Beim Mega wird der Timer immer zurückgesetzt, wenn OCR1A erreicht. Wenn OCR1B größer ist, passirt an dem entsprechenden Ausgang nichts. Ich könnte mir also vorstellen, dass du über diesen Mechanismus doch mehrere Pins in HW (= präzises Timing) schalten könntest.