Forum: Mikrocontroller und Digitale Elektronik ATtiny 2313 PWM-Frequenz zu langsam


von Remo G. (scar)


Lesenswert?

Hallo Zusammen,

ich weiss dieses Thema wurde schon des öfteren diskutiert.

-Beim mir läuft der Timer0 im Fast PWM Mode, Prescaler 1.
-Die Fuse DIV8 ist ausgeschaltet.
-8MHz int. RC Osc.

Aber die PWM-Frequenz beträgt ca. 126Hz, mit dem KO gemessen.
->Nach Formel im Datenblatt sollte diese ja (fclk_io/N*256) ca. 31.25kHz 
betragen.

Kann mir jemand ein Tipp geben?

Danke!

von troll (Gast)


Lesenswert?

Quellcode zeigen.

von spess53 (Gast)


Lesenswert?

Hi

>Kann mir jemand ein Tipp geben?

Du hast etwas falsch gemacht. Deine 126 Hz sind etwa 1/256 (122 Hz) vom 
erwarteten Wert. Und der Faktor muss irgendwo herkommen.

MfG Spess

von Dave C. (dave_chappelle)


Lesenswert?

Remo Gilgen schrieb:
> -Beim mir läuft der Timer0 im Fast PWM Mode, Prescaler 1.
> -Die Fuse DIV8 ist ausgeschaltet.
> -8MHz int. RC Osc.

Etwas davon ist nicht wahr, sonst würde es funktionieren.

von Bernd S. (bernds1)


Lesenswert?

Remo Gilgen schrieb:
>
> Aber die PWM-Frequenz beträgt ca. 126Hz, mit dem KO gemessen.
> ->Nach Formel im Datenblatt sollte diese ja (fclk_io/N*256) ca. 31.25kHz
> betragen.
>
Die 31kHz ist die Frequenz, mit der der Timer läuft, der die PWM 
erzeugt. Wenn du jetzt eine 8-bit-PWM hast, braucht der Timer 256 
Zyklen, um eine Periode der PWM abzuarbeiten.
Wenn du jetzt die 31kHz durch 256 teilst, kommst auf 122Hz. Ist also 
alles richtig.

von Remo G. (scar)


Lesenswert?

Danke für die schnellen Antworten.

Auf den Faktor 256 bin ich auch schon gekommen. Nur keine Idee wo ich 
diesen suchen soll!

Code:
void timer0_fast_pwm_init(void)
{
DDRB=DDRB|(1<<PB2);
TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
TCCR0B=(0<<CS00)|(0<<CS01)|(1<<CS02);
OCR0A=0x00;
}

void timer0_PWM(void)
{
if(zaehler0==0x000f)
  {
   zaehler0=0;
   OCR0A=reload0++;
  }
if(reload0==0x8f) reload0=0;

if((TIFR&(1<<TOV0))==0x02)
  {
   zaehler0++;
   TIFR=TIFR&(1<<TOV0);
   }
}

Gruss

von Karl H. (kbuchegg)


Lesenswert?

Remo Gilgen schrieb:
> Danke für die schnellen Antworten.
>
> Auf den Faktor 256 bin ich auch schon gekommen. Nur keine Idee wo ich
> diesen suchen soll!
>
> Code:
> void timer0_fast_pwm_init(void)
> {
> DDRB=DDRB|(1<<PB2);
> TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
> TCCR0B=(0<<CS00)|(0<<CS01)|(1<<CS02);

was ist das für ein Prescaler?

-> Noch mal rechnen

voprher das hier lesen:
FAQ: Timer
dann verstehst du auch wo und wie die Formel entsteht und ... brauchst 
sie gar nicht mehr.

von Simon B. (nomis)


Lesenswert?

Bernd S. schrieb:
> Die 31kHz ist die Frequenz, mit der der Timer läuft, der die PWM
> erzeugt. Wenn du jetzt eine 8-bit-PWM hast, braucht der Timer 256
> Zyklen, um eine Periode der PWM abzuarbeiten.
> Wenn du jetzt die 31kHz durch 256 teilst, kommst auf 122Hz. Ist also
> alles richtig.

Nee, da hast Du einen Denkfehler drin.

Mit Prescaler 1 läuft der Timer mit 8MHz (sofern Clock-Source etc. 
richtig sind), d.h. die resultierende PWM-Frequenz ist 8MHz/(1 * 256) = 
31.25kHz. Da muss man nicht zweimal durch 256 teilen...

--> OP: Bitte Quellcode bereitstellen. (EDIT: Ah, ist inzwischen da...)

Grüße,
         Simon

von troll (Gast)


Lesenswert?

Zum eigentlichen Problem kann ich ohne Datenblatt gerade nichts sagen, 
aber das hier
Remo Gilgen schrieb:
>TIFR=TIFR&(1<<TOV0);

ist zu 99% Käse. Entweder TIFR|(1<<TOV0) oder TIFR&~(1<<TOV0).

von Axel R. (Gast)


Lesenswert?

>TCCR0B=(0<<CS00)|(0<<CS01)|(1<<CS02);
hier irgentwo... ?

Wo hast Du die Initialisierung her?

von Bernd S. (bernds1)


Lesenswert?

Remo Gilgen schrieb:
> Danke für die schnellen Antworten.
>
> Auf den Faktor 256 bin ich auch schon gekommen. Nur keine Idee wo ich
> diesen suchen soll!

Ich habs mir jetzt nicht im Detail angesehen, aber geh mal davon aus, 
daß dein Timer0 mit 31kHz läuft. Wie kann dann die PWM auch 31kHz haben? 
Innerhalb von 256 Schritten entscheidet sich doch, ob der Ausgangs-Pin 
high oder low gesetzt wird. Zum Beispiel bei Zählerstand Null wird er 
eingeschaltet und bei 128 wieder aus. Den Rest bis 255 bleibt er aus, 
dann geht das Spiel wieder von vorn los.

Übrigens kannst du das ganze einfacher machen, wenn du dem Timer die 
Arbeit überläßt. Dann braucht es keine Software für die PWM. Außer du 
willst andere Pins für die PWM verwenden, die nicht zum Timer gehören. 
Kannst dir ja mal das Kapitel Timer durchlesen:

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

Gruß Bernd

von Remo G. (scar)


Lesenswert?

Hallo kbuchegg

Daaaaannnnkkkkeeeeeeee!

von Felix P. (fixxl)


Lesenswert?

troll schrieb:
> Zum eigentlichen Problem kann ich ohne Datenblatt gerade nichts sagen,
> aber das hier
> Remo Gilgen schrieb:
>>TIFR=TIFR&(1<<TOV0);
>
> ist zu 99% Käse. Entweder TIFR|(1<<TOV0) oder TIFR&~(1<<TOV0).

Weder noch. Für das manuelle Löschen von Interrupt-Flags gelten 
besondere Regeln:

http://www.mikrocontroller.net/articles/AVR_Checkliste#Flag_richtig_gel.C3.B6scht.3F

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.