Forum: Mikrocontroller und Digitale Elektronik Timer-Überlauf bei Hardware PWM


von T. P. (led_pi)


Lesenswert?

Hallo,

Ich habe mittels Hardware PWM einen verstellbaren Frequenzgenerator 
programiert. Da der Timer beim verstellen manchmal übergelaufen ist und 
die Frequenz versaut hat habe ich folgendes gemacht:
1
int frequenz(int y)
2
{
3
if(TCNT3>=y)          // Prüfung ob neuer Top-Wert gleich oder niedriger als die aktuelle Timerposition ist
4
{
5
TCNT3 = 0 + (TCNT3 - y);      // Wenn ja dann wird der Timer auf 0 + den bereits überschrittenen Wert gesetzt
6
}
7
8
ICR3 = y;          // Top-Wert wird festgelegt
9
OCR3A = 127;          // Anzeit 50%
10
11
return 0;
12
}

Der µC ist ein ATMega1284P mit exteren Oszillator 7,3728 Mhz
Hier noch der Timer init:
1
void timer_init(void)
2
{
3
TCCR3A = (1<<COM3A1) | (1<<WGM31);
4
TCCR3B = (1<<WGM33) | (1<<WGM32) | (1<<CS32); // Vorteiler 256 Takt 7,3728 Mhz 
5
}

Szenario:

Timer ist bei 32765 von max 32767.
Aktueller Topwert ist bei 32766 und wird auf 32000 geändert.
In der Bearbeitunszeit von if(TCNT3>=y) und TCNT3 = 0 + (TCNT3 - y); ist 
der Timer wieder bei 0.
0-32000=-32000?

Meine Frage ist ob der Befehl TCNT3 = 0 + (TCNT3 - y); so ok ist und wie 
lange der µC für dies Operation braucht bzw ob es auch eleganter zu 
lösen geht?

MFG
LED_PI

von Thomas E. (thomase)


Lesenswert?

T. P. schrieb:
> TCNT3 = 0 + (TCNT3 - y)

Das ist doch Unsinn.  Stell das mal um (Kommutativgesetz):
1
TCNT3 = (TCNT3 -y) + 0;

Daraus wird dann:
1
TCNT3 = TCNT3 -y;

Oder schön griffig in C:
1
TCNT3 -= y;

Das Schöne dabei ist, dass der Compiler sich auf diesen Quatsch nicht 
einlässt und alle Varianten gleich lange dauern. Im *.lss kannst du dir 
angucken, was er daraus macht und nachzählen, wie viele Takte das 
dauert.

mfg.

von c-hater (Gast)


Lesenswert?

T. P. schrieb:

> Ich habe mittels Hardware PWM einen verstellbaren Frequenzgenerator
> programiert. Da der Timer beim verstellen manchmal übergelaufen ist und
> die Frequenz versaut hat

Dann hast du schlicht den FALSCHEN (für deinen Zweck ungeeigneten) 
PWM-Modus verwendet.

Phase&FrequencyCorrect wäre der richtige gewesen, da kümmert sich 
nämlich die Hardware selber auch um dieses Problem, da werden nämlich 
auch Zugriffe auf das die Frequenz bestimmende Register automatisch 
synchronisiert.

Das ist auch bitter nötig, denn eine vollständige Lösung des Problems in 
Software ist nicht bzw. nur für einen nach oben weit unter die 
Möglichkeiten des Timers selber eingeschränkten Frequenzbereich möglich.

von T. P. (led_pi)


Lesenswert?

Ok also werde ich es mal mit Mode 9 probieren.

MFG
Led_Pi

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.