Mit einem MC68HC908GP32- Mikrocontroller kann kein ordnungsgemäßes Sinussignal generiert werden . Die PWM-Beschreibung beginnt ab Seite 349. Die Taktfrequenz beträgt 2,4 MHz, während wir 7 kHz PWM verwendet haben, indem wir den Prescaler verwendet und das Timer-Modulo wie folgt auf 350 eingestellt haben:
T1SC = 0x60; // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01; // High
T1MODL = 0x5E; // Low
Der PWM-Ausgang wird durch das folgende RLC-Filter gefiltert, und dann wird DC unter Verwendung einer 1uF-Kappe der Serie entfernt. Die Grenzfrequenz liegt weit unter PWMs 7kHz.
Zunächst haben wir versucht, eine LUT zu verwenden, deren Samples mit dieser Site erstellt wurden (100 Samples, Amplitude = 250). Dies umfasst eine einzelne Periode.
int seno[100]={ 125, 133, 141, 148, 156, 164, 171, 178, 185, 192, 198, 205, 211, 216, 221, 226, 231, 235, 238, 241, 244, 246, 248, 249, 250, 250, 250, 249, 248, 246, 244, 241, 238, 235, 231, 226, 221, 216, 211, 205, 198, 192, 185, 178, 171, 164, 156, 148, 141, 133, 125, 117, 109, 102, 94, 86, 79, 72, 65, 58, 52, 45, 39, 34, 29, 24, 19, 15, 12, 9, 6, 4, 2, 1, 0, 0, 0, 1, 2, 4, 6, 9, 12, 15, 19, 24, 29, 34, 39, 45, 52, 58, 65, 72, 79, 86, 94, 102, 109, 117};
Die Breite des folgenden Impulses wird in jedem PWM-Zyklus berechnet:
interrupt 4 void rsi_t1ch0 (void)
{
//-- disable interruption flag
T1SC0&=(~0x80);
//-- pwm to '0'
PTB&=0xFD;
//some sensor measures are done here.... 100 out of the 350 cycles are left for this
}
/************************************************************/
/* TIM1 overflow rutine */
/************************************************************/
interrupt 6 void rsi_ov1 (void)
{
T1SC&=(~0x80);
//-- set PWM to 1
PTB|=0x02;
T1CH0H = ((seno[fase])>>8); // high bits
T1CH0L = (seno[fase])&0xFF; // low bits
fase+=1;
if (fase >= 99)
fase=0;
}
void main(void)
{
float temp;
int i;
CONFIG1|=0x01;
DDRB=0xFF; //-- Port B is set as output
PTB=0x00;
//Timer setup
T1SC = 0x60; // Prescaler: Div by 64
T1MODH = 0x01; //Counter modulo
T1MODL = 0x5E;
T1SC0 = 0x50; //Comparator setup
//-- Initial width
T1CH0H = 0x00;
T1CH0L = 0x53;
EnableInterrupts;
T1SC&=~(0x20); //Run timer forever
for(;;);
}
Wenn Sie es in das Oszilloskop einstecken, erhalten Sie das folgende Signal. Wir sind nicht in der Lage, diesen seltsamen Gipfel nahe dem Minimum zu vermeiden.
Wenn wir um diesen Peak zoomen, können wir sehen, dass die PWM-Ausgabe (nach oben) tatsächlich falsch ist.
Nachdem wir eine Weile herumgespielt haben und es nicht schaffen, es loszuwerden, haben wir versucht, das Sinussignal in der MCU zu berechnen, anstatt den Wert für jedes Sample hart zu codieren. Wir haben den folgenden Code in die Hauptfunktion eingefügt, kurz vor der Einrichtung des Zählers:
for(i=0;i<99;i++) {
temp=100*(sin(2*3.14159*i/100)+1);
seno[i]=(int)temp;
}
Die Ergebnisse sehen jedoch nicht einmal wie eine Sinuskurve aus:
Nachdem wir stundenlang damit zu kämpfen hatten, konnten wir unseren Fehler nicht finden. Wir würden uns über einen Rat freuen.