Forum: Mikrocontroller und Digitale Elektronik Realisierungsfrage zum Timer


von Sören K. (fluxkompensator)


Lesenswert?

Guten Tag,

[Atmega 16/32]
Ich möchte mehrere digitale Kanäle/Ausgänge (ca 8-16 Stück) zeitversetzt 
für eine variable Zeit (0,xms bis ca 5ms) schalten (Impulslänge variiert 
auch unter den einzelnen Kanälen). Zwischen den Schaltimpulsen der 
einzelnen Kanäle liegen in etwa 20ms. Daraus folgt ja, dass sich 
einzelne Impulse teilweise überschneiden.

Ich habe mir schon einige Tutorials über den Timer durchgelesen, 
trotzdem weiß ich nicht, wie ich das realisieren kann mit der begrenzten 
Anzahl an Timern.

Ich hoffe auf eure Hilfe,
fluxkompensator

von Pete K. (pete77)


Lesenswert?

Kannst Du nicht den Timer auf die kleinste "Auflösung" stellen und dann 
bei jedem Tick entscheiden, welchen Impuls Du auslösen willst ?

Also nicht ein Timer pro Impuls, sondern ein Timer für alle Impulse.

von Sören K. (fluxkompensator)


Lesenswert?

Hört sich logisch an.

Kann ich bei der Abarbeitung dieser Vergleiche im main-programm einfach 
mit if-Befehlen arbeiten oder gibt es dann Probleme zwischen dem 
linearen Ablauf des Programms und der teilweisen Überlappung der 
Schaltzeiten?

von Gast (Gast)


Lesenswert?

Ich würde auch einen Timer mit einer Taktzeit von 1ms generieren und in 
der ISR dann über verschiedene Variablen einzelne Timer generieren. Wenn 
der Timer sofort wieder gestartet wird hast du da auch keine 
Zeitverzögerung.

von sam (Gast)


Lesenswert?

vor dem schaltvorgang erstellt man sich eine tabelle erstellen mit dem 
portzustand sowie dem zeitstempel:
zeit[]   portausgabe[]
0        11110000
13       11100000
50       11100001

usw.
den algorythmus kann man dann mit dem timer aufrufen (ein paar takte 
länger als die minimale ausführungszeit)
1
if ( zeit[index+1] >= zähler)  index++;
2
port = portausgabe[index];
3
zähler++;

wenn du das z.b. alle 0.1ms aufrufst hast du eine zeitliche auflösung 
von 0.1ms mit der du beliebig viele ausgänge ansteuern kannst ... 
vorrausgesetzt dein µC ist schnell genug.

von Sören K. (fluxkompensator)


Lesenswert?

Hallo,

Die Idee von sam finde ich sehr gut.
Ich hoffe, ich habe sie richtig verstanden:
Man legt zunächst fest, wann welche Pins gesetzt werden und vergleicht 
dann mit der unteren Routine, ob es soweit ist? Ganz klar ist mir die 
Sache mit dem Index noch nicht.
Und: Wie legt man so eine mehrspaltige Tabelle an?

Ich benötige allerdings eine zeitliche Auflösung von 0.01ms, d.h. 10ns.
Kann man irgendwie ausrechnen, ob bspw. ein ATmega16 oder ATmega32 mit 
8/16MHz getaktet das hinbekommt?

Viele Grüße,
fluxkompensator

von Sören K. (fluxkompensator)


Lesenswert?

Korrektur: Ich meinte natürlich 10µs

von STK500-Besitzer (Gast)


Lesenswert?

>Kann man irgendwie ausrechnen, ob bspw. ein ATmega16 oder ATmega32 mit
>8/16MHz getaktet das hinbekommt?

Ja.
Wie groß ist denn die Periodendauer bei 8MHz?
Vielfache davon passen in 10µs.
Soviele Takte muß der Timer laufen, bis er einen Interrupt erzeugt 
(CTC-Mode).
Bei 16MHz ist es halt die doppelte Anzahl.

von Sören K. (fluxkompensator)


Lesenswert?

Hallo STK500-Besitzer,

Periodendauer bei 8MHz sind 125ns, dementsprechend bei 16MHz 62,5ns.
Aber die Realisierbarkeit müsste ja auch noch davon abhängen, wie lange 
die Abarbeitung dieser Routine erfordert, oder? Und das kann ich halt 
überhaupt nicht einschätzen.

Grüße,
fluxkompensator

von STK500-Besitzer (Gast)


Lesenswert?

Der Timer arbeitet unabhängig von ISR-Länge. D.h. der Interrupt tritt 
auf jeden Fall auf, auch wenn die ISR noch abgearbeitet wird.
Man sollte ISRs immer so kurz wie möglich halten. Bei einer Taktfrequenz 
von 8MHz hätte man dann zwei Interrupt Zeit für etwa 80 Befehle (Befehle 
mit 1 Takt Abarbeitungszeit).
Man sollte also in die ISR nur eine Variable herunterzählen, die den 
Abstand zum nächsten Schaltpunkt angibt und dann den nächsten Wert an 
den Port schreiben. Das sollte sogar in C noch ohne besondere 
Optimierungseinstellungen gehen.

von Michael H. (mah)


Lesenswert?

Ich  glaube, für dieses Problem sind software-Timer gut geeignet, deren 
Anzahl ist im Gegensatz zu Hardware-Timern nicht beschränkt,

Sie Dir mal Peter Danegger's Timer an, zB: 
Beitrag "Wartezeiten effektiv (Scheduler)"
oder den von Jörg Wunsch: http://www.sax.de/~joerg/avr-timer/ .

Die Timer-Tick-Rate legt die Auflösung fest.

-Michael

von sam (Gast)


Lesenswert?

die liste ist ein normales array in c ... int_array ist quasi der zeiger 
auf den anfang des speicherbereichs und der index in eckigen klammern 
ist das zu dem zeiger addiert wird vor der dereferenzierung
1
int int_array[3];
2
3
int_array[0]=2;
4
int_array[1]=8;
5
int_array[2]=5;

was mir noch einfiel :
wenn sich diese einzelnen signale zyklisch wiederholen sollen, sollte 
man sich ein anderes system überlegen.

wenn der schaltvorgang einmalig ist oder insgesamt zyklisch, muss man 
die hilfsvariablen ja nur zurücksetzen.

dazu ist zu beachten, dass man mit mind. 16 bit zählen sollte und evtl 
eine 16 bit portmaske braucht ... und 16 bit auf einem 8 bit prozessor 
zu benutzen, braucht ja mind. doppelt soviel zeit zur ausführung.

im avr-studio kann man ja in der simulation die ausfrührungszeit 
anschauen.
der atmega48 oder atmega 88 läuft auch mit 20 MHz ... falls du noch 
etwas rauskitzeln willst.

von Sören K. (fluxkompensator)


Lesenswert?

Das ganze soll sich zyklisch wiederholen.
Die Zyklen sind variabel zwischen 20ms und 200ms lang. (Regle ich mit 
einem ADC)
In jedem Zyklus sollen alle ca 16 Signale zeitlich möglichst gut 
aufgeteilt, d.h. versetzt, ausgegeben werden. Dass sich die Signale 
dabei teilweise überschneiden ist mir klar.

Grüße,
fluxkompensator

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
Noch kein Account? Hier anmelden.