Ми не можемо генерувати синусоїду належним чином за допомогою мікроконтролера MC68HC908GP32 . Опис ШІМ починається на сторінці 349. Тактова частота становить 2,4 МГц, тоді як ми використовували ШІМ 7 кГц за допомогою докалера та встановивши модуль таймера на 350 таким чином:
T1SC = 0x60; // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01; // High
T1MODL = 0x5E; // Low
Вихід ШІМ фільтрується за допомогою наступного фільтра RLC, а потім постійний струм видаляється за допомогою кришки серії 1uF. Частота відсікання значно нижче 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;
}
Але результати навіть не схожі на синусоїду:
Після години боротьби з ним ми не змогли знайти свою помилку. Ми будемо вдячні за пораду.