Мы не можем правильно генерировать синусоидальный сигнал с помощью микроконтроллера MC68HC908GP32 . Описание ШИМ начинается на стр. 349. Тактовая частота составляет 2,4 МГц, в то время как мы использовали ШИМ 7 кГц, используя прескалер и установив таймер по модулю 350 следующим образом:
T1SC = 0x60; // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01; // High
T1MODL = 0x5E; // Low
Выход ШИМ фильтруется следующим RLC-фильтром, а затем постоянный ток удаляется с помощью колпачка серии 1 мкФ. Частота среза намного ниже 7 кГц ШИМ.
Сначала мы попытались использовать LUT, образцы которого были сгенерированы с использованием этого сайта (100 образцов, амплитуда = 250). Это включает в себя один период.
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};
Ширина следующего импульса вычисляется каждый цикл ШИМ:
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(;;);
}
Когда подключаем его в прицел, мы получаем следующий сигнал. Мы не можем избежать этого странного пика вблизи минимума.
При масштабировании вокруг этого пика мы можем видеть, как на самом деле выход ШИМ (вверх) неверен.
Итак, после недолгой разминки и неспособности избавиться от нее, мы попытались вычислить синусоидальный сигнал в MCU вместо жесткого кодирования значения для каждой выборки. Мы добавили следующий код в основную функцию непосредственно перед настройкой счетчика:
for(i=0;i<99;i++) {
temp=100*(sin(2*3.14159*i/100)+1);
seno[i]=(int)temp;
}
Но результаты даже не похожи на синусоиду:
После нескольких часов борьбы мы не смогли найти свою ошибку. Мы были бы признательны за совет.