Attiny841 kein PWM Signal

OP #4811744
Lesenswert?
• ▲
▼
Hallo zusammen,

ich möchte am PIN PA7 eine PWM mit timer0 generieren. Leider bekomme ich 
überhaupt kein Signal.

DDRA |= (1<<PORTA7); // PA7 auf Output

// PWM am PIN PA7 aktivieren
TOCPMSA1 = (1<<TOCC6S0);
TOCPMCOE = (1<<TOCC6OE);

// Compare Output Mode, Phase Correct PWM Mode (siehe Tabelle 11-7 auf 
Seite 87)
TCCR0A = (1<<COM0B1);

// PWM, Phase Correct (siehe Tabelle 11-8 auf Seite 87) mit TOP OCRA
TCCR0A = (1<<WGM00) | (1<<WGM02);

// Vorteiler auf 256 => f = CPU_8MHZ/256
TCCR0B |=  (1<<CS02);
// PWM 50%
OCR0A = 127;

CPU läuft mit geändert Fusbits mit 8MHz. Bitte um Hilfe und Tipps. 
Herzlichen DANK
OP #4812114
Lesenswert?
• ▲
▼
Vielen Dank für die Hinweise und Tipps. Ich habe den Code korregiert:

// PA7 as output
DDRA = (1 << PINA7);
// configure 8 bit timer0 as PWM
TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0B0); // PWM Modus, 
non-inverting mode
TCCR0B = (1 << CS01); // Prescaler 8

//TOCPMSA0 = (0 << TOCC3S0);
TOCPMSA1 = (1<<TOCC6S0); // select TOCC6 (PA7) for output compare OC0B

TOCPMCOE |= (1 << TOCC6OE); // enable mux channel output
OCR0B = 8; // duty cycle (0...255)

Leider immer noch kein Signal am Pin. Woram kann es liegen? werdenhier 
DDRA Register (siehe PINA7 Bezeichung) und TOCPMSA1 mit TOCPMCOE richtig 
eingestellt?

Danke für die Tipps
OP #4812223
Lesenswert?
• ▲
▼
Das setzen auf COM0B1 ist leider trotzdem kein Siganl am Pin. Hier 
nochmal der gesamte Code im Überblick:

int main(void)
{

        PUEA &= ~ (1<<PORTA7); // Pull up on PA7 disabled
  PORTA &= ~ (1<<PORTA7);
  // PA7 as output
  DDRA |= (1 << PORTA7);

  // configure 8 bit timer0 as PWM
  TCCR0A |= (1 << WGM01) | (1 << WGM00) | (1 << COM0B1); // PWM Modus, 
non-inverting mode
  TCCR0B |= (1 << CS01); // Prescaler 8

  // select TOCC6 (PA7) for output compare OC0B
  TOCPMSA0 = 0x00;
  TOCPMSA1 |= (1<<TOCC6S0) | (1 << TOCC6S1);

  TOCPMCOE |= (1 << TOCC6OE) ; // enable mux channel output
  OCR0A = 127; // duty cycle 50%

  sei();

  while(1)
  {

  }
}

Bitte um weitere Hinweise und Tipps
(Firma: TravelRec.) Persönliche Seite #4812442
Lesenswert?
• ▲
▼
So, wie gesagt. In meiner Anwendung sind alle Timer aktiv, deswegen die 
entsprechende Init. Timer0 geht mit OCR0B auf TOCC2 raus. Musst Du also 
passig ändern.

1
 
2
;setup Ports
3
 ldi  Temp, 0b11101011
4
 out  DDRA, Temp
5
 ldi  Temp, 0b00001000
6
 out  PortA, Temp
7

8
...
9

10

11
;setup Timer0 (Timebase)
12
 ldi  Temp, (1<<COM0B1)|(1<<WGM01)|(1<<WGM00)
13
 out  TCCR0A, Temp                                  ;Fast PWM, noninverting
14
 ldi  Temp, (0<<CS02)|(0<<CS01)|(1<<CS00)                        ;Prescaler 1
15
 out  TCCR0B, Temp
16
 ldi  Temp, 255                                    ;Charger off
17
 out  OCR0B, Temp
18

19
 ldi  Temp, 0b00000000                                ;OC0B routed to TOCC2 output
20
 sts  TOCPMSA0, Temp    
21

22

23
 ldi  Temp, 0b11110100                                ;TOCC7/TOCC6/TOCC4/TOCC4/TOCC2 output enabled
24
 sts  TOCPMCOE, Temp
Gast #4812484
Lesenswert?
• ▲
▼
Das:
> DDRA |= (1<<PORTA7); // PA7 auf Output

und das:
 ldi  Temp, 0b11101011
 out  DDRA, Temp

passt für micht nicht zusammen.

Wie ist denn PORTA7 bei Dir definiert?
Vielleicht mal mit

 DDRA |= (1<<DDA7); // PA7 auf Output
(müsste ja wahrscheinlich
 DDRA |= 0b00000001 sein)

ausprobieren.

Werner
OP #4813380
Lesenswert?
• ▲
▼
Vielen Dank an euch für die Hinweise und Tipps. Jetzt funktioniert es!!!
Am Anfang hatte ich Probleme, da der OCR0B Register für die Pulsweite 
nicht definiert war. Hier nun ein Beispiel mit 122 HZ PWM und 50% duty 
cycle mit einem Bild als Beweis :-)

#include "headerfiles.h"

int main(void)
{
  PUEA &= ~ (1<<PORTA7);  // Pull up off
  PORTA &= ~ (1<<PORTA7); // reset Port A7
  DDRA |= (1 << DDRA7); // PA7 as output

  // configure 8 bit timer0
  TCCR0A |=  (1 << WGM00) | (1 << WGM01) | (1 << COM0B1); // fast PWM 
Modus, non-inverting mode
  TCCR0B |= (1 << WGM02); // set TOP counter OCR0A

  // select TOCC6 (PA7) for output compare OC0B
  TOCPMSA0 |= 0x00;
  TOCPMSA1 |= 0x00; // (1<<TOCC6S0) => warum 0x00?

  TOCPMCOE |= (1 << TOCC6OE); // enable mux channel output (PA7)

  OCR0A = 255; // PWM Frequenz f = CPU/prescaler/OCR0A = 
8000000/1024/255 =~ 122 Hz ~ 8ms
  OCR0B = 127; // Pulsweite (duty cycle) 50% ~ 4ms

  TCCR0B |=  (1 << CS02); // start timer0 with prescaler 1024

  sei(); // enable interrupts

  while(1)
  {
           TO DO...
  }
}

Eine Frage hätte ich: Warum muss TOCPMSA1 auf 0x00 gesetzt werden? 
Welchen Sinn macht dann dieser Register?
Angehängte Dateien:
(Firma: TravelRec.) Persönliche Seite #4814176
Lesenswert?
• ▲
▼
In TOCPSMA1 steckt die Kodierung der Timer OCRs für TOCC4 bis TOCC7, in 
Deinem Fall also auch für TOCC6. Da Du OCR0B verwenden willst, lauten 
die Bits dafür 00. Da Du andere Timer noch nicht verwendest, ist es 
klug, auch diese Bits erst einmal auf 0 zu lassen, damit Du nicht 
zusätzlich verwirrt wirst. Wenn Du andere OCRs verwenden willst, kannst 
Du die betreffenden Bits selbstverständlich auch manipulieren. Aber 
einen Schritt nach dem anderen und durch Probieren das Datenblatt 
verstehen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren