www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer mit 10µs Betriebstakt, aber wie??


Autor: Debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Francesco Na (franceso-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Francesco Na

endlich mal was Produktives (ausgenommen Peter)
werd mal darüber schlafen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast recht. Mit dem CTC gehts nicht ohne Interrupt.
Aber mit dem Fast-PWM gehts.
#include <avr/io.h>

int main()
{
  ICR1 = 147;
  OCR1A = 14;

  TCCR1A = ( 1 << WGM11 );
  TCCR1B = ( 1 << WGM12 ) | ( 1 << WGM13 );

  TCCR1A |= ( 1 << COM1A1 ) | ( 1 << COM1A0 );

  DDRB = ( 1 << PB5 ) | ( 1 << PB6 );
  PORTB = ( 1 << PB5 ) | ( 1 << PB6 );
  TCCR1B |= ( 1 << CS10 );

  while( 1 )
    ;
}

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.


Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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



Autor: Christoph Kessler (db1uq) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Alex Trusk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Alex Trusk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.