PWM Frequenz um Faktor 4 zu niedrig

OP (Firma: Brainit GmbH) #2998995
Lesenswert?

Hallo zusammen,

ich hab hier ein Phänomen, welches ich nicht verstehe:

ATmega328P mit 16 MHz (externer Quarz)

Timer 0 mit Prescaler 1024 für SoftPWM

Timer 0 läuft von 0..255, je nach Schwellwert (ebenfalls 0..255 also 
uint8) wird eine Display-Hintergrundbelechtung ein- oder ausgeschaltet.

Funktioniert eigentlich super!

Nun hab ich mit dem Oszi das PWM-Signal nach dem Schalttransistor 
angesehen, schaut eh gut aus, hat aber eine Periodendauer von 4 msec 
(und zwar nciht ungefähr 4 msec, sondern recht genau 4 msec)

4 msec => 250 Hz

Allerdings: 16 MHz / 1024 (prescaler) = 15625 Hz Timer-Takt

ein Volldruchlauf 0..255 => 15625 / 256 = 61 Hz

also genau um den Faktor 4.096 daneben

Wo ist mein Denkfehler?
OP (Firma: Brainit GmbH) #2999019
Lesenswert?

Hellseher schrieb:
> Definitionen des Timers posten

Sorry, vergessen:
1
#define BACKLIGHT_PORT PORTB
2
#define BACKLIGHT_BIT _BV( 0 )
3
#define BACKLIGHT_INIT DDRB |= BACKLIGHT_BIT
4
#define BACKLIGHT_OFF BACKLIGHT_PORT &= ~BACKLIGHT_BIT
5
#define BACKLIGHT_ON  BACKLIGHT_PORT |=  BACKLIGHT_BIT
6

7
static volatile uint8_t pwm_phase = 0;
8
static volatile uint8_t pwm_value = 0;
9

10

11
// init Timer 0
12
static void timer_init(void)
13
{
14
    pwm_phase = 0;
15
    pwm_value = 0;
16

17
    TCCR0A = 0; // normal operation
18
    TCCR0B = _BV(CS02) || _BV(CS00);    // prescaler 1024
19
    TIMSK0 = _BV(TOIE0);  // enable overflow interrupt
20
}
21

22

23

24
// Timer 0 overflow handler
25
ISR(TIMER0_OVF_vect)
26
{
27
    pwm_value++;
28
    if (pwm_value < pwm_phase) {
29
  BACKLIGHT_ON;
30
    } else {
31
  BACKLIGHT_OFF;
32
    }
33
}
#2999056
Lesenswert?

Mit deinen WErten für pwm_phase dürfte sich an deinem Pin überhaupt 
nichts tun.


Deine Berechnung stimmt an und für sich. Wenn die 16Mhz gesichert sind, 
bleibt nur noch die Möglichkeit, dass du dich vermessen hast oder nicht 
das misst was du denkst das du misst oder in deinem Programm ist noch an 
anderer Stelle was faul.

PS: deine Beleuchtung müsste flackern wie Sau.
OP (Firma: Brainit GmbH) #2999065
Lesenswert?

Karl Heinz Buchegger schrieb:
> Mit deinen WErten für pwm_phase dürfte sich an deinem Pin überhaupt
> nichts tun.

Richtig. aber pwm_phase wird (an nicht sichtbarer Stelle) geändert. Zum 
Testen/Oszilloskopieren hab ichs auf 128 gesetzt (also 50%)

> Deine Berechnung stimmt an und für sich. Wenn die 16Mhz gesichert sind,
> bleibt nur noch die Möglichkeit, dass du dich vermessen hast oder nicht
> das misst was du denkst das du misst oder in deinem Programm ist noch an
> anderer Stelle was faul.

Genau die 16 MHz zweifle ich ja auch an. Nur - wie prüf ich die? Am 
Quarz zu oszilloskopieren wird ja nicht funktionieren.

Kanns an den Fuses liegen? eingestellt wären die auf

lfuse:w:0xff:m
hfuse:w:0xd6:m
efuse:w:0x05:m

Auch andere Stellen hääte ich geprüft, nur gibts nciht viel. Das ist der 
einzige Timer, sonst gibts nur diverse port-zugriffe...
#2999070
Lesenswert?

>     TCCR0B = _BV(CS02) || _BV(CS00);    // prescaler 1024

Ach hier ist er.
Das ist kein Prescaler von 1024, sondern ein Prescaler von 1.

|| ist kein binäres Oder sondern ein logisches.

Und dann stimmt auch die Berechnung wieder. Mit einem Prescaler von 1 
kommt man auf eine rechnerische PWM-Frequenz von 244Hz
OP (Firma: Brainit GmbH) #2999108
Lesenswert?

Ich dnek ich habs: bei meinem Tippfehler
1
TCCR0B = _BV(CS02) || _BV(CS00);    // prescaler 1024

schlägt die "short circuit evaluation" zu, und TCCR0B wird auf _BV(CS02) 
gesetzt, das entspricht einem Prescaler von 256, und damit passt alles 
zusammen.

Danke nochmal!
#2999150
Lesenswert?

Michael Reinelt schrieb:
> Karl Heinz Buchegger schrieb:
>
>> Und dann stimmt auch die Berechnung wieder. Mit einem Prescaler von 1
>> kommt man auf eine rechnerische PWM-Frequenz von 244Hz
>
>
> Ähhhh...
>
> 16 MHz, prescaler 1 => 16 MHz
> 16 MHz / 256 = 62.5 kHz
>
> Wie kommst du auf 244 Hz?

Du brauchst 256 ISR Aufrufe, bis ein PWM Zyklus durch ist.
62kHz / 256 -> 244Hz
#2999155
Lesenswert?

Michael Reinelt schrieb:
> Ich dnek ich habs: bei meinem Tippfehler
>
>
1
> TCCR0B = _BV(CS02) || _BV(CS00);    // prescaler 1024
2
>
>
> schlägt die "short circuit evaluation" zu

Nö.

Das ist ein LOGISCHES Oder!
Bei logischen Operationen kann das Ergebnis nur 0 oder 1 sein.
Bei dir ist es 1, da sowowhl _BV(CS02) als auch _BV(CS00) ungleich 0 und 
damit logisch TRUE sind. Das Ergebnis ist also TRUE (1) und wenn man das 
zuweist, ergibt das einen Prescaler von 1

> gesetzt, das entspricht einem Prescaler von 256, und damit passt alles
> zusammen.

Du hast eine ISR Aufruffrequenz von 62kHz. Aber in der ISR teilst du das 
ja durch den Zähler nochmal weiter runter. Im Endeffekt landest du bei 
einer PWM Frequenz (steigende Flanke zu steigende Flanke am Portpin) von 
244Hz.
OP (Firma: Brainit GmbH) #2999185
Lesenswert?

Karl Heinz Buchegger schrieb:
> Bei logischen Operationen kann das Ergebnis nur 0 oder 1 sein.
> Bei dir ist es 1, da sowowhl _BV(CS02) als auch _BV(CS00) ungleich 0 und
> damit logisch TRUE sind. Das Ergebnis ist also TRUE (1) und wenn man das
> zuweist, ergibt das einen Prescaler von 1


> Du hast eine ISR Aufruffrequenz von 62kHz.
> Aber in der ISR teilst du das
> ja durch den Zähler nochmal weiter runter. Im Endeffekt landest du bei
> einer PWM Frequenz (steigende Flanke zu steigende Flanke am Portpin) von
> 244Hz.

Du hast natürlich recht. meine "Soll-Berechnung" war schon komplett 
falsch.

Ohne Tippfehler hätte ich eine PWM-Frequenz von

16 MHz / 1024 (prescaler) / 256 (overflow) / 256 (counter) = 0.2 Hz.

jetzt versteh ich auch deine Aussage "deine beleuchtung muss flackern 
wie Sau" :-)
Gast #2999187
Lesenswert?

Hi

>Können vor Lachen :-) leider ist kein Output-Compare-Pin mehr frei.

Du kannst auch den Pin im Overflow-Interrupt setzen und im 
Compare-Interrupt
löschen. Da ist keine Soft-PWM notwendig.

MfG Spess
OP (Firma: Brainit GmbH) #2999194
Lesenswert?

spess53 schrieb:
> Hi
>
>>Können vor Lachen :-) leider ist kein Output-Compare-Pin mehr frei.
>
> Du kannst auch den Pin im Overflow-Interrupt setzen und im
> Compare-Interrupt
> löschen. Da ist keine Soft-PWM notwendig.
>
> MfG Spess

ja, so werd ich's eh machen müssen. Nachdem ich jetzt hoffentlich alle 
Denk- Tipp- und Rechenfehler elimiert habe, ist mir die PWM-Frequenz 
ohnehin zu niedrig.

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