mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Software-PWM und Grundfrequenz


Autor: hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: Flo.K (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Flo.K

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

Gruß Hilel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.