Forum: Mikrocontroller und Digitale Elektronik Frage zu Soft-PWM


von Bene (Gast)


Lesenswert?

Hallo zusammen,

ich habe eben mit dem Soft-PWM Programm aus dem Tutorial rumgespielt. 
Ich möchte die auf 100 Hz definiert PWM-Frequenz erhöhen und erhalte 
dabei immer folgende Fehlermeldung:

../soft_pwm_test.c:129: warning: integer overflow in expression


Ausschnitt aus dem Code:
// Timer 1 Output COMPARE A Interrupt
ISR(TIMER1_COMPA_vect)
{
    static uint8_t pwm_cnt=0;
    uint8_t tmp=0;

    OCR1A += (uint16_t)T_PWM;  <== Zeile 129 <== <== <== <== <==

    if (pwm_setting[0] > pwm_cnt) tmp |= (1<<0);
    if (pwm_setting[1] > pwm_cnt) tmp |= (1<<1);
    if (pwm_setting[2] > pwm_cnt) tmp |= (1<<2);
    if (pwm_setting[3] > pwm_cnt) tmp |= (1<<3);

    PWM_PORT = tmp;                         // PWMs aktualisieren
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
        pwm_cnt=0;
    else
        pwm_cnt++;
}

Kann mir jemand einen Tip geben?

Gruß

Bene

von Mikes (Gast)


Lesenswert?

OCR1A ist ein 8 Bit register!

von Karl H. (kbuchegg)


Lesenswert?

Bene wrote:

> ../soft_pwm_test.c:129: warning: integer overflow in expression

Das bedeutet nichts anderes, als dass in einer konstanten Berechnung der 
Zahlenbereich überschritten wurde.

>     OCR1A += (uint16_t)T_PWM;  <== Zeile 129 <== <== <== <== <==

Aha. Dann sehen wir uns einfach mal an, was T_PWM ist.

#define T_PWM (F_CPU/(F_PWM*PWM_STEPS))

wobei
#define F_CPU 8000000L
#define F_PWM 100
#define PWM_STEPS 256

die einzige Integer-Berechnung die in der T_PWM Formel vorkommt, ist 
F_PWM*PWM_STEPS

Mit deinen gewählten Werten ergibt sich also, dass F_PWM*PWM_STEPS einen 
Wert größer als 32767 ergibt. Und damit ist das ausserhalb des 
int-Bereiches bei 16 Bit. Du könntest zb. den Compiler zwingen die 
Berechnung nicht in int, sondern in long durchzuführen. Dazu genügt es, 
wenn eine der beiden Zahlen eine Long-Zahl ist. Also zb

#define F_PWM 100L

von Mikes (Gast)


Lesenswert?

@Karl Heinz
Und was bringt Dir das, wenn OCR1A doch nur die untersten 8 Bit addiert?

von Bene (Gast)


Lesenswert?

Vielen Dank

hab was gelernt und es funktioniert.

Gruß

Bene

von Mikes (Gast)


Lesenswert?

sorry vergessen:

... und speichert.

von Karl H. (kbuchegg)


Lesenswert?

Mikes wrote:
> @Karl Heinz
> Und was bringt Dir das, wenn OCR1A doch nur die untersten 8 Bit addiert?

Du irrst.
OCR1A ist ein 16 Bit Register, bestehend aus OCR1AH und OCR1AL


Selbst wenn es ein 8 Bit Register wäre:
Ist uninteressant, der Compiler kann das sowieso nicht prüfen, da der 
neue Wert des Reigsters unter anderem auch vom alten Wert abhängt. Eine 
Warnung wie die oben angegebene wird vom Compiler normalerweise nur dann 
ausgegeben, wenn alle beteilgten Operanden konstant sind. Und bei += 
sind sie das nun mal nicht.

Ausserdem: Auch eine konstante Berechnung, die nur aus int besteht, kann 
durchaus ein Ergebnis liefern, welches in einen uint8_t passt.

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.