Forum: Mikrocontroller und Digitale Elektronik ATMega8 PWM-Problem mit Timer2


von Roland N. (eroli)


Lesenswert?

Hallo zusammen,

ich arbeite an einem kleinem Programm, bei dem ich bisher Timer0 und 
Timer1 schon in Gebrauch habe. Zeitgleich dazu möchte ich mit Timer2 die 
LEDs dimmen und hier stoße ich auf ein Problem...

In Timer0 möchte ich Timer2 immer unterschiedlich vorladen, damit es so 
aussieht als würden die LEDs pulsieren. Timer0 wirft ungefähr alle 100ms 
einen Overflow...

Timer0 sieht also so aus:
1
fading:
2
  ; Timer 2 starten
3
  cpi runs, 0
4
  brne timer2on   ; Damit der Timer nur einmal gestartet wird
5
  ldi temp, 250
6
  out TCNT2, temp
7
  ldi temp, 0b010; Vorteiler 1
8
  out TCCR2, temp
9
  timer2on:
10
  out TCNT2, runs
11
12
end:
13
  inc runs
14
  rjmp exit

In Timer2, der das eigentliche Fading machen soll sieht es so aus:
1
Timer2_Overflow:  ; LED-Fading
2
3
push temp        ; Sichern von "TEMP" im Stack
4
in   temp, SREG    ; Einlesen des SREG 
5
push temp        ; Schreiben von  SREG  im Stack (KOPIE)
6
7
  sbic PORTB, 0    ;Nächsten Befehl überspringen, falls Bit0 abm PortB ist AUS (= LED ist EIN)  
8
    rjmp led_ein2  ;Ansonsten LED einschalten (s. unten).
9
  sbis PORTB,0    ;Überspringen, falls Bit0 abm PortB ist EIN (= LED ist AUS)  
10
    rjmp led_aus2  ;Ansonsten LED ausschalten (s. unten).
11
12
  led_ein2:    ;Zum Einschalten:
13
    ldi temp, 0x00
14
    out PORTB, temp
15
    out PORTD, temp
16
    rjmp end2  ;und beenden.
17
  led_aus2:    ;Zum Ausschalten:
18
    ldi temp, 0xFF
19
    out PORTB, temp
20
    out PORTD, temp
21
    rjmp end2
22
23
end2:
24
pop  temp      ; LESEN von SREG vom STACK (KOPIE)
25
out  SREG, temp    ; Wiederherstellen von SREG
26
pop  temp      ; Wiederherstellen von "TEMP" 
27
reti        ; ISR beenden.

Der Vorteiler für TImer2 muss bei 32 bleiben, sonst flackert es 
offensichtlich. Allerdings habe ich schon verschiedene Werte zum 
vorladen probiert, doch ein richtiges pulsieren ist nicht zu sehen.

Was kann ich da noch ändern, damit ich meinem Ziel näher komme??

Vielen Dank :-)

von spess53 (Gast)


Lesenswert?

HI

>Was kann ich da noch ändern, damit ich meinem Ziel näher komme??

Beschäftige dich mit PWM und benutze das OC-REgister. Mit dem unseligen 
Vorladen kommst du auf keinen grünen Zweig.

Und das

>  sbic PORTB, 0 i
>    rjmp led_ein2
>  sbis PORTB,0
>    rjmp led_aus2
>  led_ein2:
>    ldi temp, 0x00
>    out PORTB, temp
>    out PORTD, temp
>    rjmp end2
>  led_aus2:
>    ldi temp, 0xFF
>    out PORTB, temp
>    out PORTD, temp
>    rjmp end2

kannst du einfach dadurch
1
  in temp,PortB
2
  com temp
3
  out PortB,temp
4
  out PortD,temp

ersetzen

MfG Spess

von Roland N. (eroli)


Lesenswert?

Hi Spess,

danke für die Antwort.

Wenn ich das OCR2-Register benutze, dann muss ich doch vom 
Overflow-Interrupt zum CompareMatch-Interrupt wechseln, richtig?

Im Timer-Tutorial steht relativ weniv zu Timer2. Wie genau gehe ich 
damit vor? Was genau ist am OCR2 besser als am vorladen des TCNT2?

> kannst du einfach dadurch
>
>  in temp,PortB
>  com temp
>  out PortB,temp
>  out PortD,temp

klar, das hatte ich nur von woanders entnommen. Werde das vereinfachen.

von Karl H. (kbuchegg)


Lesenswert?

Roland Moch schrieb:
> Hi Spess,
>
> danke für die Antwort.
>
> Wenn ich das OCR2-Register benutze, dann muss ich doch vom
> Overflow-Interrupt zum CompareMatch-Interrupt wechseln, richtig?

Nein, warum?
Der Timer 2 hat genauso einen Overflow Interrupt wie der Timer 0. Wie 
alle Timer.

> Im Timer-Tutorial steht relativ weniv zu Timer2. Wie genau gehe ich
> damit vor?

Genau gleich. Die Timer sind alle ähnlich. Hast du einen verstanden, 
hast du alle (zumindest in den Grundzügen) verstanden. Und die Details, 
was der Timer alles kann stehen im Datenblatt des Prozessors.

> Was genau ist am OCR2 besser als am vorladen des TCNT2?

Warum willst du dir Arbeit machen, wenn die Hardware deine LED komplett 
ohne dein Zutun ganz von alleine mittels PWM dimmen kann?

Timer richtig konfigurieren und der dimmt deine LED ganz von alleine auf 
den Wert den du haben willst. Du musst nur noch die jeweilig gewünschte 
Helligkeit ins OCR Register eintragen (und zeitlich variieren). Fertig

von Roland N. (eroli)


Lesenswert?

> Timer richtig konfigurieren und der dimmt deine LED ganz von alleine auf
> den Wert den du haben willst. Du musst nur noch die jeweilig gewünschte
> Helligkeit ins OCR Register eintragen (und zeitlich variieren). Fertig

Sorry, wenn ich so blöd frage, aber irgendwie bleiben nach dem Tutorial 
auf dieser Seite immer noch Fragen dazu offen... Hast du vielleicht 
einen guten Link?

Habe irgendwo gelesen, dass die PWM eine LED an einem bestimmten PIN 
dimmen kann, aber in meinem Fall muss ich PORTB und PORTD dimmen. Dann 
geht das nicht mit diesem "Automatismus", oder?

EDIT: Also ich werd irgendwie den OCR2 für die Helligkeit einstellen 
müssen und laut Datenblatt das WGM21:0 = 1 (was mir nich sonderlich viel 
sagt) und dann lüppt die Sache von alleine? Auch an meinen beiden Ports?

von spess53 (Gast)


Lesenswert?

Hi

>Sorry, wenn ich so blöd frage, aber irgendwie bleiben nach dem Tutorial
>auf dieser Seite immer noch Fragen dazu offen

Das Tutorial ist für den Einsieg gedacht. Aber es kann dich nicht bis an 
dein Lebensende begleiten. Nimm dir das Datenblatt und werde flügge.

MfG Spess

von Roland N. (eroli)


Lesenswert?

Hallo nochmal,

nunja, ich bin immer noch ziemlich blutiger Anfänger...

Habe mir das Datenblatt mal angeschaut und alles relevante zum Timer2 
durchgelesen. Also ich würde so vorgehen (Bitte verbessert mich):


1. Im TIMSK die entsprechenden Interrupts "erlauben"
2. LSB von WGM21 auf 1 setzen, um die phasenkorrekte PWM zu benutzen
3. Im OC2 die Helligkeit einstellen, oder eben wie hoch der Timer zählen 
soll
4. Über COM21 ist (nicht)invertierte PWM einstellbar
5. Nun wird eine entsprechende Waveform am OC2-Pin (muss auf output 
geschaltet sein) generiert

Nun meine Fragen:
1. Ist obiges Vorgehen korrekt?
2. Wird die Waveform am OC2-Pin ohne irgendwelchen Code im 
InterruptHandler erzeugt (Vermutung: Ja)?
3. Wie kann ich damit meine Ports pulsweitenmodellieren, was ja mein 
eigentliches Ziel ist. Da bringt mir doch auch eine Waveform an OC2 
nichts?

Entschuldigt bitte, wenn ich euch nerve, aber da Datenblatt überfordert 
mich doch schon ziemlich und alles, was mir wichtig erschien, habe ich 
oben zusammengefasst.
Ich wäre wirklich sehr dankbar, wenn sich jemand erbarmen würde, um mir 
eine Hilfestellung zu geben, damit ich schneller "flügge" werden kann...

Einen schönen Abend an Alle :-)

von Roland N. (eroli)


Lesenswert?

Hallo zusammen,

ich habe mir das Datenblatt "reingezogen" und ich habe es hinbekommen 
eine PWM an PORTB3 zu etablieren. Das habe ich daran erkannt, dass ich 
bei Prescaler 1024 ein deutliches blinken/flackern sehe, dass vergeht, 
wenn ich den Prescaler runtersetze.

Der wesentliche Code-Ausschnitt sieht so aus:
1
  ; Prog4 ausfuehren: Test-Fading
2
  ldi temp, 0x01  ; Zur Kontrolle die ersten beiden LEDs einschalten
3
  out PORTB, temp
4
  out PORTD, temp
5
6
  ldi temp, 1<<OCIE2 | 1<<TOIE1 | 1 <<TOIE0  ; Timer0-Overflow und Timer1-Overflow und Timer2-Compare "erlauben"
7
  out TIMSK, temp
8
  ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20  ; Phasenkorrekte PWM und Prescaler setzen
9
  out TCCR2, temp
10
  ldi temp, 0x00  ; Irgendein Startwert fuer OCR2 (Unsere Helligkeit)
11
  out OCR2, temp

Allerdings kann ich keine Helligkeitsänderung an der LED an PORTB3 
feststellen, egal ob ich OCR2 mit 0xFF oder 0x00 oder irgendetwas 
dazwischen lade. Dies dürfte wohl an der logarithmischen 
Helligkeitswahrnehmung unseres Auges zu tun haben - oder an einem 
Programmfehler...
Oder gibt es da noch einen anderen Trick um eine deutlichere 
Helligkeitsänderung herbeizuführen?

von spess53 (Gast)


Lesenswert?

Hi

>ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20
                        ^^^^^^^^^^

Du hast CTC und nicht PWM eingestellt.

MfG Spess

von Ralf (Gast)


Lesenswert?

Roland Moch schrieb:
> Der wesentliche Code-Ausschnitt sieht so aus:

... das ist nun nicht unbedingt das Wesentliche.

Also, ich würde so rangehen:
PWM-Signal mit Timer1/ 16Bit/ Fast-PWM. Damit hat man 256 sichtbare(!) 
Helligkeitsunterschiede (das liegt einmal tatsächlich an der Wahrnehmung 
des Auges und außerdem an der Leistungsausbeute bei PWM. Bei einer 
Motoransteuerung wäre der Effekt der gleiche.). Die einzelnen Stufen 
gehen dann von s=1 .. 256. Mit s^2-1 füttert man später das OC-Register. 
Den Maximalwert (volle Helligkeit) schreibt man ins IC-Register (Bei 
Benutzung aller 256 Stufen: 0xFFFF). Jetzt braucht man nur noch im 
Interrupt von irgend einem anderen Timer entsprechend der gewünschten 
Helligkeit eine Variable hoch- und runterzählen lassen und die Werte 
eintragen.

von Paul Baumann (Gast)


Lesenswert?

Spess schrob:
>Nimm dir das Datenblatt und werde flügge.

Ein einzelnes A4-Blatt wird aber sein Gewicht nicht tragen können.
;-)
MfG Paul

von Roland N. (eroli)


Lesenswert?

Hi,

>>ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20
>                        ^^^^^^^^^^
>
>Du hast CTC und nicht PWM eingestellt.

Wenn ich das richtig verstanden habe, dann muss ich WGM21 auf 0 und 
WGM20 auf 1 setzen. Werde das später zu Hause mal austesten...

Angenommen ich setze WGM21 und WGM20 auf 1, dann hätte ich doch eine 
FastPWM, aber laut dem Mikrocontroller-Tutorial kann Timer2 doch nur 
einen phasenkorrekte PWM. Was ist denn nun richtig und was falsch?

(Zu den anderen Antworten kann ich mich ebenfalls heute Abend mal 
melden...)

von Roland N. (eroli)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

nun sieht es so aus:
1
  ldi temp, 0x01  ; Zur Kontrolle die ersten beiden LEDs einschalten
2
  out PORTB, temp
3
  out PORTD, temp
4
5
  ldi temp, 1<<OCIE2 | 1<<TOIE1 | 1 <<TOIE0  ; Timer0-Overflow und Timer1-Overflow und Timer2-Compare "erlauben"
6
  out TIMSK, temp
7
  ldi temp, 1 << COM20 | 0 << WGM21 | 1 << WGM20 | 0 << CS22 | 1 << CS21 | 0 << CS20  ; Phasenkorrekte PWM und Prescaler setzen
8
  out TCCR2, temp
9
  ldi temp, 0x99  ; Irgendein Startwert fuer OCR2 (Unsere Helligkeit)
10
  out OCR2, temp

Aber es ist immernoch kein Helligkeitsunterschied feststellbar, egal ob 
ich OCR2 mit 0x00, 0xFF oder 0x99 lade...

Wo ist denn da der Wurm drin???

Ich hab auch mal das komplette Programm hochgeladen, beachtet dabei 
bitte das prog so vorgeladen wird, dass immer Prog4 ausgeführt wird...

von Stefan E. (sternst)


Lesenswert?

COM21=0/COM20=1 ist keine gültige Einstellung für die PWM-Modes.

von Roland N. (eroli)


Lesenswert?

Stimmt, das ist wirklich nicht erlaubt? Was macht der Microcontroller in 
so einem Fall? Stürzt der ab? Macht der irgendetwas unkontrollierbares?

Ich hatte COM20 doch extra auf 1 gesetzt, damit PortB3 bei CompareMatch 
getoggled wird. Wie soll ich das denn sonst machen?

von Stefan E. (sternst)


Lesenswert?

Roland Moch schrieb:
> Ich hatte COM20 doch extra auf 1 gesetzt, damit PortB3 bei CompareMatch
> getoggled wird.

Mit "Toggeln bei Compare-Match" hättest du aber gar keine PWM.
(gar nicht mal so unwahrscheinlich, dass du genau dieses Toggeln bei 
Compare-Match jetzt hast)

> Wie soll ich das denn sonst machen?

Ins Datenblatt schauen, und den richtigen COM-Modus raus suchen.

von Roland N. (eroli)


Lesenswert?

Ok, machen wir mal ein kleines Ausschlussverfahren:

COM21/COM20
0 / 0 - Keine PWM an PortB3 - will ich nicht
0 / 1 - Reserved - geht eh nicht
1 / 0 - Clear OC2 on Compare Match when up-counting. Set OC2 on Compare
Match when downcounting
1 / 1 - Set OC2 on Compare Match when up-counting. Clear OC2 on Compare
Match when downcounting

Zwischen den letzten beiden kann ich mich nicht wirklich entscheiden. 
Dürften die nicht dasselbe bezwecken (für meine ganz eifnache 
LED-Dimmung) nur genau umgekehrt?

Bin jetzt übers Wochenende zu Hause und kann nichts testen, aber stimmt 
meine Annahme? Würde beides gehen ohne bei meinem einfachen Projekt 
einen Unterschied zu bewirken?

Schönen Morgen noch an Alle :-)

von spess53 (Gast)


Lesenswert?

Hi

1 / 0 normale PWM -> ON-Zeit steigt mit größer werdendem OC-Wert

1 / 1 invertierte PWM -> ON-Zeit sinkt mit größer werdendem OC-Wert

MfG Spess

von Roland N. (eroli)


Lesenswert?

Hallo Spess,

danke für die Erklärung.

Ich komme leider erst Dienstag wieder an die Hardware dran, dann werde 
ich das testen :-)

Bis dahin wünsch ich euch allen frohe Ostern und Ruhe vor mir ;-)

von Roland N. (eroli)


Lesenswert?

Hi,

kurze Rückmeldung meinerseits:
Es klappt nun alles hervorragend. Habe mich doch noch für eine 
Hardware-PWM (Fast-PWM) entschieden und betreibe damit den kompletten 
PORTB und PORTD. Im Compare-Interrupt werden die Lichter ausgeschaltet 
und im Overflow-Interrupt an.

Der 8-Bit-Timer löst dafür schon fein genug auf - gefällt mir sehr gut 
:-)

Danke nochmal für eure Hilfe :-)

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.