Forum: Mikrocontroller und Digitale Elektronik Software-PWM und Grundfrequenz


von hilel (Gast)


Lesenswert?

Hallo zusammen.
Ich möchte die Anzahl der PWM-Signale eines MEGA128 erweitern. Es soll 
softwaremässig mit einem 16Bit-Timer/Counter ein PWM-Signal erzeugt 
werden. Die PWM-Frequenz soll 1kHz betragen.
Meine Berechnung sieht wie folgt aus:

Sei f die Taktfrequenz (16MHz), p der Prescaler (1), k der Teiler
des 16Bit-Timer/Counter TC und n (in diesem Fall 8) die Breite des 
Zählers. Dieser Zähler zählt von 0 an bis zu seinem Maximum und ändert 
die Zählrichtung, sobald dieses Maximum (TOP) erreicht wird. Es handelt 
sich also um eine phasenrichtige PWM. Bei Erreichen eines Compare-Wertes 
wird ein Ausgangspin getoggelt.
Dann gilt für das softwaremässig erzeugte PWM Signal:

                    f
f(PWM) = -------------------------------
          (2^n+1  - 2)  Prescaler  k

Geht man von der PWM-Frequenz von 1kHz aus, dann berechnet sich k zu:

k = 16000000/(1000*(2^9 -2)) = 31,37 (gewählt k=31)

Nachladewert des Counters ist dann:
2^16 - 31 = 65505 = 0xFFE1

TCNT1H = 0xFF
TCNT1L = 0xE1
TCCR1B = 0x01   Prescaler: 1

Sind meine Überlegungen richtig?
Ich bekomme aus irgendwelchen Gründen die falsche PWM-Frequenz. Diese 
Frequenz ist zwar nicht wichtig, ich möchte dennoch verstehen, wo der 
Denkfehler liegt.
Hier ist ein Ausschnitt vom C-Quellcode

// TIMER1 initialisation - prescale:1
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xFF; //setup
 TCNT1L = 0xE1;
}

#pragma interrupt_handler timer1_ovf_isr:15
void timer1_ovf_isr(void)
{
 TCNT1H = 0xFF;      // reload counter high value
 TCNT1L = 0xE1;      // reload counter low value

 if(!direction)       //
    count++;
  else
    count--;
  if(count==0x01)
    direction=0;
  if(count==0xFE)
    direction=1;
  if(count == temp1)
    TOGGLEBIT(PORTD,5);
}

void main()
{
 init_devices();
 direction=0;     // der 8Bit-Zähler soll zunächst vorwärts zählen
 count = 0x00;
 TCCR1B = 0x01; //start Timer, no prescaling
 while(1);
}

von Flo.K (Gast)


Lesenswert?

Hi hilel,
ich würde an deiner Stelle den Timer im Compare-Modus laufen lassen, 
damit sparst du dir schon mal dir Reinitialisierung nach dem Overflow 
(inkl. Zeitverzug).

Mir hat bei diesem Thema mit dem Software PWM eine Applicatione Note von 
Atmel weitergeholfen (AVR136: Low-jitter Multi-channel Software PWM). 
Ist zwar am Anfang ein bisschen unübersichtlich, aber wenn man das 
Prinzip kappiert hat ist die Lösung wesentlich einfacher als das Rad neu 
zu erfinden.

Mfg
Flo

von hilel (Gast)


Lesenswert?

Hallo Flo.K

Danke für die rasche Antwort.
Ich werde mir diese AN anschauen.

Gruß Hilel

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.