Forum: Mikrocontroller und Digitale Elektronik Attiny841 Timer0 PWM: Wo ist der OC0A Pin?


von Niklas B. (niklas90)


Lesenswert?

Hallo,

ich versuche den Timer0 vom Attiny841 für eine einfache PWM zu 
konfigurieren. Modus und Prescaler einstellen scheint mir aus dem 
Datenblatt ersichtlich, aber wo wird das PWM Signal überhaupt 
ausgegeben? Im Datenblatt wird mehrfach dafür "OC0A" angegeben, aber 
dieser Pin existiert überhaupt nicht (?), zumindest nicht laut Seite 
2...

Wenn ich mir den Pin mit TOCPMSA0 auswählen kann, dann stehe ich erst 
Recht auf dem Schlauch, ich verstehe dieses Register nicht. Bzw. könnte 
mir jemand sagen, ob und wie ich PA3 als PWM-Output verwenden kann?

Derzeitiger Code:
1
// configure 8 bit timer0 as PWM
2
TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0A1); // Fast PWM mode, non-inverting
3
TCCR0B = (1 << CS01); // Prescaler 8
4
5
// select pin for pwm output?
6
7
OCR0A = 64; // duty cycle for example 25 % (0...255)

von Karl. M. (Gast)


Lesenswert?

Niklas,

wo wird denn das Pin konfiguriert, beachte bitte Seite Table 10-1. Port 
Pin Configurations

12.12.4 TOCPMSA1 and TOCPMSA0 – Timer/Counter Output Compare Pin Mux 
Selection Registers

Zur Auswahl stehen dir:
TOCC1 OC0A - PA2
TOCC3 OC0A - PA4
TOCC5 OC0A - PA6
TOCC7 OC0A - PB2

PA3 ist aber leider: TOCC2; somit Pech gehabt !

*Beispiel:* Für TOCC1 OC0A - PA2 wählt man dann:

Table 10-1. Port Pin Configurations
PUEA &= ~(1<<PA3);
PORTA &= ~(1<<PA3);
DDRA |= (1<<PA3);

12.12.4 TOCPMSA1 and TOCPMSA0 – Timer/Counter Output Compare Pin Mux 
Selection Registers
TOCPMSA1 = 0;
TOCPMSA0 = (0<<TOCC1S1) | (0<<TOCC1S0); // nur der Vollständigkeit 
halber

12.12.5 TOCPMCOE – Timer/Counter Output Compare Pin Mux Channel Output 
Enable
TOCPMCOE |= (1<<TOCC1OE);

von Karl. M. (Gast)


Lesenswert?

Niklas,

wo wird denn das Pin konfiguriert, beachte bitte Seite Table 10-1. Port 
Pin Configurations

12.12.4 TOCPMSA1 and TOCPMSA0 – Timer/Counter Output Compare Pin Mux 
Selection Registers

Zur Auswahl stehen dir:
TOCC1 OC0A - PA2
TOCC3 OC0A - PA4
TOCC5 OC0A - PA6
TOCC7 OC0A - PB2

PA3 ist aber leider: TOCC2; somit Pech gehabt !

*Beispiel:* Für TOCC1 OC0A - PA2 wählt man dann:

Table 10-1. Port Pin Configurations
PUEA &= ~(1<<PA2);
PORTA &= ~(1<<PA2);
DDRA |= (1<<PA2);

12.12.4 TOCPMSA1 and TOCPMSA0 – Timer/Counter Output Compare Pin Mux 
Selection Registers
TOCPMSA1 = 0;
TOCPMSA0 = (0<<TOCC1S1) | (0<<TOCC1S0); // nur der Vollständigkeit 
halber

12.12.5 TOCPMCOE – Timer/Counter Output Compare Pin Mux Channel Output 
Enable
TOCPMCOE |= (1<<TOCC1OE);

von Niklas B. (niklas90)


Lesenswert?

Mein Pin war schon richtig eingestellt ;-). Die Pullups und PORT-outs 
sind übrigens schon standardmäßig aus (der Initialwert für die Bits 
steht unten an den Registerbeschreibungen).

Danke für das Beispiel, jetzt habe ich dass mit dem Output compare Mux 
besser verstanden.

PA2 ist bei mir schon belegt, läuft aber mit PA4 genauso:
1
// PA4 as output
2
DDRA = (1 << PA4);
3
// configure 8 bit timer0 as PWM
4
TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0A1); // PWM Modus, non-inverting mode
5
TCCR0B = (1 << CS01); // Prescaler 8
6
TOCPMSA0 = (0 << TOCC3S0); // select TOCC3 (PA4) for output compare OC0A
7
TOCPMCOE |= (1 << TOCC3OE); // enable mux channel output
8
OCR0A = 8; // duty cycle (0...255)

Danke nochmal.

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hallo,

bitte beachte: TOCPMSA0.TOCC3S1 = TOCPMSA0.TOCC3S0 = 0 !
TOCPMSA1 = 0;

dann viel Erfolg !

von Tobi der Bastler (Gast)


Lesenswert?

Sorry für den alten Teil, hab aber nichts neues dazu gefunden.

Karl. M. schrieb:
> 12.12.4 TOCPMSA1 and TOCPMSA0 – Timer/Counter Output Compare Pin Mux
> Selection Registers
>
> Zur Auswahl stehen dir:
> TOCC1 OC0A - PA2
> TOCC3 OC0A - PA4
> TOCC5 OC0A - PA6
> TOCC7 OC0A - PB2

Was ist aber mit OC0B?
Der Pin PA5 hat ja nach der Tabelle OC0B und damit TOCC4.
Damit ergibt sich nach 12.12.4 TOCPMSA1 Bit 1 und 0.
Nach Tabelle 12-7 ist TOCC4 damit OC0B und TOCPMSA1 wird TOCC4S1 auf 1 
gesetzt.
TOCPMCOE ebenfalls auf 1.
Sieht dann so aus:
1
TOCPMSA1|=(1<<TOCC4S1);
2
TOCPMCOE|=(1<<TOCC4OE);
Versteh die Tabelle 12-7 und das mit 00, 01 und 1x dazu leider nicht.
Ist das korrekt?

von Georg M. (g_m)


Lesenswert?

Tobi der Bastler schrieb:
>
1
> TOCPMSA1|=(1<<TOCC4S1);
2
>
Das wäre für OC2B.



Tobi der Bastler schrieb:
> Versteh die Tabelle 12-7 und das mit 00, 01 und 1x dazu leider nicht.

00 für Timer 0
01 für Timer 1
1x für Timer 2

von Tobi der Bastler (Gast)


Lesenswert?

In der Tabelle 12-7, TOCPMSA1 ist doch TOCC4S1 und TOCC4S0 beim Start 
bereits auf 0 gesetzt. Wie kann ich dann das einstellen? Oder ist es 
beim Start schon auf OC0B eingestellt?

von Tobi der Bstler (Gast)


Lesenswert?

Timer dazu sieht so aus:
1
TCCR1B = (1<<WGM12);      // Auswahl CTC Modus
2
  TCCR1B = (1<<CS11)|(1<<CS10);  // Prescaler auf 64 setzen
3
  OCR1A=4999;            // Wert für 20 ms
4
  // Endpostion 1ms=249, 2ms=499
5
  // Neutralposition Mitte 375
6
  OCR1B=375;
7
  // Interrupt für Compare Match A und B aktivieren
8
  TIMSK1|=(1<<OCIE1A)|(1<<OCIE1B);      // Interrupt erlauben
9
  //TOCPMSA1|=(0<<TOCC4S1);
10
  TOCPMSA1|=(1<<TOCC4S0);
11
  TOCPMCOE|=(1<<TOCC4OE);
12
  sei();
13
14
ISR (TIMER1_COMPA_vect)    // ISR für Timer 1 und A
15
  {
16
    PORTA |=(1<<PINA5);    // Servo - ein
17
  }
18
19
ISR (TIMER1_COMPB_vect)    // ISR für Timer 1 und B
20
  {
21
  PORTA &=~(1<<PINA5);     // Servo - aus
22
  }

von Georg M. (g_m)


Lesenswert?

Tobi der Bastler schrieb:
>  Oder ist es beim Start schon auf OC0B eingestellt?

Ja.



Tobi der Bstler schrieb:
> Timer dazu sieht so aus:
>
1
> TCCR1B = (1<<WGM12);      // Auswahl CTC Modus
2
>   TCCR1B = (1<<CS11)|(1<<CS10);  // Prescaler auf 64 setzen
3
>   OCR1A=4999;            // Wert für 20 ms
4
>   // Endpostion 1ms=249, 2ms=499
5
>   // Neutralposition Mitte 375
6
>   OCR1B=375;
7
>   // Interrupt für Compare Match A und B aktivieren
8
>   TIMSK1|=(1<<OCIE1A)|(1<<OCIE1B);      // Interrupt erlauben
9
>   //TOCPMSA1|=(0<<TOCC4S1);
10
>   TOCPMSA1|=(1<<TOCC4S0);
11
>   TOCPMCOE|=(1<<TOCC4OE);
12
>   sei();
13
> 
14
> ISR (TIMER1_COMPA_vect)    // ISR für Timer 1 und A
15
>   {
16
>     PORTA |=(1<<PINA5);    // Servo - ein
17
>   }
18
> 
19
> ISR (TIMER1_COMPB_vect)    // ISR für Timer 1 und B
20
>   {
21
>   PORTA &=~(1<<PINA5);     // Servo - aus
22
>   }
23
>

Ohne Erklärung verstehe ich den Code nicht. Warum Interrupts und keine 
PWM?

von Tobi der Bastler (Gast)


Lesenswert?

Das soll einen Servo ansteuern. Mache es mit dem 16 Bit Timer 1. Dazu 
wird wird 20ms erzeugt und eingeschaltet. Mit Tastern kann ich 3 
verschiedene Positionen anfahren und testen wie weit sich der Servo 
dreht.
Wieso PWM, geht das besser damit?

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.