5
\$\begingroup\$

I'm using an AVR Mega 168 to generate a sine wave via pulse width modulation. My goal is to generate a sine wave with a frequency of approximately 50 Hz. I understand that the PWM frequency needs to be as fast possible so its easier to attenuate in the filter.

So far, my µC is running at 8 MHz using the internal RC oscillator (I plan on moving to a crystal later on - taking this one step a time). This provides me with a maximum PWM base frequency of 8x106/256 (fast PWM mode) = 31.25 kHz.

My program updates the duty cycle whenever timer0 overflows i.e. every 32 µS (I think... since 1/31250 = 32 µS).

My question now is, how can I 'control' the frequency of the actual sine wave? I can easily slow down by prescaling but that would obviously make the base frequency quite low.

I have included my code below:

uint8_t i=0;


int main(void)
{
     int ipwm;

     DDRD = 0xFF;

     TCCR0A = 0b10000011;
     TCCR0B = (1 << WGM12);

     TIMSK0 |= (1 << TOIE0);
     TIFR1 |= (1 << OCF0A);
     TCCR0B = (1 << CS10);
     TCNT0 = 0;

     OCR0A = 128;

     sei();

     for(;;)
     {

     }

     return 1;
}

 ISR(TIMER0_OVF_vect)
 {
    OCR0A=pgm_read_byte(&sinewave[i]); // update duty cycle
    i++;
 }
\$\endgroup\$

1 Answer 1

12
\$\begingroup\$

The 31.25kHz is 625x your 50Hz. So all you have to do is build a 625 entries sine lookup table, and at each interrupt set your output compare value to the next table entry. If you have a 32\$\mu\$s interrupt you'll have ran over the full table (=full sine cycle) every 625 x 32\$\mu\$s = 20ms, so that will be your 50Hz.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you! Just generated 625 values and the frequency is now 50Hz (I measured using my DMM). \$\endgroup\$
    – Saad
    Commented Aug 16, 2011 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.