Forum: Mikrocontroller und Digitale Elektronik Fragen zum Artikel Soft-PWM


von Owen S. (senmeis)


Lesenswert?

Servus,

der Link des Artikels ist hier: 
[http://www.mikrocontroller.net/articles/Soft-PWM].

Ich habe einige Fragen zum zweiten Versuch im Artikel.

1. Handelt es sich um den Normal-Mode oder den CTC-Modus? Nach der Zeile
1
TCCR1B = 1;
sollte das Normal-Mode sein, aber im Normal-Mode spielt das 'OCR1A' 
keine Rolle!

2.
1
OCR1A += (uint16_t)T_PWM;
Was macht diese Zeile in der ISR ? Nach jeder ISR wird das OCR1A um 312 
(T_PWM) erhöht, also 0, 312, 624 usw. Das bedeutet, die Zeitabstände 
zweier ISRs sind immer höher: 312, 624 usw. Habe ich falsch verstanden?
Irgendwann muss das OCR1A einen Überlauf bekommen, und dann?

3.
1
TCCR1B = 1;             // Timer läuft mit vollem Systemtakt
2
      TIMSK |= (1<<OCIE1A);   // Interrupt freischalten
Geht es um Kanal A oder Kanal B? Sollte TIMSK eigentlich TIMSK1 heissen?

Vielen Dank für jeden Hinweis.
Senmeis

von Karl H. (kbuchegg)


Lesenswert?

Owen Senmeis wrote:
> aber im Normal-Mode spielt das 'OCR1A'
> keine Rolle!

Doch das tut es.
Der Output Compare Interrupt wird ausgelöst, wenn der Timerstand mit dem 
OCR1A Register übereinstimmt.
Der Timer läuft halt weiter ohnr das sonst irgendwas passiert. Aber rein 
durch die Übereinstimmung der beiden Register wird der Interrupt 
ausgelöst. Alles andere ergibt sich dann daraus

> Irgendwann muss das OCR1A einen Überlauf bekommen, und dann?

dann gibts einen Überlauf, und es geht wieder von vorne los.
Macht aber nichts. Den das Zählregister hat ja genau den gleichen 
Überlauf.

von Owen S. (senmeis)


Lesenswert?

Zitat ueber den normalen Modus aus dem Handbuch:"The Output Compare 
units can be used to generate interrupts at some given time. Using the 
Output Compare to generate waveforms in Normal mode is not recommended, 
since this will occupy too much of the CPU time.". Aber an welchen 
Zeitpunkten?

Zu meiner zweiten Frage: Nach meinem Verstaendnis sollen die Zeitspannen 
zweier Aufrufe der ISR immer gleich sein, z.B.
alle 50us, nicht wahr?

Gruss
Senmeis

von Joachim (Gast)


Lesenswert?

Ich grabe mal das alte Thema aus, da ich genau die gleiche Frage zu dem 
Artikel habe. Eine Antwort habe ich im Forum noch nicht gefunden.
Also was genau die Zeile:

OCR1A += (uint16_t)T_PWM;

macht. Ich bin bis jetzt auch immer davon ausgegangen, dass der ISR 
immer gleich lang sein sollte. In vielen anderen Beispielen hier im 
Forum ist das auch so.

Wer kann da weiter helfen?

Gruß,
Joachim

von Falk B. (falk)


Lesenswert?

@oachim (Gast)

>Also was genau die Zeile:
>OCR1A += (uint16_t)T_PWM;

Ganz einfach, damit wird der Zeitpunkt für den nächsten Interrupt 
festgelegt. Zum aktuellen Wert von OCR1A wird der Wert T_PWM addiert.

>macht. Ich bin bis jetzt auch immer davon ausgegangen, dass der ISR
>immer gleich lang sein sollte.

Das hat mit der LÄNGE der ISR nichts zu tun, sondern mit dem zeitlichen 
Abstand des Aufrufs.

> In vielen anderen Beispielen hier im Forum ist das auch so.

Wahrscheinlich weil man sowas des öfteren braucht.

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Joachim schrieb:
> Ich grabe mal das alte Thema aus, da ich genau die gleiche Frage zu dem
> Artikel habe. Eine Antwort habe ich im Forum noch nicht gefunden.
> Also was genau die Zeile:
>
> OCR1A += (uint16_t)T_PWM;
>
> macht. Ich bin bis jetzt auch immer davon ausgegangen, dass der ISR
> immer gleich lang sein sollte.

Das hat damit nichts zu tun

Jetzt ist es 12:04
Wenn du in genau 20 Minuten das Licht aufdrehen sollst, dann ist das um
12:04 + 00:20  -> 12:24

Also stellst du deinen Wecker auf 12:24
Der klingelt auch um die Zeit (die ISR kommt)

13 Minuten später sollst das Licht wieder ausschalten. Das wird dann 
sein um

  12:24 + 00:13  -> 12:37

Also wird der Wecker (wenn er um 12:24 geklingelt hat) auf die neue 
Weckzeit 12:37 eingestellt. Wenn er klingelt, schaltest du das Licht 
wieder aus und rechnest dir anhand des nächsten Zeitintervalls aus, wenn 
das Wecker das nächste mal, für die nächste Aktion, klingeln soll.

Und so geht das immer weiter.

Das Uhrwerk im Wecker ist dein Timer.
Die Einstellung der Klingelzeit ist das OCR Register
Und das Klingeln ist der Aufruf der ISR

Jetzt klarer?

von Joachim (Gast)


Lesenswert?

Danke schon mal für die Antworten!

Da habe ich mich etwas ungeschickt ausgedrückt. Ich wollte auch sagen, 
dass sich die Zeit zwischen den ISRs unterscheidet, also nach jeden ISR 
wird die Pause länger, bis die 16 bit voll sind und es wieder von vorne 
losgeht.

Ich glaube ich habe es jetzt verstanden. Ich habe immer ein festes 
Zeitintervall (die T_PWM) bei dem ich schaue ob ich die LEDs (oder 
Lampen ;-) ) entweder an oder aus schalten muss.
Hat diese Vorgehensweise einen Vorteil gegenüber einer festen Frequenz 
der ISR?

Gruß,
Joachim

von Falk B. (falk)


Lesenswert?

@Joachim (Gast)

>Ich glaube ich habe es jetzt verstanden.

Ich glaube nein.

> Ich habe immer ein festes
>Zeitintervall (die T_PWM) bei dem ich schaue ob ich die LEDs (oder
>Lampen ;-) ) entweder an oder aus schalten muss.

In deinem Beispiel ja.

>Hat diese Vorgehensweise einen Vorteil gegenüber einer festen Frequenz
>der ISR?

Welche Vorgehensweise? Dein Beispiel hat eine feste ISR-Frequenz. Aber 
das dritte Beispiel im Artikel Soft-PWM hat KEINE feste Frequenz. 
Der Grund und Vorteil steht im Artikel.

MFG
Falk

von ... (Gast)


Lesenswert?

???
Solange T_PWM konstant ist, hast Du eine feste Interruptfrequenz.

von Joachim (Gast)


Lesenswert?

... schrieb:
> Solange T_PWM konstant ist, hast Du eine feste Interruptfrequenz.

Nein, weil bei jedem Interrupt OCR1A um T_PWM erhöht wird und somit der 
Interrupt später kommt. Oder nicht?
Im Artikel steht da jetzt aber "Im Interrupt, welcher regelmäßig 
aufgerufen wird,...." Seh ich allerdings nicht?

Ich vergleiche hier den "zweiten Lösungsansatz" und die "übliche" 
Vorgehensweise hier im Forum bei der ein fester Wert für den Compare 
Match oder ein Overflow verwendet, eine Variable hochgezählt wird und 
abhängig vom Wert der Variable die LEDs gesetzt werden.

von ... (Gast)


Lesenswert?

T_PWM gibt den "Abstand" zwischen 2 Interrups an. Und wenn der konstant 
ist, ist auch die Frequenz konstant. Ist doch nu wirklich nicht soooo 
schwer.
Ist im Endeffekt dasselbe, als wenn man den CTC-Mode mit demselben Wert 
benutzt.
Bei dem verlinkten Artikel geht es aber um eine Soft-PWM mit acht 
Kanälen. Und wenn man den dann auch noch komplett liest und den 
Abschnitt "Intelligenter Lösungsansatz" auch noch versteht, dann kann 
man eventuell nachvollziehen warum das in diesem Fall genau so gemacht 
wird.

von Karl H. (kbuchegg)


Lesenswert?

Joachim schrieb:
> ... schrieb:
>> Solange T_PWM konstant ist, hast Du eine feste Interruptfrequenz.
>
> Nein, weil bei jedem Interrupt OCR1A um T_PWM erhöht wird und somit der
> Interrupt später kommt. Oder nicht?

Nein.
Du hast es immer noch nicht.
Der Timer läuft weiter!

Der wird nicht auf 0 gesetzt. Genausowenig wie du deinen Wecker bei 
jedem Klingeln nicht auf Mitternacht zurückstellst.

> Im Artikel steht da jetzt aber "Im Interrupt, welcher regelmäßig
> aufgerufen wird,...." Seh ich allerdings nicht?

Weil du davon ausgehst, dass der Timer bei jedem Interrupt wieder bei 0 
anfängt, aber das tut er nicht. Der zählt einfach weiter.

von Joachim (Gast)


Lesenswert?

Jetzt hab ichs aber :-)

Anfangswerte: OCR1A=0 und TCNT1=0
--> 1. Interrupt
nach dem 1. Interrupt: OCR1A=312 und TCNT1=0
--> 2. Interrupt bei OCR1A=312 und TCNT1=312
nach dem 2. Interrupt: OCR1A=624 und TCNT1=312

usw.
==>Fester Abstand zwischen den Interrupts 312 Zyklen :-)

Ihr habt ja recht! Ich bin fälschlicher Weise tatsächlich von einem 
"Clear Timer on Compare" ausgegangen.

Da ist der Groschen aber in Pfenningen gefallen (Irgendwo hab ich noch 
welche ;-) )

Vielen Dank für eure Mühe!

Joachim

von ... (Gast)


Lesenswert?

Ein Blatt Papier und ein Stift und selber Controller spielen wirkt 
manchmal Wunder :)

von Nobody (Gast)


Lesenswert?

Joachim schrieb:
> Anfangswerte: OCR1A=0 und TCNT1=0
> --> 1. Interrupt
> nach dem 1. Interrupt: OCR1A=312 und TCNT1=0
> --> 2. Interrupt bei OCR1A=312 und TCNT1=312
> nach dem 2. Interrupt: OCR1A=624 und TCNT1=312

Eigentlich nicht. Es fehlt das setzen von OCR1A und die genaue Notation 
des Zeitpunkts. Der Interrupt tritt immer dann auf wenn OCR1A == TCNT1

Also vielmehr so:

Anfangswerte: OCR1A=312 und TCNT1=0
1. Interrupt tritt auf mit OCR1A=312 und TCNT1=312
OCR1A <- 624
2. Interrupt tritt auf mit OCR1A=624 und TCNT1=624
OCR1A <- 936
3. Interrupt tritt auf mit OCR1A=936 und TCNT1=936

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.