I wrote a minimal project template for a DDS explained in the video lecture.
C:
#include io.h> #include delay.h> #include #include #define F_CPU 16000000 // 16Mhz system clock // Sine lookup-table. One full cycle. volatile int8_t sineTable[256]; // Accumulator (signal phase) for Direct Digital Synthesis (DDS) volatile uint16_t accumulator; // Increment value for DDS. This defines the signal frequency volatile uint16_t increment; void main(void) { // Initialize the sine table for (int i=0; i256.0)); } // TODO 1 /* Setup 8bit PWM. Rest of the code assumes that duty cycle is defined by OCR register. Values [0, 255] */ // .. initialization omitted // TODO 2 /* Setup interrupt for duty cycle update. ISR must execute at constant frequency Fs */ // .. initialization omitted /* Calculate increment for constant sine frequency */ // increment = (Frequency*(2^16)) / Fs; /* Infinite loop */ for(;;) { } } /******************************************************************************/ /* Interrupt service routine executes at constant frequency. (sine wave sample frequency). Do not confuse this with pwm frequency. */ ISR() { accumulator += increment; // Increment accumulator OCR = 128 + sineTable[accumulator>>8]; // Update PWM duty cycle } /******************************************************************************/
If you want to output 3 sine waves with 120 phase shift, then the ISR becomes something like: (You will have to setup 3-channel PWM, of course)
C:
/* Interrupt service routine executes at constant frequency. (sine wave sample frequency). Do not confuse this with pwm frequency. */ ISR() { accumulator += increment; // Increment accumulator // PWM Channel A 0-phase OCRA = 128 + sineTable[accumulator>>8]; // Update PWM duty cycle // PWM Channel B 120-phase OCRB = 128 + sineTable[(accumulator+21845)>>8]; // Update PWM duty cycle // PWM Channel C 240-phase OCRC = 128 + sineTable[(accumulator+43691)>>8]; // Update PWM duty cycle } /******************************************************************************/