Guten Tag Ich möchte mit einem ATtiny24 mir 8MHz Takt ein asymetrisches Rechtek-Signal generieren (low < high) dass eine Periodendauer von bis zu 2,5ms hat. Hat jemand eine Idee wie ich dass Signal genau timen kann? Dass Blöde ist, dass ich eine Auflösung von ca. 0,05ms brauche. Da die Hauptschleife nichts anderes zu tun hat als das Signal zu generieren, währe es am Einfachsten wenn ich für das Generieren des Signals delay_us verwenden würde. Aber dass will ja bekanntlich unter CodeVisionAVR nur statische Werte und unter WinAVR nur Intervalle die nicht für diese Zeitdauer geeignet sind. Der 16 Bit Timer 1 läuft mit Prozessortakt / 4, der 8 Bit Timer0 mit Prozessortakt / 32. Die zu generierenden Zeitdauern liegen als us-Wert in 16Bit Variablen vor. Hat jemand eine Idee wie ich dass lösen kann? Leider bin ich in ASM eine absolute Niete und brauche eure Hilfe.
@ Barny F. (barny) >Ich möchte mit einem ATtiny24 mir 8MHz Takt ein asymetrisches >Rechtek-Signal generieren (low < high) dass eine Periodendauer von bis >zu 2,5ms hat. >Hat jemand eine Idee wie ich dass Signal genau timen kann? Mit einem Timer und der Output Compare Funktion. >Dass Blöde ist, dass ich eine Auflösung von ca. 0,05ms brauche. 50us. >Da die Hauptschleife nichts anderes zu tun hat als das Signal zu >generieren, währe es am Einfachsten wenn ich für das Generieren des >Signals delay_us verwenden würde. Nö. >Aber dass will ja bekanntlich unter CodeVisionAVR nur statische Werte >und unter WinAVR nur Intervalle die nicht für diese Zeitdauer geeignet >sind. Nö. MfG Falk
> ein asymetrisches Rechtek-Signal generieren (low < high) dass eine > Periodendauer von bis zu 2,5ms hat. Sowas nennt der Fachmann PWM > Der 16 Bit Timer 1 läuft mit Prozessortakt / 4, der 8 Bit Timer0 mit > Prozessortakt / 32. Evtl. kannst du den Timer 1 irgendwie freimachen und für deine PWM verwenden?
Servos? Wenn deine kleinste Auflösung 50µs ist, kannst du ein so großes delay_us verwenden und zählen, wie oft das abgearbeitet wird. Richtige Lösung sind timer/pwm.
PWM kann ich leider nicht verwenden, da es sich um ein Signal handelt und ich dass Puls-Pausenverhältnis nicht hinbekomme. Wie avion23 richtig vermutet handelt es sich um ein PPM Signal. Aber leider handelt es sich nicht um ein gemütliches Servosignal sondern um ein 8-Kanal PPM Summensignal welches aus dem Signal des Empfängers generiert wird. (je 3us bis 6us Pause zwischen den 0,8 bis 2,2ms langen Impulsen) Wenn ich meine Anlage als Ausgang nehme habe ich da 8 Kanäle mit je 10 Bit Auflösung. Dass die Kanäle eine gemeinsame steigende Flanke haben, macht es einem auch nicht leichter. Desswegen möchte ich nicht all zuviel an Daten bei der Umwandlung verlieren. Die Auflösung des generierten Signals sollte möglichst nahe bei den 10Bit liegen. Da ich den Timer1 schon zum Ermitteln der Zeiten der einzelnen Kanäle verwende, kann ich leider nicht mit output compare arbeiten. Ich weis dass es solche Wandler schon zu kaufen gibt. Aber ich will mir erstens soetwas selbst bauen und außerdem brauche ich ein paar spezielle Funktionen.
dann generiere dir doch interrupts alle 50µs, und frage im interupt ab, welches tastverhältnis du brauchst, also wann du auf high und wann du auf low schaltest. So hast du eine Einstellmöglichkeit von HI time und LOW time. Einziger Nachteil: hohe CPU-Auslastung, wenn du wirklich sehr oft(festgemacht an der Auflösung) einen Interrupt auslöst. Andersherum denke ich, dass du mit der Auslastung gut leben kannst, da du ja mit 8MHz taktest. du kannst im interrupt zwei counter inkrementieren: in c: a++;b++; dann abfragen, ob a == HI-zeit/auflösung und ob b == LOW-zeit/auflösung pin ensprechend toggeln verstanden?
bsp: 1ms auf hi 2ms auf low sind bei einer auflösung(timerinterrupts) von 50µs dann 20 ints auf low und 40 ints auf hi im interrupt: also eine zählervariable inkrementieren ist die zählervariable <= hizeit/50µs dann Pin auf HI ist die zählervariable > hizeit/50µ dann pin auf LOW ist sie bei (hizeit/50µs + lowzeit/50µs) // also bei 20+40 dann musst du sie wieder auf 0 setzen. interrupt zu ende
Daran hatte ich auch schon gedacht. Aber dass wird nichts. Die 50us ist dass maximal vertretbare. Lieber währe mir ein Faktor 10 bis 100 schneller. Die 50us Auflösung ist ja schon fast im Bereich "binäre Steuerung" Und bei dieser Methode komme ich den Interupts der eingelesenen Signale in die Quere. Timo, das PPM Signal sieht übrigens folgendermaßen aus: Der Empfänger liefert 8x folgendes Signal: Ein 0,8ms bis 2,2 ms high Pegel, gefolgt von einem längeren Lowpegel der je nach Fernbedienungshersteller bis zu 20ms lang sein kann. Leider kommen bei den neuen Digitalsendeanlagen die steigende Flanke bei mehreren bzw. allen Kanälen gleichzeitig. Und folgendes Signal soll aus den 8 parallelen Signalen generiert werden: die 8 einzelnen empfangenen Signale sollen hintereinander gereit und dur 3us Pausen getrennt ausgegeben werden. Nach diesem Impulspaket kommt eine Pause die 7ms lang ist und dann geht dass Ganze wieder von vorne los. Würde folgendes funktionieren? Ich setze am Anfang des Signal-Frames TCNT1 auf 0x0000. Dann überprüfe ich in einer Schleife ob der Timer einen bestimmten Wert erreicht/überschritten hat und schalte den Ausgang um. Nach der Wartezeit von 3us zur Signaltrennung legt man den Ausgang auf high und wartet wieder bis der Timer den richtigen Wert erreicht hat um den Ausgang auf low zu legen. Dass Ganze wird 8 mal gemacht.
Barny F. schrieb: > PWM kann ich leider nicht verwenden, da es sich um ein Signal handelt > und ich dass Puls-Pausenverhältnis nicht hinbekomme. Timer mit Interrupt und Pin-Change, im Interrupt jeweils die naechste Zeit setzen. Fertig und sehr genau.
Barny F. schrieb: > Und folgendes Signal soll aus den 8 parallelen Signalen generiert > werden: > die 8 einzelnen empfangenen Signale sollen hintereinander gereit und dur > 3us Pausen getrennt ausgegeben werden. > Nach diesem Impulspaket kommt eine Pause die 7ms lang ist und dann geht > dass Ganze wieder von vorne los. Das Erzeugen ist doch popeleinfach. Du nimmst den Compare-Interrupt und der Pin wird mit dem Compare gesetzt oder gelöscht. Und im Compareinterrupt lädst Du ganz bequem den nächsten Zeitpunkt in das Compareregister. Die Pulsdauer ist damit auf exakt einen CPU-Zyklus genau (0,125µs). Schwieriger ist da schon das parallele Empfangen von 8 Signalen. Dazu müßte man den Pin-Change-Interrupt nehmen und den Timestamp in Software auslesen. Damit hat man aber mehrere CPU-Zyklen Fehler. Vorteilhaft ist, daß beides mit Timer1 gemacht werden kann, da der durchlaufen muß. Peter
Genau so wie Peter Dannegger & Peter Stegemann habe ich es auch gelöst. Das funktioniert einwandfrei. Wenn du den Timer 1:1 laufen lässt ist die Auflösung nur durch deinen CPU Takt und 16bit begrenzt. Leider hast du auch eine Verzögerung bis zu 20ms. Das kann auch erwünscht sein, weil dann nicht alle Servos gleichzeitig schalten.
@Peter Dannegger und Peter Stegemann Danke ihr beiden. Da sieht man wieder was für ein schmarrn rauskommt wenn man sich in irgend etwas verannt hat. Da sieht man das Byte vor lauter Bits nicht mehr. @Peter Dannegger Für das Einlesen verwende ich schon den PCINT. Da diese Fehler bei jedem Kanal aber einigermaßen konstant ist, kann man ihn einigermaßen genau herausrechnen. @avion23 Ich glaube du hast mich nicht ganz verstanden. Ich will nicht ein PPM Summensignal in ein paralleles umrechen wie es die Empfänger machen, sondern die andere Richtung. Wenn ich da ein Servo anschließe, wird es mir etwas husten. Kannst du mir bitte sagen wo da eine Verzögerung von 20ms herkommt? Dass Blöde ist eher dass mir die Eingangssignale davonlaufen da das seielle Datenpaket dass generiert wird aufgrund der Anpassung der Sicherheitsabstände zwischen den Daten und den Datenpaketen etwas länger ist.
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.