Nous ne pouvons pas générer correctement un signal sinusoïdal à l'aide d'un microcontrôleur MC68HC908GP32 . La description du PWM commence à la page 349. La fréquence d'horloge est de 2,4 MHz, tandis que nous avons utilisé le PWM à 7 kHz en utilisant le pré-échelle et en réglant le module de minuterie sur 350 comme suit:
T1SC = 0x60; // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01; // High
T1MODL = 0x5E; // Low
La sortie PWM est filtrée par le filtre RLC suivant, puis DC est retiré à l'aide d'un capuchon de 1 uF série. La fréquence de coupure est bien inférieure à 7 kHz de PWM.
Tout d'abord, nous avons essayé d'utiliser une LUT, dont les échantillons ont été générés en utilisant ce site (100 échantillons, amplitude = 250). Cela comprend une seule période.
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};
La largeur de l'impulsion suivante est calculée à chaque cycle PWM:
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(;;);
}
Lorsque vous le branchez dans la portée, nous obtenons le signal suivant. Nous ne pouvons pas éviter cet étrange pic proche du minimum.
En zoomant autour de ce pic, nous pouvons voir comment la sortie PWM (vers le haut) est en fait incorrecte.
Ainsi, après avoir gâché pendant un certain temps et être incapable de s'en débarrasser, nous avons essayé de calculer le signal sinusoïdal dans le MCU, au lieu de coder en dur la valeur de chaque échantillon. Nous avons ajouté le code suivant dans la fonction principale, juste avant toute la configuration du compteur:
for(i=0;i<99;i++) {
temp=100*(sin(2*3.14159*i/100)+1);
seno[i]=(int)temp;
}
Mais les résultats ne ressemblent même pas à une sinusoïde:
Après des heures de lutte, nous n'avons pas pu trouver notre erreur. Nous apprécierions un conseil.