Hallo zusammen, habe ein kleines Problem: Ich möchte mit einem ATMega128 einen Timer bekommen welcher mit 10 µS getaktet ist und einen Overflow interrupt erzeugt. (alle 10µs x 2^16) Ich benuzte 14,7456 MHz und weis nicht wie ich zu einem solchen Betriebstakt für einen Timer kommen kann. Ich will aber keine Interrupts alle 10µs haben weil dann die Systemauslastung zu hoch wird. danke für eure Hilfe
Muss es unbedingt ein Overflow sein? Ohne jetzt nachgerechnet zu haben, denke ich dass du mit einem CTC Interrupt mit dem Timing besser hinkommen wirst. Vor allen Dingen deshalb weil du dann bei jedem beliebigen Zählerstand einen Interrupt auslösen lassen kannst und nicht erst dann wenn der Timer seinen hardwarebedingten Maximalwert erreicht hat.
Karl heinz Buchegger wrote: > Muss es unbedingt ein Overflow sein? > Ohne jetzt nachgerechnet zu haben, denke ich > dass du mit einem CTC Interrupt mit dem Timing > besser hinkommen wirst. Vor allen Dingen deshalb > weil du dann bei jedem beliebigen Zählerstand einen > Interrupt auslösen lassen kannst und nicht erst dann > wenn der Timer seinen hardwarebedingten Maximalwert > erreicht hat. Schlecht ausgedrückt. Im CTC Mode zählt der Timer bis zu einer von dir vorgegebenen Obergrenze, löst den Interrupt aus und beginnt wieder bei 0
ich benutzte den Timer als Zeitstempel auf 10µSekunden genau eben, aber ich habe KEINEN 10µs takt, das ist mein Problem, man kann ja nur durch zweiepotenzen Teilen. Der Timer soll soll jdesmal bei Überlauf einen aktion auslösen (Zeitstempelüberlauf) sonst dient er nur als Hardwaregenauer Zeitstempel.
Sag ich doch. Mit dem CTC kannst du auf dein Timing kommen. CTC - nicht Overflow Vorausgesetzt es geht sich mit den Vorteilern vernünftig aus.
Nochmal, ich brauche 10µs als Basistakt. Mit CTC kann ich zwar 10µs erzeugen, ich brauche diese Zeit aber als Taktquelle. für meinen Zeitstepel welcher Hardwaremäßig vor sich hin laufen soll. ohne Interrupt alle 10 µs, wie bekomme ich mit CTC einen TIMER mit taktquelle 10µs , das geht nicht
Bei 14.7456 Mhz hast du eine Zykluszeit von 1 / 14.745600. Macht 6.78158 E-8 Sekunden 10 µS sind 0.000010 Sekunden. 6.78 E-8 / 0.000010 = 147.456 d.h. der Zähler muss bei einem Vorteiler von 1 abwechwselnd bis 147 bzw. 148 zählen. Timer1 in CTC Modus, Obergrenze 147 und fertig. Bei 10µS wird ein CTC Interrupt angezeigt, der Zähler resettet und der nächste Zählvorgang beginnt. Jetzt musst du nur noch den externen Pin entsprechend ein bzw. Ausschalten. Sollte sich mit einer Kombination aus Compare Match Abfragen und entsprechnder Hardware Pin-Toggelei erreichen lassen. Schau doch bitte mal ins Datenblatt deines Prozessors und lies den Abschnitt über Timer1. Oder programmierst du in BASCOM?
> Schau doch bitte mal ins Datenblatt deines Prozessors > und lies den Abschnitt über Timer1. Oder programmierst > du in BASCOM? Der war gemein. Den nehme ich zurück.
Es ist doch eigentlich wurscht, ob der Timer mit 10µs läuft oder sonstwas. Willst Du damit ein Delay zählen, dann kann doch der Compiler bequem den richtigen Zählwert ausrechnen. Und willst Du ne Zeit messen und für einen Menschen in 10µs-Schritten anzeigen, dann hast Du alle Zeit der Welt für die Umrechnung, schneller als ein Lidschlag dauert. 10µs ist nicht besser und schlechter, als jede andere Zahl. Nimmste eben 4,34µs und gut is. Peter
Das gibt ein Datenlogger und die Zeitbasis für die Zeitstempel sollte eben einigermaßen vernünfig sein. Bei Aufzeichnungen auf 2 Kanälen mit 115KBd habe ich schon alle 50µs einen Interrupt, das System würde bei nochmaligen interrupt überlasten. Zu Bascom: NEIN Verarschen kann ich mich selber.
Das geht, die 14,7456 durch 32 teilen, also vorteiler 32, dann hat man ca je alle 2 uS einen increment. Weiters beim Timestamp teilt man das durch 5, also da der AVR kein HW-div hat, macht man eine Multiplication daraus. ((tick-timer * 1422) >> 16 ) + K K ist eine Korrekturkonstante, die normalerweise (tick-timer >> P) ist, kann aber auch kombinationen von solchen K´s sein, die dann addiert oder auch subtrahiert werden, oder das K auch weggezählt wird. Zur Zahl, 1000/14,7456 = 67,816840277777777777777777777778 nS / Tick Tick * 32 (prescaler) = 2170,1388888888888888888888888889 nS = 2,170138888888888888888888888888 uS / Tick Um nun vom Tick einen 10uS Wert zu erhalten, macht man folgendes: 10 uS / 2,170138888888888888888888888888 uS = 4,6080000000000000000000000000019 256*256 / 4,6080000000000000000000000000019 = 14222,222222222222222222222222219 Also, wenn man den 16bit Timer mit 14222 multipliziert, und das Resultat um 16 bit nach Rechts shiftet, erhält man die 10uS Interwalle. Da die Zahl nicht Ganzzahlig ist, muß man das noch korrigieren. 0,222222222222222222222222219 256 256 = 14563,555555555555555555555353284 Dies ist der Fehler, der unter 16bit ist, also sind die 10uS exact. Da der Timer läuft alle ca 142 mS über. Dieser Überlauf sollte dann mit dem Breshnam Algorithm gezählt werden, sowie der Korrekturwert appliziert werden, damit man einen wirklich exakte Zeit hat. Also den 32/48/64 bit counter mittels Breshnam Algorithm alle 142mS incrementieren und heisse ihn mal Tick_10_high. Um den 10uS Tick zu loggen, sollte man Tick_10_high + (cast)(( tick * (cast)1422 ) >> 16) machen. Das geht dann sehr schnell, diese Rechnung.
Danke Francesco Na endlich mal was Produktives (ausgenommen Peter) werd mal darüber schlafen.
Du hast recht. Mit dem CTC gehts nicht ohne Interrupt. Aber mit dem Fast-PWM gehts.
1 | #include <avr/io.h> |
2 | |
3 | int main() |
4 | {
|
5 | ICR1 = 147; |
6 | OCR1A = 14; |
7 | |
8 | TCCR1A = ( 1 << WGM11 ); |
9 | TCCR1B = ( 1 << WGM12 ) | ( 1 << WGM13 ); |
10 | |
11 | TCCR1A |= ( 1 << COM1A1 ) | ( 1 << COM1A0 ); |
12 | |
13 | DDRB = ( 1 << PB5 ) | ( 1 << PB6 ); |
14 | PORTB = ( 1 << PB5 ) | ( 1 << PB6 ); |
15 | TCCR1B |= ( 1 << CS10 ); |
16 | |
17 | while( 1 ) |
18 | ;
|
19 | }
|
Da der AVR-Simulator im Bereich fast-PWM ziemlich buggy ist, habe ich versucht das so gut es geht im Simulator auf einem Mega128 zu simulieren. Die PWM funktioniert grundsätzlich, der OC-Pin wird aber im Simulator nicht richtig getoggelt. Im echten Device sollte das aber nach Datenblatt gehen. > endlich mal was Produktives (ausgenommen Peter) Das nächste mal such dir die Modi selbst aus dem Datenblatt raus, wenn du schon mit der Nase darauf gestossen wirst. Das wär dann echt produktiv von dir.
@ Debugger Warum nimmst du nicht einfach einen passenden Quarz? Der Vorteiler kann mit 1/8/64/256/1024 arbeiten. D.h. bei 10uS Timertakt brauchst du einen Quarz von 100kHz/800kHz/6.4 MHz, die höheren Teiler gehen nicht, weil das Quarze über 20 MHz braucht. Alternativ kann man noch 12,8 MHz nehmen und einfach die Zeitstempel durch 2 teilen (lsr). MfG Falk
Vermutlich braucht er die 14,7456 für die serielle Schnittstelle, um mehr als 9600 Baud sauber einzustellen. Der Vorschlag mit dem abwechselnden Teilen durch 147 / 148 scheint mir die einzige Lösung zu sein. Man könnte es verfeinern, (so wie Schaltjahre alle 4 Jahrhunderte ausfallen) und die 147.456 genauer als durch 147,500 annähern. Ergebnis ist natürlich ein kleiner Jitter des Zeitstempels, aber der mittelt sich heraus.
den ganzen "stress" kann man sich sparen, wenn man auf peter dannegger hoert und die gewuenschte 10µs-aufloesung aus einem beliebigen takt nachtraeglich ausrechnet. das mag zwar nicht in das vorher so toll ausgedachte konzept passen, aber ich finde, es ist die praktikabelste loesung. 2 portpins und 2 timer zu "opfern"(ein timer erzeugt den takt des anderen) ist allerdings auch ein netter workarround. leider scheint das ja mit ctc nicht zu klappen(habs grad nicht selber nachgelesen), aber mit fast-pwm soll es laut Karl heinz Buchegger gehen. ein bisschen eigeninitiative waere hier vielleicht angebracht. gruss, alex.
@ Christoph Kessler Mit 12,8 kann man auch alle Baudraten sehr genau erzeugen. 1% Frequenzabweichung ist problemlos akzeptabel! Mein Excel sheet sagt für 14,4k bis 115,2k -0.8%. Passt schon. Das it dem durch 147/148 halte ich für arg aufwendig. @Alex Trusk Wieso Stress? 12,8 MHz und gut ist. Klar, Peters Methode wird in den meisten Fällen auch sehr gut funktionieren, aber wenn es beispielsweise darum geht, bestimmte Vorgänge mit klar definiertem Zeitraster aufzuzeignen und darzustellen wirds umschön und ggf aufwändig. Niemand will ein Oszilloskop, das 4,75 us/ DIV anzeigt. MfG Falk
ok, das mit dem stress ist relativ und koennen wir aussen vor lassen. die 12,8 MHz sind damit die dritte(?) alternative und ein externer 100kHz oszillator waere eine vierte. ich persoenlich wuerde entweder die ctc-variante waehlen und im int eine hilfsvariable hochzaehlen, oder falls das wirklich zu viel ressourcen frisst(was ich nicht glaube), auf peters variante ausweichen.
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.