AVR ATmega168 Timer2 PWM Verständniss

OP #3341035
Hallo zusammen,
Ich versuche schon länger auf einem ATmega168 beim Timer2 Pin OC2A eine 
Fast PWM zu entlocken, allerdings erfolglos. Beim Timer1 hatte ich keine 
Probleme, doch bei  Timer2 habe ich keinen Erfolg. Kann mir einer helfen 
wo ich auf dem Schlauch stehe?

1
#include <avr/io.h>
2

3
int main(void)
4
{
5
  
6
  /* PB3 as output */
7
  DDRB = (1<<PB3);
8
  
9
  /*Asynchronous status register*/
10
  ASSR = (0<<EXCLK) |    //Enable External clock input
11
      (0<<AS2);    //Enable Asynchronous Timer 2
12
  
13
  /* Timer Counter Control Register A */
14
  TCCR2B = (0<<FOC2A) |  //Force Output compare A
15
       (0<<FOC2B) |  //Force Output compare B
16
       (1<<CS21) |  //Clock select, 32
17
       (1<<CS20);    //Clock select
18
       
19
  /* Timer Counter Control Register B */
20
  TCCR2A = (1<<COM2A1) |  //Connect OC2A
21
       (0<<COM2A0) |  //Connect OC2A
22
       (0<<COM2B1) |  //Connect OC2B
23
       (0<<COM2B0) |  //Connect OC2B
24
       (1<<WGM21) |  //Waveform generation mode, Fast PWM
25
       (1<<WGM20);  //Waveform generation mode
26
  
27
  /* Output Compare Register A*/
28
  OCR2A = 127; //50% cycle
29
  
30
  /* Timer Counter Interupt Mask Register */
31
  TIMSK2 = (0<<OCIE2B) |  //Timer 2 output compare match B interrupt enable
32
      (0<<OCIE2A) |  //Timer 2 output compare match A interrupt enable
33
      (0<<TOIE2);    //Timer 2 overflow interrupt enable
34

35

36

37
    while(1)
38
    {
39
    
40
    }
41
}


Vielen Dank für eure Hilfe :D
Gruss Christian
Gast #3341105
>>   ASSR = (0<<EXCLK) |    //Enable External clock input
>>       (0<<AS2);    //Enable Asynchronous Timer 2
>Lass das mal ersatzlos weg. Du hast ihm gerade den Clock weggenommen.

ASSR mit 0 zu beschreiben dürfte das nicht machen.

Setz mal WGM22 in TCCR2B auf 1.
OP #3341122
Hm das hab ich gemacht, hat leider nix gebracht. Allerdings sollte dies 
meiner Meinung nach sowieso keinen Einfluss gehabt haben, da ich die 
interne Clock benütze. Aber danke für die Idee, hast du weitere?

Ahja was ev noch weiterhilft: Ich habe das Programm im Simulator (AVR 
Studio 5) ausprobiert. Dort Toggelt PORTB.3
Ebenfalls hab ich die Hardware über folgenden Befehl überprüft:
1
DDRB = (1<<PB3);
2
PORTB = (1<<PB3);

Der Ausgang geht wie Erwartet auf High. Ein Defekt kann also 
ausgeschlossen werden.
OP #3341139
Ok ich hab jetzt auch den Tipp von Holger ausprobiert und den folgenden 
Teil geändert:
1
TCCR2B = (1<<COM2A1) |  //Connect OC2A
2
       (0<<COM2A0) |  //Connect OC2A
3
       (0<<COM2B1) |  //Connect OC2B
4
       (0<<COM2B0) |  //Connect OC2B
5
       (1<<WGM22)  |  
6
       (1<<WGM21) |  //Waveform generation mode, Fast PWM
7
       (1<<WGM20);  //Waveform generation mode

Ich nehme an, dass es sich bei WGM22 um TCCR2B.3 handelt (im Datasheet 
liegt wohl ein Fehler vor, da es das Bit WGM22 TCCR2B nur als Read 
beschreibt).

Jetzt ist der Pin immer HIGH.
Gast #3341163
Wieso hast du die beiden jetzt auch in TCCR2B gesetzt?

       (1<<WGM21) |  //Waveform generation mode, Fast PWM
       (1<<WGM20);  //Waveform generation mode

Die gibt es dort gar nicht.
OP #3341177
Hm da ist mir wohl beim Posten was durcheinander gekommen sry, danke für 
den Hinweis. Um Missverständnisse ausschliessen zu können, hier der 
aktuelle Code:
1
#include <avr/io.h>
2

3
int main(void)
4
{
5
  
6
  /* PB3 as output */
7
  DDRB = (1<<PB3);
8
  
9
//   /*Asynchronous status register*/
10
//   ASSR = (0<<EXCLK) |    //Enable External clock input
11
//       (0<<AS2);    //Enable Asynchronous Timer 2
12
//   
13
  /* Timer Counter Control Register A */
14
  TCCR2B = (0<<FOC2A) |  //Force Output compare A
15
       (0<<FOC2B) |  //Force Output compare B
16
       (1<<WGM22)  |  
17
       (1<<CS21) |  //Clock select, 32
18
       (1<<CS20);    //Clock select
19
       
20
  /* Timer Counter Control Register B */
21
  TCCR2A = (1<<COM2A1) |  //Connect OC2A
22
       (0<<COM2A0) |  //Connect OC2A
23
       (0<<COM2B1) |  //Connect OC2B
24
       (0<<COM2B0) |  //Connect OC2B
25
       (1<<WGM21) |  //Waveform generation mode, Fast PWM
26
       (1<<WGM20);  //Waveform generation mode
27
  
28
  /* Output Compare Register A*/
29
  OCR2A = 127; //50% cycle
30
  
31
  /* Timer Counter Interupt Mask Register */
32
  TIMSK2 = (0<<OCIE2B) |  //Timer 2 output compare match B interrupt enable
33
      (0<<OCIE2A) |  //Timer 2 output compare match A interrupt enable
34
      (0<<TOIE2);    //Timer 2 overflow interrupt enable
35

36

37

38
    while(1)
39
    {
40
    
41
    }
42
}
Gast #3341200
>Setz mal WGM22 in TCCR2B auf 1.

Nee, nimm das wieder weg. TOP muss 0xFF sein.
WGM21 und WGM20 auf 1 ist ok.

Dummerweise sehe ich dann aber keinen Fehler mehr in deinem Code.
Müsste gehen.
#3341276
holger schrieb:
>>>   ASSR = (0<<EXCLK) |    //Enable External clock input
>>>       (0<<AS2);    //Enable Asynchronous Timer 2
>>Lass das mal ersatzlos weg. Du hast ihm gerade den Clock weggenommen.
>
> ASSR mit 0 zu beschreiben dürfte das nicht machen.
>
> Setz mal WGM22 in TCCR2B auf 1.

Ja habe ich auch gerade gesehen. Wieder dieses dämliche 0 schieb 
sonstwohin. Erleichtert die Fehlersuche ungemein.

1
#include <avr/io.h>
2

3
int main(void)
4
{  
5
  DDRB = (1<<PB3);
6
  TCCR2B = (1<<CS21)|(1<<CS20);    //Clock select       
7
  TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20);  //Waveform generation mode
8
  
9
  OCR2A = 127; //50% cycle
10

11
    while(1)
12
    {
13
    
14
    }
15
}

> (1<<WGM22)  |

WGM22 war gesetzt. Damit ist TOP OCR2A und Duty ist OCR2B. Nur mit WGM20 
und 21 ist das Mode3 mit TOP = 0xFF und Duty OCR2A. Mit OCR2B und COM2B1 
kannst du den 2.PWM-Kanal schalten.

mfg.
OP #3341425
Boa vielen Dank, es funktioniert :D
Ich Code eigentlich auch nicht mit (0<<x) jedoch, habe ich es zu 
debuggingzecken so geschrieben. Allerdings sehe ich den Unterschied zu 
meinem allerersten Post nicht (ausser dass der Code natürlich bedeutend 
schlanker ist ;D)

Nochmals vielen Dank, hier sind super hilfsbereite Leute.
Gast #3341464
>Boa vielen Dank, es funktioniert :D
>Ich Code eigentlich auch nicht mit (0<<x) jedoch, habe ich es zu
>debuggingzecken so geschrieben. Allerdings sehe ich den Unterschied zu
>meinem allerersten Post nicht (ausser dass der Code natürlich bedeutend
>schlanker ist ;D)

Zeig deinen neuen Code doch mal.
OP #3341474
Ich verwende jetzt 1:1 den Code von Thomas:
1
#include <avr/io.h>
2

3
int main(void)
4
{  
5
  DDRB = (1<<PB3);
6
  TCCR2B = (1<<CS21)|(1<<CS20);    //Clock select       
7
  TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20);  //Waveform generation mode
8
  
9
  OCR2A = 127; //50% cycle
10

11
    while(1)
12
    {
13
    
14
    }
15
}
Gast #3341484
>Ich verwende jetzt 1:1 den Code von Thomas:

Ist identisch zu deinem zuerst geposteten Code.
Da sind nur die funktionslosen Nullschieber rausgekürzt.

Dein Code hätte auch so funktionieren müssen.
#3341504
holger schrieb:
>>Ich verwende jetzt 1:1 den Code von Thomas:
>
> Ist identisch zu deinem zuerst geposteten Code.
> Da sind nur die funktionslosen Nullschieber rausgekürzt.
>
> Dein Code hätte auch so funktionieren müssen.

Ich sehe da auch keinen Unterschied. Dem Compiler ist es auch Wurscht, 
wie das aussieht. Hauptsache er bekommt seine Klammern und Semikolons.

@Christian
Schreib nicht so viele Kommentare. Einmal oben drüber, was der Timer 
machen soll und gut ist. Daß die WGM-Bits für den Modus, die CS-Bits für 
den Prescaler und die COM-Bits für die Ausgänge sind, weiss man, wenn 
man das ein paar Mal gemacht hat, auch so. Und sonst gehört das 
Datenblatt sowieso auf den Tisch oder in 2 Registerkarten in den 
Browser. Eine fürs Pinout, die andere zum Blättern.

mfg.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.