Forum: Mikrocontroller und Digitale Elektronik Timer/Counter1 ATmega32


von Manni (Gast)


Lesenswert?

Jetzt muss ich doch Eure Hilfe in Anspruch nehmen, denn das Problem 
bereit mir schon fast schlaflose Nächte !

Frage:
Wie muss ich den Timer/Counter1 konfigurieren, damit aus den 
korrespondierenden Ausgängen OC1A und OC1B folgende Signale rauskommen:

OC1A  ----____----____
OC1B  --____----____----

also OC1A gegenüber OC1B um 90 Grad phasenverschoben. Übrigens: die 
Frequenz soll 40 KHz betragen, auf das eine oder andere Herz mehr oder 
weniger kommt's nicht an, nur müssen sie in der Phase richtig liegen.

Oder verlange ich da zuviel von diesem doch so intelligenten Timer mit 
den Tausend Modes ?

Bin mal gespannt, wer diese Knobelei lösen kann und bedanke mich jetzt 
schon !!

von crazy horse (Gast)


Lesenswert?

CTC Top on ICR (Frequenzeinstellung)
OutA toggle on compare
OutB toggle on compare

sollte funktionieren, probiert habe ich es nicht. In OCR1A/OCR1B  müssen 
natürlich passende Werte eingetragen werden.

von Fritz (Gast)


Lesenswert?

Ich will nicht lügen, aber das kann Timer1 wohl nicht, zumal die 
Frequenz einstellbar sein soll. So verwirrend die vielen Modi auch sind, 
universell ist T1 nicht.

von Peter D. (peda)


Lesenswert?

Verrücktes Pferd hat recht.

In OCR1A wird der Teilerwert für die gewünschte Frequenz eingetragen und 
in OCR1B die Hälfte.


Peter

von 1001. Rahul (Gast)


Lesenswert?

Statt des CTC-Mode würde ich den FastPWM-Mode mit ICR1 als TOP nehmen.
Da kann man in der ISR dann den neuen OC-Wert eintragen.
Wie man das dann weiter gestaltet ist einem selbst überlassen... ;-)

von crazy horse (Gast)


Lesenswert?

Ein PWM-mode dürfte nicht gehen.

von 1001. Rahul (Gast)


Lesenswert?

>Ein PWM-mode dürfte nicht gehen.

Warum nicht?
CTC und Fast-PWM unterscheiden sich AFAIK nur dadurch, dass FastPWM im 
Gegensatz zu CTC die Vergleichswerte zwischenspeichert und erst beim 
Erreichen von TOP aktualisiert.
Dass der Phase-correct-mode nicht geht, ist mir klar...

von Peter D. (peda)


Lesenswert?

1001. Rahul wrote:
>>Ein PWM-mode dürfte nicht gehen.
>
> Warum nicht?
> CTC und Fast-PWM unterscheiden sich AFAIK nur dadurch, dass FastPWM im
> Gegensatz zu CTC die Vergleichswerte zwischenspeichert und erst beim
> Erreichen von TOP aktualisiert.


Falsch.

Eine PWM ändert, wie ja der Name schon sagt, die Pulsweite.

Der Toggle-Pin Mode gibt aber immer 50% und der 2. Comparewert bestimmt 
dann die Phasenverschiebung zum ersten.


Peter


von 1001. Rahul (Gast)


Lesenswert?

>Falsch.

Auch wenn ich deine Begründung nicht genau verstehe (für mich gehört der 
CTC auch zu den PWM-Modi...), weiß ich jetzt auch, wieso meine Version 
nicht so funktionieren kann:
Table 45 beschreibt sehr schön das Verhalten der OC-Pins. Mit COM1A = 1 
wird der Toggle-Mode eingestellt. Der kümmert sich aber nicht um OC1B 
(normal Pinfunction).
Demnach ist der CTC-Mode der einzig mögliche.
Würde sich die Fast-PWM im Toggle-Pin-mode auch um OC1B kümmern, wäre 
das für mich die bessere Wahl.

... wieder was gelernt.

von crazy horse (Gast)


Lesenswert?

:-)
So kurz kann man es auch sagen, ich wollte gerade das Datenblatt 
zitieren, Seite 97 Fast PWM Mode.

von Manni (Gast)


Lesenswert?

Au Mann, da habe ich ja in ein Wespennest gestochen. Mit diesem 
entusiastischen Response habe ich nicht gerecht und es freut mich, dass 
meine schlaflosen Nächte wohl bald ein Ende haben werden, aber 
..........

@ Rahul: Das mit dem PWM habe mir natürlich auch angeschaut, aber auf 
Seite 106 in Tabelle 45 und auch 46 steht ja nun mal eindeutig, dass 
OC1B in diesem Mode dann abgeklemmt ist und als normales Port arbeitet; 
somit ist das Thema wohl gegessen.

Also kommt anscheinend dann doch nur der CTC Mode in Frage.

Aber dass muss mir noch mal einer erklären: Wenn das Timerregister mit 
beiden Output Compare Registern verglichen wird, kann niemals eine 
Phaseverschiebung an OC1A und OC1B rauskommen, so wie crazy horse 
vorschlägt, denn die Werte in OCR1A und B defineiren nur die Frequenz.

@ Peter: Wenn ich in OCR1A den Nominalwert eintrage und in OCR1B den 
halben, kommt zwar bei OC1A das richtige raus, aber bei OC1B leider nur 
die doppelte Frequenz. Oder liege ich da schief ?

Womit wir wieder am Anfang stehen.

@ Fritz: Vielleicht hast du ja doch recht, wenn du behauptest, das der 
Timer1 dies nicht kann. Aber ich lasse mich ja gerne noch belehren ...

Trotzdem vielen Dank an alle für euren response !

von Peter D. (peda)


Lesenswert?

Manni wrote:

> @ Peter: Wenn ich in OCR1A den Nominalwert eintrage und in OCR1B den
> halben, kommt zwar bei OC1A das richtige raus, aber bei OC1B leider nur
> die doppelte Frequenz. Oder liege ich da schief ?

Warum ?

OC1B toggled die halbe Zeit nach CNT1 = 0 und OCR1A macht gleichzeitig 
das CTC (Mode 4).


Peter

P.S.:
Beim ATMega8

von crazy horse (Gast)


Lesenswert?

jo, vielleicht sollten wir mal klären, um welchen MC genau es geht??

von AVR-Jünger (Gast)


Lesenswert?

>jo, vielleicht sollten wir mal klären, um welchen MC genau es geht??

ATmega32

(steht zumindest in der Überschrift...)

von Manni (Gast)


Lesenswert?

@Peter
Es fällt mir schwer dir zu widersprechen. Da ja nun Wochenende ist werde 
ich das mal ausprobieren ... aber so ganz glauben kann ich es noch 
nicht.

Mein Vesrtändlnis ist, das man im Mode 4 mit den Inhalten von OCR1A und 
OCR1B nur die Frequenz festlegen kann. Wieso sollte sich dann der uC um 
die Phase kümmern ?

Also ich werd mich mal ran machen...

@crazy horse
ich rede hier von einem ATmega32. Der 16er hat zwar auch einen 16bit 
counter, aber ich hab noch nicht nachgeschaut, ob er auch zwei Output 
Compare Register hat -- spielt aber hier erst mal keine Rolle.

von crazy horse (Gast)


Lesenswert?

ich hatte zum Anfang auch an den Mega32 gedacht (stand ja auch da, als 
aber Peter vom Mega8 anfing, habe ich nochmal gescrollt - für dicke 
Überschriften bin ich blind:-).
Mega16/32 sind bis auf die Speichergrössen identisch.
So, und nun noch mal zum Thema:
Der Timer läuft im CTC-Mode bis ICR, anschliessend automatisch auf Null. 
Da du ein 40kHz-Signal willst und die OCR-Pins bei jedem Durchlauf 
toggeln, muss der Timer also 1/80kHz=12,5µs laufen. Aus der 
Oszillatorfrequenz (nehmen wir mal 10MHz=0,1µs Periode) errechnet sich 
ICR=125. OCR1A und OCR1B kannst du nun auf beliebige Werte zwischen 0 
und ICR setzen. Es ergibt sich auf beiden Kanälen  ein 40kHz-Signal mit 
50:50 Tastverhältnis. Die Phasenverschiebung kommt auf die Differenz 
zwischen OCR1A/B an, mit 10MHz und 40kHz Ausgangsfrequenz kommt man also 
nicht auf exakt 90° (wahrscheinlich kannst du mit der Abweichung leben, 
ansonsten Ausgangsfrequenz und/oder Quarzfrequenz ändern.
Das alles passiert ohne jedes Zutun der CPU, also ohne Interrupts, 
Nachladen per Software o.ä.

von Fritz (Gast)


Lesenswert?

Es geht mit Modus 4. OCR1A dient als TOP und OCR1B wird mit halben Wert 
geladen.
Register etwa so:
DDRD |= 0x30; für Ausgänge
TCCR1A = 0x50; toggle A+B
TCCR1B = 0x0a; Vorteiler/8, COMPA-clear
OCR1A = x
OCR1B = 1/2 x

Glück gehabt !

von Manni (Gast)


Lesenswert?

@Fritz:
Volltreffer und Problem gelöst !!!

@Peter:
Wie sollte es auch anders sein, dein Tip war natürlich mal wieder 
richtig.

Wem darf ich denn jetzt den Scheck zuschicken ??

Nichts für ungut: vielen Dank an alle und mal wieder was dazu gelernt.

Gruß Manni

von Manni (Gast)


Lesenswert?

So, nach langwieriger Fehlersuche muss ich den Scheck wohl wieder 
einziehen !?!

Was ist passiert ? Mit:
DDRD |= 0x30; für Ausgänge
TCCR1A = 0x50; toggle A+B
TCCR1B = 0x0a; Vorteiler/8, COMPA-clear
OCR1A = x
OCR1B = 1/2 x

funktionierts, aaaaaber mal läuft die Phase von OC1A vor oder nach, 
nachdem die obrigen Anweisungen durchgeführt wurden, d.h. entweder:

OC1A  ----____----____
OC1B  --____----____----

oder mal so:

OC1A  ----____----____
OC1B  __----____----____----

Ich blicks noch nicht ganz, aber die Sache scheint wirklich etwas 
vertrackst zu sein.

Vielleicht kann Peter oder crazy horse noch mal ein Auge drauf werfen.

Gruß
Manni

von Manni (Gast)


Angehängte Dateien:

Lesenswert?

Da also keiner was damit was anfangen kann, hier der vereinfachte Code.
Mal die Problembeschreibung im Source Code zu StartTimer lesen. 
Vielleicht hat doch noch jemand eine Idee, warum dieses "seltsame" 
Verhalten des ATmega32 auftritt.

Vielen Dank schon mal für Anregungen und Kommentare.
Gruß
Manni

von Peter D. (peda)


Lesenswert?

Manni wrote:

> funktionierts, aaaaaber mal läuft die Phase von OC1A vor oder nach,
> nachdem die obrigen Anweisungen durchgeführt wurden, d.h. entweder:

Ja, das ist klar, toggle hängt eben vom Startzustand ab.

Du mußt also einen definierten Startzustand herstellen, ehe Du den Timer 
von 0 an startest.

Z.B. beide Pins auf "set low on compare", dann ein "force compare" und 
dann erst auf "toggle on compare".


Peter

von Manni (Gast)


Lesenswert?

Hallo Peter,

ich bewundere Dich immer wieder, wie du glasklar das Problem 
indentifizierst. In meiner Routine StartTimer hatte ich eigentlich 
gedacht, alles ordnungsgemäß initialisiert zu haben, d.h. beide Ports 
auf Null, Timer auf Null, etc.

Au Mann, dass "Force Output Compare" (In non-PWM waveform generation 
modes,..... usw.) habe ich im Manual noch nicht endeckt.

Ich werde weiter forschen (in diesem Falle lesen), was eigentlich eine 
Selbstvertändlichkeit sein sollte.

Ich melde mich wieder. Zunächst vielen Dank für Deine Müh

Manni

von Manni (Gast)


Lesenswert?

Problem gelöst !!!

Peter: ich danke dir für den Tip !!

Manni

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.