Forum: Mikrocontroller und Digitale Elektronik Attiny85 Timer1 PWM: Keine Duty-Cycle-Formel (da nichtlinear?)


von Hans W. (Gast)


Lesenswert?

Hallo,
kann mir jemand erklären warum die PWM vom Timer0 und Timer1 
unterschiedlich funktionieren? Genauer gesagt wundere ich mich, dass 
beim Timer1 die PWM beim min. UND beim max. Wert konstant auf Minimum 
oder Maximum gehalten werden.
Beim Timer0 ist das nicht so und der ist linear, denn der kann z.B. von 
0/256 bis 255/256 (1/256 - 256/256).
Wie man jetzt beim Timer1 mit 256 Eingangszuständen, 257 
Ausgangszustände erzeugen will, ist mir nicht so gaanz klar... Welcher 
Wert da übersprungen wird - keine Ahnung! Vielleicht der obere, 
vielleicht der untere, oder einer aus der Mitte.. Das ist jedenfalls 
seltsam, oder?!

Besten Dank & schöne Grüße
Hans W.

von Stefan F. (Gast)


Lesenswert?

Wo hast du diese Zahlen her?

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>kann mir jemand erklären warum die PWM vom Timer0 und Timer1
>unterschiedlich funktionieren?

Weil sie verschieden aufgebaut sind.

>Genauer gesagt wundere ich mich, dass
>beim Timer1 die PWM beim min. UND beim max. Wert konstant auf Minimum
>oder Maximum gehalten werden.

???

>Beim Timer0 ist das nicht so und der ist linear, denn der kann z.B. von
>0/256 bis 255/256 (1/256 - 256/256).

Kann Timer 1 auch.

>Wie man jetzt beim Timer1 mit 256 Eingangszuständen, 257
>Ausgangszustände erzeugen will, ist mir nicht so gaanz klar...

Will man gar nicht.
>
> Welcher
>Wert da übersprungen wird - keine Ahnung! Vielleicht der obere,
>vielleicht der untere, oder einer aus der Mitte.. Das ist jedenfalls
>seltsam, oder?!

Nö. Das Zauberwort heißt Fast PWM und Phase/Frequency Correct PWM.
Ersterer kann nicht 0/256 oder 255/255 erzeugen, je nach Einstellung, 
letzterer schon.

RTFM.

Linear sind beide.

von c-hater (Gast)


Lesenswert?

Hans W. schrieb:

> kann mir jemand erklären warum die PWM vom Timer0 und Timer1
> unterschiedlich funktionieren?

Nein, das kann dir sicher niemand erklären. Warum?

Weil du nicht mal erwähnt hast, um welche Sorte Timer es geht, also 
welcher µC sie bereitstellt. Ausserdem natürlich auch deshalb, weil du 
nicht mal erwähnt hast, wie du die Timer initialisiert hast, denn selbst 
bei einem µC können Timer durchaus recht verschiedene Sachen tun, je 
nach ihrer Initialisierung.

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

Verdammt, Subject völlig ignoriert, mein Fehler. Also Tiny85. Damit ist 
klar, was die Timer können.

Das allerdings bleibt:

> Ausserdem natürlich auch deshalb, weil du
> nicht mal erwähnt hast, wie du die Timer initialisiert hast, denn selbst
> bei einem µC können Timer durchaus recht verschiedene Sachen tun, je
> nach ihrer Initialisierung.

von Hans W. (Gast)


Lesenswert?


von Hans W. (Gast)


Lesenswert?

>Weil du nicht mal erwähnt hast, um welche Sorte Timer es geht, also
>welcher µC sie bereitstellt.

Attiny85 Timer1 PWM (-Mode)

von Hans W. (Gast)


Lesenswert?

Beim Timer1 gilt doch:
0 -> 0/256 (=nie an)
255 -> 256/256 (=immer an)
Wenn z.B. weiter gilt:
1 -> 1/256
2 -> 2/256
...
Was ist dann mit:
254 -> ??

Da muss es ja irgendwo einen Sprung geben..

Und zum Timer0: Kann ich den irgendwie so konfigurieren, dass
0 -> 0/256
...
255 -> 255/256
statt
0 -> 1/256
...
255 -> 256/256

K.A. warum da nicht 0 auf 0 abgebildet wird!

von Reiner_Gast (Gast)


Lesenswert?

Hans W. schrieb:
> Beim Timer1 gilt doch:
> 0 -> 0/256 (=nie an)
> 255 -> 256/256 (=immer an)
> Wenn z.B. weiter gilt:
> 1 -> 1/256
> 2 -> 2/256

Also... 8 Bits können 256 Zustände beschreiben (= 2^8)

Der Wert "0" wäre also der erste Zustand (1/256 nach deiner Bezeichnung) 
der vorkommen kann.

Weiter wird dann:
Wert    Zustand
1    ->    2/256
2    ->    3/256 ... usw.
254  ->  255/256
255  ->  256/256

Da ist kein Sprung drinnen...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hans W. schrieb:
> 0 -> 0/256 (=nie an)

Nein.

0   -> 1/256
255 -> 256/235

Wenn Du die PWM ausschalten willst, schalte die PWM über die 
entsprechenden Register aus.

von Hans W. (Gast)


Lesenswert?

>Da ist kein Sprung drinnen...
Nein, das ist kein Sprung drin, weil es dem Verhalten von Timer0 
entspricht.
Mir gehts aber um Timer1 im PWM-Modus (sofern man Timer0 nicht zu "0 -> 
0/256" bringen kann).

Laut folgendem gibt es beim Timer1 sowohl "ganz an" als auch "ganz aus"! 
Was, ohne Sprünge anzunehmen, auf 257 (= 2^8+1..) Zustände hinaus läuft.

http://cdn-reichelt.de/documents/datenblatt/A300/ATTINY25-ATTINY45-ATTINY85_DATASHEET.pdf#G1.1849153

Tabelle 12.2


>Wenn Du die PWM ausschalten willst, schalte die PWM über die
>entsprechenden Register aus.
Daran habe ich auch schon gedacht. Aber wenn ich das richtig sehe, führt 
das zu Glitches, da der Vergleichswert zwar gepuffert ist (gegen 
Glitches), aber das Aus-/Anschalten nicht (meine ich).

von Hans W. (Gast)


Lesenswert?

>(sofern man Timer0 nicht zu "0 -> 0/256" bringen kann)
* im Saw-PWM-Modus...

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>Mir gehts aber um Timer1 im PWM-Modus (sofern man Timer0 nicht zu "0 ->
>0/256" bringen kann).

Mensch Hans, nimm das Ding, programmier ne PWM und schau es dir mit dem 
Oszi an. Das geht schneller.

>Laut folgendem gibt es beim Timer1 sowohl "ganz an" als auch "ganz aus"!

Ja.

>Was, ohne Sprünge anzunehmen, auf 257 (= 2^8+1..) Zustände hinaus läuft.

Nö. Es sind 256 Zustände, weil der Durchlauf bei DEM Timer in DIESEM AVR 
auf nur 255 Takte programmierbar ist. Dieser Timer ist anders als die 
üblichen Timer der meisten älteren AVRs aufgebaut.

0/255 bis 255/255, macht exakt 256 Zustände incl. Dauer LOW und Dauer 
HIGH.

Die älteren Timer z.B  im Atmega 328 (Arduino) können das nur im Phase 
correct mode (uo/down, dual slope mode). Bei Fast PWM (single slope) 
dieser "alten" Timer hat man immer das Problem, daß eben entweder 0/256 
oder 256/256 nicht geht!

>Tabelle 12.2

Die Tabelle nützt hier praktisch gar nichts.

von Sven K. (quotschmacher)


Lesenswert?

Hans W. schrieb:!
> Was, ohne Sprünge anzunehmen, auf 257 (= 2^8+1..) Zustände hinaus läuft.

Ist dir klar, was 8 bit bedeutet? Das geht ziemlich genau von 0 bis 255 
und mehr kann man damit nicht darstellen.

von Hans W. (Gast)


Lesenswert?

>weil der Durchlauf bei DEM Timer in DIESEM AVR
>auf nur 255 Takte programmierbar ist.

Wollte das gerade austesten... (um nen anderen Timer eines anderen AVRs 
gings mir ja auch nie)
Die Leute konnten sich wohl nicht entscheiden, ob ihr Datenblatt eher 
Nachschlagewerk, oder Einführungslektüre sein soll.. Naja dann schreibt 
man lieber vieles doppelt und dreifach hinein und lässt kurze, prägnante 
Fomeln weg. Heraus kommt dieses Monster.

>Die Tabelle nützt hier praktisch gar nichts.
Weil? ..Sie beschreibt doch, wenn auch etwas zu kryptisch, das von dir 
genannte Verhalten (DES Timers DIESES AVRs)...
Bzw. wozu ist sie dann gut?!?

>Ist dir klar, was 8 bit bedeutet? Das geht ziemlich genau von 0 bis 255
>und mehr kann man damit nicht darstellen.
Das is ja mal doof. Ich hätte zu gerne auf [-127,128] abgebildet, oder 
auf {rot, blau, grün,..}...

von c-hater (Gast)


Lesenswert?

Hans W. schrieb:

> Beim Timer1 gilt doch:
> 0 -> 0/256 (=nie an)
> 255 -> 256/256 (=immer an)

Nein.

Der Timer1 der ATtiny25/45/85 ist was völlig anderes als der Timer1 der 
ATmegas (den einige der Thread-Teilnehmer wohl im Kopf hatten, als sie 
ihre Postings verfasst haben). Aber selbst bei denen würde das niemals 
gelten. Bei keinem AVR8-Timer ist es möglich, allein über das 
OCRxy-Register mehr Zustände zu realisieren, als der Zählumfang des 
Counters im jeweiligen Modus bietet.

Grundsätzlich muss man unterscheiden zwischen single slope (=fast PWM) 
und dual slope (=phase correct oder phase and frequency correct). Dual 
slope-Betriebsarten können nur einige Timer der ATmegas, üblicherweise 
halt mindestens Timer1, bei den größeren Megas auch noch weitere.

Der Timer1 der Tiny25/45/85 kann das aber nicht. Er bietet im Prinzip 
nur dieselbe Hausmannskost wieTimer0, also maximal fast PWM mit 8Bit und 
dementsprechend 256 über das OCRxy ansteuerbaren verschiedenen 
Zuständen. Je nach Initialisierung und angesteuerter Schaltung geht also 
entweder "komplett an" oder "komplett aus" nicht. Diese Zustände muss 
man unter Zuhilfenahme anderer Steuermöglichkeiten erreichen.

Die einfachste ist, mit DDRx des Ports zu hantieren, über den die 
PWM-Ausgabe läuft, das erfordert aber je nach angeschlossener Schaltung 
ggf. einen externen Pulldown-Widerstand.

von Falk B. (falk)


Lesenswert?

@ c-hater (Gast)

>Der Timer1 der Tiny25/45/85 kann das aber nicht.

Stimmt nicht. RTFM.

"When OCR1A or OCR1B contain $00 or the top value, as specified in OCR1C 
register, the output PB1(OC1A) or PB4(OC1B) is held low or high 
according to the settings of COM1A1/COM1A0. This is shown in Table 
12-2."

D.h. wenn man 0xFF in OCR1C reinschreibt, welches den Zählumfang von 
Timer 1 bestimmt, zählt Timer 1 von 0-255 und fängt bei 0 wieder an, 
macht 256 Schritte. Allerdings gibt es in der PWM-Ausgabe halt die 
Sonderfälle, wenn

OCR1A == 0, dann wird 0/256 ausgegeben
OCR1A = OCR1C (hier 0xFF), dann wird Dauer-HIGH = 256/256 ausgegeben.

Bei 1 ist es 1/256, bei 2/256 etc. EIGENTLICH müßte bei 255 255/256 
ausgegeben werden, die Speziallogik verhindert das aber! Damit kommt in 
der letzten Stufe ein Sprung rein! nämlicht von 254/256 auf 256/256!! 
Ich glaube DAS meinte der OP!

Da ist zugegebenermaßen ein bisschen blöd.


> Er bietet im Prinzip
>nur dieselbe Hausmannskost wieTimer0, also maximal fast PWM mit 8Bit und
>dementsprechend 256 über das OCRxy ansteuerbaren verschiedenen
>Zuständen. Je nach Initialisierung und angesteuerter Schaltung geht also
>entweder "komplett an" oder "komplett aus" nicht
> Diese Zustände muss
>man unter Zuhilfenahme anderer Steuermöglichkeiten erreichen.

Falch, genau das GEHT, eben durch die Speziallogik als Sonderlösung, 
siehe Tabelle 12-2! Ob das nur besser ist, sei dahingestellt.

>Die einfachste ist, mit DDRx des Ports zu hantieren, über den die
>PWM-Ausgabe läuft, das erfordert aber je nach angeschlossener Schaltung
>ggf. einen externen Pulldown-Widerstand.

Nö, man schaltet einfach per COMxy DIE PWM auf den Ausgangsport oder 
nicht. denn dessen Zustand kann man per PORTx definieren.

Der Dual Slope Modus des Timer 1 der "normalen" AVRs ist da besser, denn 
der KANN 0/255 und 255/255 problemlos erzeugen, auch mit beliebig 
anderen Periodendauern dank CTC-Modus.

von Hans W. (Gast)


Lesenswert?

>Ich glaube DAS meinte der OP!
DANKESCHÖN!

Hast du mal ausgestestet, wo der Sprung stattfindet?
(Er zählt also doch nicht nur bis 255?????)

von Hans W. (Gast)


Lesenswert?

>CTC-Modus
Hat der Timer0 ebenfalls, nur der fängt ja bei 0 -> 1/256 an! ARGH!!!

von Hans W. (Gast)


Lesenswert?

....Oder macht der da nur wenn TOP == MAX ..... Das wäre ja noch zu 
verkraften - fast schon nachvollziehbar.
Man weiß es nicht. Ich wollte doch "nur mal eben kurz". Ich dreh durch!

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>>Ich glaube DAS meinte der OP!
>DANKESCHÖN!

Heureka! ;-)

>Hast du mal ausgestestet, wo der Sprung stattfindet?

Nö, hab das so noch nie benutzt, den Tiny85 auch nicht.
Mal sehen, vielleicht morgen, da könnte einer in der Firma rumliegen.

>(Er zählt also doch nicht nur bis 255?????)

Doch, denn es ist ja ein 8 Bit Zähler, mher geht nicht ;-)
Er kann aber auch weniger zählen, wenn man in ICR1C eine andere 8 Bit 
Zahl reinschreibt.

>>CTC-Modus
>Hat der Timer0 ebenfalls, nur der fängt ja bei 0 -> 1/256 an! ARGH!!!

Nö, bei 0 kommt 0/256 raus, bei 1 1/256 etc. Der Sprung ist nur am 
oberen Ende.

Ja, aber da finde ich die Doku eine wenig konfus. Dieser Timer ist 
irgendwie kein Meisterwerk von Atmel. Denn wenn das Ding sowieso ein 
eigenes für CTC Mode reserviertes Register hat, ist die Unterscheidung 
zwischen CTC und Normalmodus überflüssig. Modernere Timer in neueren 
32Bit uCs haben das sowieso, da gibt es auch keinen expliziten CTC 
Modus, denn die Periode des Timers wird da IMMER über ein extra Register 
definiert. Der CTC Modus ist nur eine Sparversion von Atmel, die eine 
handvoll Register sparen und damit doppelt belegen wollte (OC1A, ICR1 im 
CTC Modus). Ob DAS so sinnvoll war? Wieviel um^2 Silizium und uCent hat 
man da beim Design gespart?

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>....Oder macht der da nur wenn TOP == MAX ..... Das wäre ja noch zu
>verkraften - fast schon nachvollziehbar.
>Man weiß es nicht. Ich wollte doch "nur mal eben kurz". Ich dreh durch!

Warum denn? Wenn du diesen komischen Effekt nicht haben willst, nimm 
Timer 0, der kann phase correct PWM, da paßt das.

von Hans W. (Gast)


Lesenswert?

>(Er zählt also doch nicht nur bis 255?????)
Sorry falsch formuliert: Er hat dann doch nicht nur 255 Zustände??? (Er 
zählt also doch nicht nur bis 254?????)

>Er kann aber auch weniger zählen, wenn man in ICR1C eine andere 8 Bit
>Zahl reinschreibt.
Das wäre jetzt die nächste Frage: Wenn OCR1C<255, z.B. OCR1C = 254, 
springt er dann, unnötiger Weise, bei 253 auch schon auf 255/255 ?


>Nö, bei 0 kommt 0/256 raus, bei 1 1/256 etc. Der Sprung ist nur am
>oberen Ende.
So wie ich das Datenblatt verstehe, gibt diesen Sprung nur beim Timer1. 
Timer0 braucht keinen Sprung, weil da nicht gilt, dass er sowohl ganz an 
(256/256), als auch ganz aus (0/256) sein kann. Somit werden die 256 
Zustände auf [1/256, 256/256] abgebildet.
Beim Timer1 werden 256 Zustände wohl auf [0/256, 256/256] abgebildet, 
mit einem Sprung irgendwo dazwischen, oder auf [0/255, 255/255], dann 
evtl. ohne Sprung,..

>Ob DAS so sinnvoll war? Wieviel um^2 Silizium und uCent hat
>man da beim Design gespart?
Das habe ich mich auch gefragt, aber zuerst natürlich, ob ich es nich 
doch irgendwie dazu bringen kann, das zu machen, was ich mir vorstelle..

von Hans W. (Gast)


Lesenswert?

>der kann phase correct PWM
Der kann aber keinen PLL-Takt.. Das wären 64MHz vs. 16/2 Mhz Takt..

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>Sorry falsch formuliert: Er hat dann doch nicht nur 255 Zustände??? (Er
>zählt also doch nicht nur bis 254?????)

Der Zähler geht im Normalmodus von 0-255.

>>Er kann aber auch weniger zählen, wenn man in ICR1C eine andere 8 Bit
>>Zahl reinschreibt.

>Das wäre jetzt die nächste Frage: Wenn OCR1C<255, z.B. OCR1C = 254,
>springt er dann, unnötiger Weise, bei 253 auch schon auf 255/255 ?

Nein, bei 254 geht er auf 255/255. Bei 253 sind es aber 253/255, eben 
die Lücke.

>So wie ich das Datenblatt verstehe, gibt diesen Sprung nur beim Timer1.

Ja.

>Timer0 braucht keinen Sprung, weil da nicht gilt, dass er sowohl ganz an
>(256/256), als auch ganz aus (0/256) sein kann.

Stimmt.

> Somit werden die 256
>Zustände auf [1/256, 256/256] abgebildet.

Aber nur im Phase vorect mode.

>Beim Timer1 werden 256 Zustände wohl auf [0/256, 256/256] abgebildet,

Nein, man muss zwischen Fast PWM und Phase correct Mode unterscheiden.

 >mit einem Sprung irgendwo dazwischen,

Nein, dort gibt es keinen Sprung, wohl aber nicht alle wünschenswerten 
Zustände.

von Hans W. (Gast)


Lesenswert?

>Nein, dort gibt es keinen Sprung, wohl aber nicht alle wünschenswerten
Zustände.
Jetzt verwirrst du mich. Also ich meinte mit Sprung das Auslassen einer 
bestimmten Pulsbreite.

>Nein, bei 254 geht er auf 255/255. Bei 253 sind es aber 253/255, eben
>die Lücke.
Tja was soll ich sagen: Das ist leider falsch. Da waren wir wohl zu 
optimistisch. Der Timer1 funktioniert quasi doch genau so wie Timer0, 
nur dass statt "0 -> 1/256", "0 -> 0/256" gilt, der Rest bleibt aber 
gleich. Sprich der Sprung findet ganz am Anfang statt....
So ein Müll, d.h. ich muss mich zwischen einem langsamen Timer mit Bias, 
oder einem schnellen mit Bias und Nichtlinearität entscheiden :/

von Stefan F. (Gast)


Lesenswert?

> Aber nur im Phase vorect mode.

Phase verreckt Modus? :-)

von Falk B. (falk)


Lesenswert?

@Hans W. (Gast)

>>Nein, dort gibt es keinen Sprung, wohl aber nicht alle wünschenswerten
>Zustände.
>Jetzt verwirrst du mich. Also ich meinte mit Sprung das Auslassen einer
>bestimmten Pulsbreite.

Das habe ich auch so verstanden.

>>Nein, bei 254 geht er auf 255/255. Bei 253 sind es aber 253/255, eben
>>die Lücke.

>Tja was soll ich sagen: Das ist leider falsch. Da waren wir wohl zu
>optimistisch. Der Timer1 funktioniert quasi doch genau so wie Timer0,
>nur dass statt "0 -> 1/256", "0 -> 0/256" gilt, der Rest bleibt aber
>gleich. Sprich der Sprung findet ganz am Anfang statt....

Woher weißt du das? Hast du das getestet?

>So ein Müll, d.h. ich muss mich zwischen einem langsamen Timer mit Bias,
>oder einem schnellen mit Bias und Nichtlinearität entscheiden :/

Brauchst denn denn die Extremwerte bei dem Timer?

von Peter D. (peda)


Lesenswert?

Falk B. schrieb:
> Brauchst denn denn die Extremwerte bei dem Timer?

In der Regel braucht man die nicht. Keiner sieht, ob eine LED 100% an 
ist oder nur 99,6%.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> In der Regel braucht man die nicht. Keiner sieht, ob eine LED 100% an
> ist oder nur 99,6%.

Eben. Lesenswert in dem Zusammenhang ist: LED-Fading

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Ich hab da mal was getestet, siehe Anhang.

Ergo. Der Ansatz ist gut gemeint, aber praktisch eher schlecht 
umgesetzt. Die Lücke zwischen den beiden letzten PWM-Werten ist nervig. 
Timer 0 macht das besser, selbst im Fast PWM Mode.

von Peter D. (peda)


Lesenswert?

Falk B. schrieb:
> Die Lücke zwischen den beiden letzten PWM-Werten ist nervig.

Interessant, wußte ich bisher nicht. In der Praxis wird sich das kaum 
bemerkbar machen.

von Falk B. (falk)


Lesenswert?

@ Peter D. (peda)

>> Die Lücke zwischen den beiden letzten PWM-Werten ist nervig.

>Interessant, wußte ich bisher nicht. In der Praxis wird sich das kaum
>bemerkbar machen.

In der Praxis machen sich solche Effekte immer dann bemerkbar, wenn man 
sie am wenigsten gebrauchen kann!

von Joachim B. (jar)


Lesenswert?

hmm, auch wenn ich kaum verstehe worum es geht.....

Lücke oder Sprung, TIMERn

Ich steuere ja ein Nokia5110 mit dem ATmega328p an und nutze die Arduino 
PWM Funktion. Dazu habe ich die LED Fading

https://www.mikrocontroller.net/articles/LED-Fading

Tabelle für 11 Werte generieren und umdrehen müssen:

const uint8_t pwmtable_11C[] PROGMEM = {255, 253, 251, 248, 244, 236, 
223, 201, 164, 103,   1};

als ich von Stufe 0 = 255 geringste Helligkeit 0% langsam in 9% 
Schritten (0-10) hoch ging erwartete ich die größte Helligkeit eben bei 
0 -> Stufe 10 = 100% -> pwmtable_11C[10] nur was passierte, die 
Hintergrundbeleuchtung ging aus, die höchste Stufe erreichte ich bei 1, 
deswegen endet die Tabelle bei 1  und nicht bei 0.

analogWrite(BL, pgm_read_byte(&pwmtable_11C[MY_EEP_VAR.backlicht]));

Ist das der "Sprung" wovon hier die Sprache ist? und warum, das wird mir 
immer noch nicht klar, aber weil Arduino genutzt wird und ich dort die 
Timer Modi nicht sehe muss ich raten.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> Ist das der "Sprung" wovon hier die Sprache ist?

Soweit ich das bisher hier verstanden habe, gibts den "Sprung" bei den 
ATmegas nicht. Hier geht es um ATTiny25/45/84. Von daher ist Dein 
ATmega328 raus.

von Stefan F. (Gast)


Lesenswert?

> wenn ich kaum verstehe worum es geht

Bei mir hat es auch einige Beiträge gedauert bis ich das Anliegen des TO 
verstanden habe. Das kannst du an meiner Spontanen Frage ganz oben 
erkennen.

Ein idealer 8bit PWM Timer könnte Impulse mit einer Breite von 0 bis 256 
Takte erzeugen, was einer analogen Ausgangsspannung von 0 bis 100% in 
gleichmäßigen Schritten entsprechen würde.

Beim Steuerwert 0 bekommst du am Ausgang ein Signal, das für die Dauer 
von 0 Takten bei insgesamt 256 Takten High ist, also immer Low.

Beim Steuerwert 1 bekommst du am Ausgang ein Signal, das für die Dauer 
von 1 Takt bei insgesamt 256 Takten High ist.

Beim Steuerwert 2 bekommst du am Ausgang ein Signal, das 2 von 256 
Takten High ist.

...

Beim Steuerwert 253 bekommst du am Ausgang ein Signal, das 253 von 256 
Takten High ist.

Beim Steuerwert 254 bekommst du am Ausgang ein Signal, das 254 von 256 
Takten High ist.

Und jetzt kommt die Ausnahme:

Beim Steuerwert 255 bekommst du am Ausgang ein Signal, das 256 von 256 
Takten High ist, also immer High.

Wenn du damit eine LED ansteuerst, wird sie bei jeder Stufe um 0,39% 
heller. Außer ganz zum Schluss, da macht sie einen doppelt so großen 
Sprung von 99,21% nicht auf 99,6% sondern auf 100%.

Mit bloßem Auge kann man diesen feinen Unterschied aber nicht sehen, 
weil das Auge logarithmisch reagiert. Je heller die LED leuchtet, umso 
weniger nimmt man feine Unterschiede wahr.

Oder anders formuliert: Bei der Treppe fehlt am oberen Ende eine Stufe, 
die letzte ist doppelt so hoch.

von Hans W. (Gast)


Lesenswert?

>In der Regel braucht man die nicht. Keiner sieht, ob eine LED 100% an
>ist oder nur 99,6%.
Aber man hört es.

>In der Praxis machen sich solche Effekte immer dann bemerkbar, wenn man
>sie am wenigsten gebrauchen kann!
Hmhm! Und noch schlimmer: Ich weiß, dass es sie gibt.

>Ich hab da mal was getestet, siehe Anhang.
Wie hast du das denn getestet? In meinen Tests kam heraus, dass er zu 
Beginn springt!
Kurz:
Timer1:
0 -> 0/256
1 -> 2/256
2 -> 3/256
...
255 -> 256/256

Timer0:
0 -> 1/256
1 -> 2/256
2 -> 3/256
...
255 -> 256/256

Bin mir eig ziemlich sicher, dass das stimmt..


Ka ob dieser Bias designtechnisch unumgänglich war, oder wieviele µCent 
man noch hätte drauf zahlen müssen. Aber für den Verbraucher wurde das 
sicherlich nicht so implementiert.. Ohne diesen Bias könnte man so 
einfach Timer basteln, die auch 0% und 100% können, aber ohne Sprünge!

von Hans W. (Gast)


Lesenswert?

>Brauchst denn denn die Extremwerte bei dem Timer?
Lieber haben und nicht brauchen, als brauchen und nicht haben. ..Oder so 
ähnlich ;)

Witzlig ist nämlich: Wenn meine min Breite 1/256, dann nehm ich als max. 
Breite eben 255/256... Aber Halt! Das geht bei Timer1 ja gar nicht! So 
oder so, dank des Sprungs müsste ich, damit es symmetrisch bleibt, als 
min. Breite 2/256 und entsprechend als max. 254/256 nehmen. Und 
natürlich immer alles -1 rechnen, um den %&"§%$ Bias zu kompensieren!

In einer alternative Realität, in der Leute nicht auf ein paar µCent 
wert legen, könnte ich mich entscheiden, ob ich lieber den PWM-Bereich 
bei ansonsten voller Auflösung einschränke, oder lieber die Auflösung 
bei vollem PWM-Bereich...

von Falk B. (falk)


Lesenswert?

@Hans W. (Gast)

>>Ich hab da mal was getestet, siehe Anhang.
>Wie hast du das denn getestet?

Mit der Software im Anhang.

>In meinen Tests kam heraus, dass er zu
>Beginn springt!

Dann hast du wahrscheinlich die invertierte PWM eingeschaltet.

>Bin mir eig ziemlich sicher, dass das stimmt..

Das sind viele hier, bis sie eines Besseren belehrt werden.

>Ka ob dieser Bias designtechnisch unumgänglich war,

Nö, das ist eine krampfhafte Lösung für ein Problem, das man anders 
besser lösen kann.

>sicherlich nicht so implementiert.. Ohne diesen Bias könnte man so
>einfach Timer basteln, die auch 0% und 100% können, aber ohne Sprünge!

Kann man, wenn man einen anderen Zähler nimmt ;-)

von S. Landolt (Gast)


Lesenswert?

> In meinen Tests kam heraus, dass er zu Beginn springt!

Bei meinem Test erfolgt der Sprung oben. Was ja auch sinnvoll ist, 
dort stört es am wenigsten.

von Hans W. (Gast)


Lesenswert?

>In der Regel braucht man die nicht. Keiner sieht, ob eine LED 100% an
>ist oder nur 99,6%.

Ich glaube, die AVR-Leute haben sich eher gedacht:"Man sieht nicht ob 
sie 1/256, oder 2/256 an ist, aber man sieht, dass sie nicht aus ist!"

von Hans W. (Gast)


Lesenswert?

>Dann hast du wahrscheinlich die invertierte PWM eingeschaltet.
Das macht (in meinem Test) keinen Unterschied! Wenn dann hätte ich den 
OCR1A rückwärts abgehen müssen - habe ich aber nicht.

>Das sind viele hier, bis sie eines Besseren belehrt werden.
Hmhm, manche empfehlen sogar RTFM, ohne es selbst getan zu haben ;)

>Kann man, wenn man einen anderen Zähler nimmt ;-)
...in einem anderen µC...


>Bei meinem Test erfolgt der Sprung oben. Was ja auch sinnvoll ist,
>dort stört es am wenigsten.
Und wie hast du das getestet?

von Hans W. (Gast)


Lesenswert?

Ernsthaft, ich kann das nicht bestätigen. Wie habt ihr denn jew. die 
Pulsbreite gemessen?

von S. Landolt (Gast)


Lesenswert?

> Und wie hast du das getestet?

Mit einem kleinen Assemblerprogramm: per Tastendruck zählt OCR1B hoch 
bis Top, am Oszilloskop sieht man dann den doppelten Längensprung des 
low-Levels beim Übergang von Top-1 auf Top.

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>Ich glaube, die AVR-Leute haben sich eher gedacht:"Man sieht nicht ob
>sie 1/256, oder 2/256 an ist, aber man sieht, dass sie nicht aus ist!"

BINGO!

von Falk B. (falk)


Lesenswert?

@ Hans W. (Gast)

>Ernsthaft, ich kann das nicht bestätigen. Wie habt ihr denn jew. die
>Pulsbreite gemessen?

Mit dem Oszi.

von Hans W. (Gast)


Lesenswert?

Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
Ich bin doch nicht verrückt.. Liegt es daran, dass ihr beide OCR1B, und 
ich OCR1A genutzt habe?!? - Mal Testen..

von Falk B. (falk)


Lesenswert?

@Hans W. (Gast)

>Ich bin doch nicht verrückt..

Wenn du schon SO fragst ;-)

>Liegt es daran, dass ihr beide OCR1B, und
>ich OCR1A genutzt habe?!? - Mal Testen..

Nein. Es sind die COMxy Bits.

GTCCR = (1<<PWM1B) | (1<< COM1B1);

von Hans W. (Gast)


Lesenswert?

>Nein. Es sind die COMxy Bits.

Die sind bei mir identisch. Damit stellt man doch eh nur ein, ob 
invertiert, oder nicht. Das sollte eig. nicht die Sprungstelle 
verändern.

Also ich hab es jetzt noch einmal ausprobiert:
Ich habe sogar beide Timer mit einander verglichen. Sie verhalten sich 
identisch, bis auf den Sprung.
So wie ihr es beschreibt, sollten sie sich aber nicht identisch 
verhalten, da, eurer Messung nach, Timer1 keinen Bias hat. Ist aber, wie 
gesagt kein Unterschied zu Timer0 festzustellen, der ja biased ist. Ergo 
sollte auch Timer1 nen Offset haben, was eig nur geht, wenn der Sprung 
am Anfang sitzt..

von Falk B. (falk)


Lesenswert?

@Hans W. (Gast)

>Die sind bei mir identisch. Damit stellt man doch eh nur ein, ob
>invertiert, oder nicht. Das sollte eig. nicht die Sprungstelle
>verändern.

Eigentlich nicht.

>Ich habe sogar beide Timer mit einander verglichen. Sie verhalten sich
>identisch, bis auf den Sprung.

Stimmt nicht, wenn du in meine Tabelle schaust.

>So wie ihr es beschreibt, sollten sie sich aber nicht identisch
>verhalten, da, eurer Messung nach, Timer1 keinen Bias hat. Ist aber, wie
>gesagt kein Unterschied zu Timer0 festzustellen, der ja biased ist. Ergo
>sollte auch Timer1 nen Offset haben, was eig nur geht, wenn der Sprung
>am Anfang sitzt..

Und du hast wirklich einen ATtiny25/45/85?

von Hans W. (Gast)


Lesenswert?

>Eigentlich nicht.
??

>Stimmt nicht, wenn du in meine Tabelle schaust.
Das ist ja gerade das Problem!

>Und du hast wirklich einen ATtiny25/45/85?
Ich habe zwar schon mal (spät nachts) ins Datenblatt vom tiny13 
geschaut, und mich gewundert, wo die ganzen Fähigkeiten hin sind, aber 
ja, diesmal bin ich mir absolut sicher. Es gibt zwar verschiedene 
Revisionen, aber ob das den Unterschied macht?!

In meinem Test habe ich die Auflösung auf 4 runter geschraubt.
Timer0 macht dann: 25%, 50%, 75%, 100%
Timer1 macht: 0%, 50%, 75%, 100%

..Zur Not kann ich das auch in ne Tabelle schreiben, wenn es dann 
überzeugender wirkt...

von Hans W. (Gast)


Lesenswert?

>??
Achso. - Ja, eigentlich nicht. Und uneigentlich wohl auch nicht.

von S. Landolt (Gast)


Lesenswert?

Auch wenn das jetzt wohl wie Eulen nach Athen tragen ist (seltsam, 
dieser Satz klingt seit ein paar Jahren auch anders als früher): die 
Rubriken 1 und 4 aus Falks Tabelle habe ich eben hier nachgebildet, 
lässt sich exakt so auf dem Oszilloskop bestätigen.

> In meinem Test ...
Was als Anzeige benutzt? Und wie sieht eigentlich das Programm aus?

von Hans W. (Gast)


Lesenswert?

>Und wie sieht eigentlich das Programm aus?
Mein Testprogramm sieht im Moment so aus:
1
 
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <avr/cpufunc.h> // "nop"
6
7
#include "tinyProj.h"
8
9
#define IDX0 6400
10
ISR(TIMER1_OVF_vect){
11
  static uint16_t idx = IDX0;
12
  static uint8_t val = 0;
13
  if(!(--idx)){
14
    OCR1A = val;
15
    OCR0B = val;
16
    OCR1B = val;
17
    idx = IDX0;
18
    val = (val+1)%5;
19
  }
20
}
21
22
int main(void){
23
  DDRB |= (1<<DDB1)|(1<<DDB0)|(1<<DDB4);
24
  
25
  TIMSK |= 1<<TOIE1;
26
  TCCR1 |= (1<<PWM1A)|(1<<COM1A1)|(1<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10); //CS12=1 für niedrigere Freq (die T0 nicht kann)!
27
  GTCCR |= (1<<PWM1B)|(1<<COM1B1);
28
29
  TCCR0A |= (1<<COM0B1)|(1<<COM0B0)|(1<<WGM00)|(1<<WGM01);
30
  TCCR0B |= (1<<WGM02)|(1<<CS02)|(1<<CS00); //fmin für T0
31
32
  OCR1C = 0x03;
33
  OCR0A = 0x03;
34
  
35
  sei();
36
37
  OCR1A = 0;
38
  OCR1B = 0;
39
  OCR0B = 0;
40
41
  while(1){
42
    _NOP();
43
  }
44
}

Gemessen habe ich visuell mit ner LED und via Spektrumsanalyse (mein 
Ohr) und ja, man kann deutlich hören, ob es sich um 50% oder 25%(75%) 
handelt. 25%/75% kann man zwar nicht unterscheiden, aber man merkt, ob 
erst die 25% und dann die 50%, oder erst die 50% und dann die 75% 
kommen. Zusätzlich habe ich das jew. Spektrum noch mit einem 
Referenzsignal gleicher Frequenz und % verglichen - passt.
Und weil ihr es seid, werde ich mir das gleich noch mal aufm Oszi 
anschauen
Kann evtl mal jemand mein Programm testen?!

von Hans W. (Gast)


Lesenswert?

..ignoriert das eine #include, sollte ohne gehen..

von S. Landolt (Gast)


Lesenswert?

Also meine C-Kenntnisse sind nur rudimentär, aber sehe ich das richtig, 
das der Tastgrad ständig geändert wird, bei jedem Timer1-Durchlauf? Wie 
kann man da etwas kontrollieren? Und Timer0 läuft doch invertiert, oder?

von S. Landolt (Gast)


Lesenswert?

Okay, ich hatte diese idx-Steuerung falsch interpretiert, damit wird es 
direkt gemütlich. Und sieht (auf dem Oszilloskop) doch gut aus, in 
Einklang mit Falks Tabelle und Stefanus' Prosa (musste ich da eigentlich 
noch als Dritter wie die alte Fastnacht hinterherkommen? - Biiig 
mistake).

von Hans W. (Gast)


Lesenswert?

>in Einklang mit Falks Tabelle und Stefanus' Prosa
Du bekommst also auch "0%, 25%, 50%, 100%, 100%" heraus? Und ganz sicher 
nicht "0%, 50%, 75%, 100%, 100%"?
Welchen Pin hast du jetzt genutzt?

von Hans W. (Gast)


Lesenswert?

>Und Timer0 läuft doch invertiert, oder?
Ups. Jap da haben sich beim umschreiben ein paar Fehler eingeschlichen..
Jetzt sollte es passen:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/cpufunc.h> // "nop"
4
5
#define IDX0 6400
6
ISR(TIMER1_OVF_vect){
7
  static uint16_t idx = IDX0;
8
  static uint8_t val = 0;
9
  if(!(--idx)){
10
    OCR0B = val;
11
    OCR1B = val;
12
    idx = IDX0;
13
    val = (val+1)%5;
14
  }
15
}
16
17
int main(void){
18
  DDRB |= (1<<DDB1)|(1<<DDB4);
19
  
20
  TIMSK |= 1<<TOIE1;
21
  TCCR1 |= (1<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10); //CS12=1 für niedrigere Freq (die T0 nicht kann)!
22
  GTCCR |= (1<<PWM1B)|(1<<COM1B1);
23
24
  TCCR0A |= (1<<COM0B1)|(1<<WGM00)|(1<<WGM01);
25
  TCCR0B |= (1<<WGM02)|(1<<CS02)|(1<<CS00); //fmin für T0
26
27
  OCR1C = 0x03;
28
  OCR0A = 0x03;
29
  
30
  sei();
31
32
  OCR1B = 0;
33
  OCR0B = 0;
34
35
  while(1){
36
    _NOP();
37
  }
38
}

Wenn ihr jew. an Pin1 und Pin4 ne LED hängt, sehen die dann (abgesehen 
vom 1. Schritt) für euch identisch aus in der Helligkeit????


...offenbar ist es nicht schlimm, wenn man 2 Timer an einen Pin hängt... 
Zum Glück kein Kurzschluss..Tralalalala...

von S. Landolt (Gast)


Lesenswert?

Pardon, ich bin heute abend etwas langsam, aber:

Ich sehe Letzteres, aber was sollte ich sonst sehen, bei OCR1C=3 und 
OCR1B=4?

von S. Landolt (Gast)


Lesenswert?

Aha, ich glaube zu verstehen, was Sie meinen, und kann es jetzt auch mit 
meinem Assembler-Taster-Programm nachvollziehen. Es scheint am Vorteiler 
zu liegen, setzen Sie mal den 'Timer/Counter1 Prescale Select' auf 1 
(nur '1<<CS10') (IDX0 muss dann entsprechend vergrößert werden), dann 
sollten Sie die 25 % sehen.

von Falk B. (falk)


Lesenswert?

@Hans W. (Gast)

>Wenn ihr jew. an Pin1 und Pin4 ne LED hängt, sehen die dann (abgesehen
>vom 1. Schritt) für euch identisch aus in der Helligkeit????

Sag mal, geht's noch? Wenn man das MESSEN will, MUSS man ein Oszi 
nehmen. Deine LED taugt praktisch gar nichts, schon gar nicht um einen 
Unterschied von EINEM Takt zu messen! Siehe LED-Fading.

Als Low Cost Alternative geht bestenfalls ein Multimeter, das mißt 
nämlich den Mittelwert und kann damit auch einen Takt Unterschied 
auflösen.

: Bearbeitet durch User
von Hans W. (Gast)


Lesenswert?

>Sag mal, geht's noch?
Hmhm, sehr gut sogar.
Nimm doch einfach mein Programm und mach es, statt hier rum zu 
theoretisieren.. Denn dort ist der Unterschied von "einem Takt" schon 
deutlich erlebbar, egal auf welche Weise, ob in Helligkeit, Spektrum, 
oder als 2D-Graph...

Das mit dem Prescaler muss ich noch selbst ausprobieren. Das wäre ja 
echt...."naja".

von S. Landolt (Gast)


Lesenswert?

> Deine LED taugt praktisch gar nichts ...

Nun ja, schon, aber: bei Top=3 entspricht 1 Takt immerhin einem Viertel, 
eben diesen 25 %!

von Hans W. (Gast)


Lesenswert?

Also zu der Sache mit dem Prescaler kann ich nur sagen:
.
.
.
.
.
.
.
.
WER MACHT SOWAS?!?!



Timer0 funktioniert natürlich noch immer wie gehabt, Timer1 nicht - ohne 
PSC ist der Sprung hinten, mit vorne.

Also, ich würd sagen, der ist verbuggt. Die nötige Investition hätte 
wohl doch mehr also nur ein paar µCent gekostet, denn Hirn ist teurer 
als Silizium...
Solche "Sonderregeln", die nirgendwo erwähnt werden, sind schon ein 
bisschen gefährlich. Z.B. bei niedriger Auflösung und wenn T0 und T1 
zusammenspielen sollen..

Danke für den Tipp, S. Landolt!!

von S. Landolt (Gast)


Lesenswert?

Es ist und bleibt merkwürdig: mit nachfolgendem Programm sehe ich auf 
dem (Analog-) Oszilloskop bei Vorteiler 1 wie erwartet einen Tastgrad 
von 50 %, bei Vorteiler 2 jedoch nicht 60, sondern ca. 55 % (eigentlich 
sind es 56).
1
#include <avr/io.h>
2
#define Taster 3    // +C gegen GND
3
4
int main(void){
5
  PORTB = (1<<Taster);
6
  DDRB  = (1<<DDB4);
7
  GTCCR = (1<<PWM1B)|(1<<COM1B1);
8
  OCR1C = 7;
9
  OCR1B = 4;
10
  while(1){
11
    TCCR1 = (0<<CS11)|(1<<CS10);    // /1
12
    while(  PINB&(1<<Taster) ) {};
13
    while(!(PINB&(1<<Taster))) {};
14
15
    TCCR1 = (1<<CS11)|(0<<CS10);    // /2
16
    while(  PINB&(1<<Taster) ) {};
17
    while(!(PINB&(1<<Taster))) {};
18
  }
19
}

Andererseits erinnert mich die ganze Sache allmählich an Kaisers Bart.

von Kaisers Bart (Gast)


Lesenswert?

S. Landolt schrieb:

> Andererseits erinnert mich die ganze Sache allmählich an Kaisers Bart.

Mich nicht. Mich erinnert sie an die Diskrepanz zwischen Angaben im 
Datenblatt und der Realität.

von Hans W. (Gast)


Lesenswert?

>Mich erinnert sie an die Diskrepanz zwischen Angaben im
>Datenblatt und der Realität.

Wie groß ist die Diskrepanz zwischen etwas nicht-existentem und der 
Realität..


>Es ist und bleibt merkwürdig: mit nachfolgendem Programm sehe ich auf
>dem (Analog-) Oszilloskop bei Vorteiler 1 wie erwartet einen Tastgrad
>von 50 %, bei Vorteiler 2 jedoch nicht 60, sondern ca. 55 % (eigentlich
>sind es 56).

Müssten es nicht sogar ~62% sein? Was passiert denn, wenn du OCR1B 
abgehst - bleiben die Differenzen von Tastgrad zu Tastgrad wenigstens 
gleich (abgesehen vom Sprung)?

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.