Immer noch: Timerverständnisfrage

Hallo miteinander,

ich grüble immer noch an der korrekten Programmierung des Timers meines Attiny13 (weil der so hübsch übersichtlich ist, ich den mit dem Uno programmieren kann und ich ein extra Programmiershield dafür gebaut habe ;))

Ziel: PWM mit einstellbarer Pulsbreite, Frequenz erstmal egal.

Mein Code:

void setup(){
DDRB |= (1 << PB0); 	//Pin PB0 als Ausgang setzen
TCCR0A |= (1<<WGM01) | (1<<WGM00) | (1<< COM0A0);  //WGM00, 01 und 02 = 1 = FastPWM mit TOP = OCR0A
OCR0A = 64;  //Wert für Pulsbreite
TCCR0B |= (1<<WGM02) | (1<< CS02) | (0<<CS01) | (0<<CS00);  //prescaler 256
}
 
void loop(){}

Jetzt hätte ich erwartet, dass da eine schmale Pulsbreite von ca. 25% rauskommt mit einer Frequenz von ca. 9,6Mhz/256 = 37kHz.
Tatsächlich kommt was halbwegs symmetrisches raus mit 70Hz :blush:

Bevor die alten Hasen jetzt wieder lachen: verkneift's euch und helft mir auf die Sprünge :frowning:
Ja, die kürzlich vorgestellten Tutorials habe ich gelesen und meine auch sie verstanden zu haben.

Wo hab ich nen Knoten im Hirn??

Danke für Erhellung
Klaus

Ich hab das jetzt nochmal gecheckt, aufgrund eines unsichtbaren Kommentars von Serenifly.
Für den Prescaler ist ja nur CS02 auf 1 gesetzt, die anderen beiden auf 0. Da ich damit schon lange rumexperimentiere muss ich da darauf achten, dass die Kombination stimmt.
Beim Setzen von Bits bleiben die anderen ja unverändert - hab ich mal gelernt.

Bin weiterhin so schlau wie vorher, und das richtige Datenblatt habe ich auch verwendet XD

Sorry, ich hatte es wieder gelöscht weil ich mich vertan hatte :frowning:

Das (0<<CS01) hat mich verwirrt. Hatte übersehen, dass das auf 0 gesetzt war und gedacht dass es 1 wäre. Ich würde die zwei 0<<x weglassen. Das bringt nichts. Sollte aber auch nichts schaden...

Rein von der Theorie sollte es passen. PWM ist allerdings genau der Timer Teil mit dem ich micht nicht wirklich auskenne :slight_smile:
Hast du mal andere PWM Modi ausprobiert?

Naja, weglassen ist nicht gut wenn man ständig am Prescaler spielt ]:smiley:
Anderer Mode macht keinen Sinn (na gut, zum Testen schon) weil ich die Pulsbreite einstellen können möchte. Mode 3 kann das ja nicht.

Du kannst aber nur mit Mode 3 den Lastzyklus ändern, wenn ich die das Manual richtig verstanden hab. Mode 7 macht dir immer ein symetrisches Signal da du immer am Top schaltest und Top ist nunmal dein gesetzt ocr0a

Ich bin auch nicht so der timerexperte aber vielleicht hilfts

Ähhh, ich habs genau andersrum gelesen

TOP is defined as 0xFF when WGM2:0 = 3, and OCR0A when WGM2:0 = 7

Demnach kannst du nur, wenn du keinen Lastcycle von 50% haben willst, nur WGM2:0 = 3 nehmen. Sonst trifft der ja den CompareMatch nie vor TOP. Dann musst du den Prescaler so wählen, dass die gewünschte PWM Frequenz = CPU-Frequenz / (Prescaler * (0xFF bzw 255 +1) .. also müsstest du hier eben den wgm ändern und den prescaler zu 1 setzen um dein gewünschtes resultat zu erziehlen.

Hallo Nussecke,

ich steh zwar immer noch auf dem Verständnis-Schlauch, aber es funktioniert jetzt so (bissel noch gemopst im I-Net):

void setup(){

  DDRB |= (1 << DDB0);  //Port 0 (Pin 5) 
  TCCR0A  = ((1<<WGM00) | (1<<WGM01) | (1 << COM0A1)) ; // Fast PWM mode 3, Clear OC0A on Compare Match, set OC0A at TOP
  TCCR0B  = ((0<<CS02) |(0<<CS01) | (1<<CS00)); //  64 divider 
  OCR0A = 26;  //Tastverhältnis = 26/255 = 10%
}	

void loop(){}

Hab den Eindruck, das ist wie Fahrrad-fahren-lernen: erst haut's Dich ordentlich oft auf die Schnute, aber wenn's mal geht dann sitzt's ]:smiley:

Danke und Grüße
Klaus