Hallo, ich möchte mit einem µC – Atmega644, 20 Mhz, in C# – einen Zweifach-Rechteckpuls ausgeben. Erst wird die Dauer des ersten Pulses vorgegeben, dann die Länge der Pause und abschließend wird noch mal die Dauer für den zweiten Puls angegeben. Die verschiedenen Zeiten sind dabei selten gleich und weichen jeweils in der Regel von einander ab. Also das Signal ist eigentlich nicht periodisch. z.B. IIII_______II, IIIII___IIIIIII, II_I Mein Problem bei der Sache ist jedoch, dass ich Zeitschritte von 50 ns will >.< Dazu kommt, dass ich nur den Timer1 zur Verfügung habe. Alle anderen Timer sind schon mit anderen Aufgaben beschäftigt. Ich hatte schon verschiedene Ansätze. z.B. versuchte ich eine Art Schrittkette zu machen, bei der der Timer in den jeweiligen Schritten immer zu abgefragt wurde bis zu einem bestimmten Zeitpunkt. Dann wurde der Timer auf 0 gesetzt, der entsprechende Port für das Ausgangssignal gesetzt, der Schritt wurde beendet und der nächste Schritt ausgeführt, der im Grunde wie der erste Schritt aufgebaut war, nur, dass er den Port wieder anders setzte … usw. Das Problem bei dieser Lösung waren die ganzen while-Schleifen und if-Abfragen, die das Ganze doch schon sehr verlängerten. Danach habe ich eine Verzögerung mit for-Schleifen versucht, bzw. einen eigenen Zähler damit zu realisieren. Nur optimierte mir der AVR Studio Compiler diese „leeren“ for-Schleifen einfach Weg. Ich konnte zwar die Optimierung runterstellen, aber diesen Zustand wollte ich für mein restliches Programm nicht haben. Das Problem konnte ich jedoch lösen, indem ich in die Schleifen eine „NOP-Anweisung“ schrieb - asm volatile ("nop"). Leider braucht ein Zählschritt bei mir 350 – 400 ns (abhängig von den Gesamtzählschritten). Ich konnte die Zählschritte auf 150 ns beschränken, indem ich in mein C-Programm die Schleife in Assembler realisierte. Mhmm, es wäre ideal, wenn genau in dem Moment wo der Timer meinen erwartete Wert erreicht hat ich den Port setzen/rücksetzen könnte. Nur fällt mir keine Lösung dazu ein – irgendwelche abfragen/Vergleiche brauchen bei mir selbst immer etwas Zeit und ein Zufallsfaktor schleicht sich dabei auch mit ein und Interrupts brauchen einfach zulange in die ISR zu springen und zurück zu kommen. Hat vielleicht einer von euch eine Idee wie ich den Zweifach-Rechteckpuls realisieren kann? Weder die Suchfunktion noch Google konnte helfen /:
50 ns ist schon heftig > Mhmm, es wäre ideal, wenn genau in dem Moment wo der Timer meinen > erwartete Wert erreicht hat ich den Port setzen/rücksetzen könnte Der Timer 1 kann das doch. Über die Output Compare Register kannst du das erreichen. Leider kannst du aber nicht die beiden OCR Register auf einen gemeinsamen Ausgangspin schalten. Trotzdem denke ich, dass der Weg über diese Timerfunktionalität führt.
irre ich mich oder sind 50ns genau die länge eines taktes bei 20MHz? und da siehst du doch bestimmt selber, dass du in dieser zeit maximal einen befehl ausführen kannst (manchmal nichtmal das, weil einige befehle 2 oder 3 taktzyklen brauchen) und schon der aufruf eines timerinterrupts sind einige befehle aber mind. ein sprungbefehl. da musst wohl einen schnelleren prozessor finden
@ auf (Gast) >ich möchte mit einem µC – Atmega644, 20 Mhz, in C# – einen >Zweifach-Rechteckpuls ausgeben. C Sharp? Schullifax. >sich dabei auch mit ein und Interrupts brauchen einfach zulange in die >ISR zu springen und zurück zu kommen. >Hat vielleicht einer von euch eine Idee wie ich den >Zweifach-Rechteckpuls realisieren kann? Ganz einfach. Hard kodieren in ASM. Das Muster kann man problemlos mit OUT Befehlen erzeugen, die kleinen Lücken füllt amn mit NOPs. Grössere Abstände macht man mit Schleifen, auch die sindt taktgenau in ASM machbar und mit NOPs auf den Takt genau trimmbar. Verschiedene Pulsfolgen kann man über mehrere Unterprogramme realisieren. Damit kann man deine 50ns Auflösung SICHER erreichen. MFG Falk
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.