Gast
#422576
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);
}