Forum: Mikrocontroller und Digitale Elektronik ATmega88 Timer Auflösung


von Norbert S. (norberts)


Lesenswert?

Hi,

ich will ne PWM mit 4kHz für 3 Sinus-Phasen erzeugen.
Dabei brauche ich alle 6 OCR weil ich die Deadtime im Controller 
erzeugen muß/will.
Alles kein Problem, Timer0 und 2 laufen mit Teiler 8, Werte in Tabellen 
für den Sinus und noch ein genereller Wert für die Amplitude.
Nun kann ich den Timer1 in 8bit laufen lassen aber jetzt kommt das 
Problem: Für den Sinus ansich brauche ich noch einen Zeitgeber und dafür 
reichen die 4kHz mit 8Bit Auflösung nicht. Anders ausgedrückt ich komme 
mit 72 Werten in der Sinustabelle dabei nur auf gut 0,1Hz Auflösung für 
die Sinusfrequenz und das ist etwas zu grob. Die Regelung lief mit 3x 
PWM schon (nur OCR0A/B und OCR2A) mit feinerer Auflösung der 
Sinusfrequenz (mit Timer1 als Taktgeber) und die feine Regelung habe ich 
auch gebraucht.

Lösungsansatz: Timer1 läuft mit Teiler 1 und als TOP nehme ich das ICR1 
mit  - ja und da ist das Problem.
Der ganze Kram basiert bis auf die Sinusfrequenz auf Byte. Volles Rohr 
wäre also 255. Nehme ich das x8 bin ich aber nur bei 2040 für Timer1.
TOP (=ICR1) muß aber 2048-1 = 2047 sein, da die Timer synchron laufen 
müssen.

Ich berechne also den PWM-Wert für eine Phase und das Ergebnis ist 
0...255.
Für die Phase mit Timer1 x8 macht 0 bei 0, 8 bei 1 usw. Soweit alles 
gut.
Aber bei 254 macht es 2032, bei 255 2040 und eben nicht TOP=2047.
Das einzige was mir einfällt wäre sowas:

Pwm_wert_timer1 = Pwm_wert * 8
If Pwm_wert_timer1 >= 2040 then Pwm_wert_timer1 = 2047

Das kommt mir unelegant vor aber ich sehe ehrlich gesagt kein wirkliches 
Problem.

Oder besser so:

Pwm_wert_timer1 = Pwm_wert * 8
Pwm_wert_timer1 = Pwm_wert_timer1 + 7

Ganz unten herum interessiert das nämlich nicht (Pwm_wert < 50 wird es 
nicht geben).

Eigentlich will ich nur den 8bit Wert "Pwm_wert" auf den 11bit Wert für 
Timer1 abbilden und muß bei 255 2047 erreichen.
Letztere Lösung sollte es tun, oder?

Bin für jeden Tip dankbar!
(Ausser z.B. "nimm nen anderen Controller, warum feiner als 0,1Hz 
auflösen" usw... - Das kommt alles nicht in Frage)

Gruß,
Norbert

von Peter D. (peda)


Lesenswert?

Von Atmel gibts ne AN für Drehstrommotoren mit dem ATtiny261.

Peter

von Norbert S. (norberts)


Lesenswert?

Norbert S. schrieb:
> Bin für jeden Tip dankbar!
> (Ausser z.B. "nimm nen anderen Controller, warum feiner als 0,1Hz
> auflösen" usw... - Das kommt alles nicht in Frage)

Peter Dannegger schrieb:
> Von Atmel gibts ne AN für Drehstrommotoren mit dem ATtiny261.
>
> Peter

Das habe ich erwartet. Es gibt auch andere App-Notes dazu.
Das ist aber nicht mein Problem.
Es wäre schön, wenn einer auch auf meine Problematik eingehen könnte.
Vielleicht habe ich das zu umfangreich beschrieben?

Gruß,
Norbert

von Route_66 (Gast)


Lesenswert?

Hallo!
Nimm doch als Rechenwert 1...256 anstatt 0...255. Als Ladewert dann nur 
minus 1 nehmen!

von Karl H. (kbuchegg)


Lesenswert?

> Ich berechne also den PWM-Wert für eine Phase und das Ergebnis
> ist 0...255.

Du musst dir hier, in dieser Berechnung noch sowas wie eine 
Pseudo-Nachkommastelle ausrechnen.
Und die nimmst du dann in die Berechnung für den Timer 1 noch mit rein.
1 Nachkommastelle sollte reichen.

von Norbert S. (norberts)


Lesenswert?

Hi,

1...256:
Halte ich für etwas unpraktisch. Überlege ich mal was das bedeuten 
würde.

Nachkommastelle: Das würde ja bedeuten, alles in höherer Auflösung zu 
rechnen und dann für die kleinen Timer wieder teilen. Das erscheint mir 
tatsächlich sinnvoll.

Gruß,
Norbert

von Karl H. (kbuchegg)


Lesenswert?

Norbert S. schrieb:

> Nachkommastelle: Das würde ja bedeuten, alles in höherer Auflösung zu
> rechnen

zb dem 8-fachen (Zwinker)

> und dann für die kleinen Timer wieder teilen.

was beim 8-fachen simpel ist.

> Das erscheint mir
> tatsächlich sinnvoll.

was besseres fällt mir nicht ein :-)


Man könnte es auch so sehen:
Du rechnest die PWM nicht den Timern 0 und 2 auf den Leib, sondern dem 
Timer 1.
Und anstelle T1 von T0/T2 abzuleiten, leitest du die Werte für T0/T2 von 
T1 ab. Dann kannst du auch schön runden :-)

von xfr (Gast)


Lesenswert?

Route_66 schrieb:
> Nimm doch als Rechenwert 1...256 anstatt 0...255. Als Ladewert dann nur
> minus 1 nehmen!

Ob man rechnet
1
Pwm_wert_timer1 = Pwm_wert * 8 + 7
oder
1
Pwm_wert_timer1 = (Pwm_wert + 1) * 8 - 1
macht ja keinen Unterschied.

Ich würde auch eher intern mit größeren Werten rechnen und am Ende 
"runterskalieren". Oder halt einfach + 7 rechnen, wenns nur darum geht, 
den Maximalwert zu erreichen, aber 8 Bit Auflösung reicht. Finde das 
nicht unelegant.

von Norbert S. (norberts)


Lesenswert?

Hi,

erstmal danke für den Input.

Ich mach das jetzt so (Pseudocode):

PWM_wert ist mein errechneter Wert von 0...255.

PWM1_corr = PWM_wert/32
Timer1_wert = 8 * PWM_wert + PWM_corr

So passt es an beiden Enden am besten.

Gruß,
Norbert

von Norbert S. (norberts)


Lesenswert?

Hi,

ich muß mich bei Peter Dannegger entschuldigen.
Der Tipp mit Tiny261 war goldrichtig.

Mein Konzept war totaler Bockmist. Den Timer1 pollen während er mit 
Systemtakt im Phase-correct Modus läuft ist total daneben, das geht 
nicht vernünftig.

Dabei war ich mir bis dahin so sicher...
Also immer schön das Konzept hinterfragen, manchmal verbeisst man sich 
in Details und sieht nicht mehr, daß der Ansatz schon scheisse war...

Gruß,
Norbert

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.