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.
@ 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.
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.
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.
>RTFM http://cdn-reichelt.de/documents/datenblatt/A300/ATTINY25-ATTINY45-ATTINY85_DATASHEET.pdf#G1.1849153 Table 12-2.
>Weil du nicht mal erwähnt hast, um welche Sorte Timer es geht, also >welcher µC sie bereitstellt. Attiny85 Timer1 PWM (-Mode)
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!
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...
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.
>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).
>(sofern man Timer0 nicht zu "0 -> 0/256" bringen kann)
* im Saw-PWM-Modus...
@ 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.
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.
>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,..}...
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.
@ 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.
>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?????)
>CTC-Modus
Hat der Timer0 ebenfalls, nur der fängt ja bei 0 -> 1/256 an! ARGH!!!
....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!
@ 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?
@ 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.
>(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..
>der kann phase correct PWM
Der kann aber keinen PLL-Takt.. Das wären 64MHz vs. 16/2 Mhz Takt..
@ 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.
>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 :/
> Aber nur im Phase vorect mode.
Phase verreckt Modus? :-)
@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?
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%.
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
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.
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.
@ 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!
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.
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.
> 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.
:
Bearbeitet durch User
>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!
>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...
@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 ;-)
> 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.
>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!"
>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?
Ernsthaft, ich kann das nicht bestätigen. Wie habt ihr denn jew. die Pulsbreite gemessen?
> 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.
@ 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!
@ Hans W. (Gast) >Ernsthaft, ich kann das nicht bestätigen. Wie habt ihr denn jew. die >Pulsbreite gemessen? Mit dem Oszi.
Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm. Ich bin doch nicht verrückt.. Liegt es daran, dass ihr beide OCR1B, und ich OCR1A genutzt habe?!? - Mal Testen..
@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);
>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..
@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?
>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...
>??
Achso. - Ja, eigentlich nicht. Und uneigentlich wohl auch nicht.
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?
>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?!
..ignoriert das eine #include, sollte ohne gehen..
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?
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).
>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?
>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...
Pardon, ich bin heute abend etwas langsam, aber: Ich sehe Letzteres, aber was sollte ich sonst sehen, bei OCR1C=3 und OCR1B=4?
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.
@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
>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".
> Deine LED taugt praktisch gar nichts ...
Nun ja, schon, aber: bei Top=3 entspricht 1 Takt immerhin einem Viertel,
eben diesen 25 %!
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!!
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.
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.
>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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.