DDS using ATmega328.
50 Hz sine and 100 Hz rectified sine
Output is PWM so a low pass filter is required.
#include <xc.h>
static int8_t const st[1 << 9] = {
0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 17, 18, 20, 21, 23,
24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45, 47,
48, 50, 51, 52, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69,
70, 71, 73, 74, 75, 76, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
89, 90, 91, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 102, 103, 104,
105, 106, 107, 108, 108, 109, 110, 111, 112, 112, 113, 114, 114, 115, 116, 116,
117, 117, 118, 119, 119, 120, 120, 121, 121, 121, 122, 122, 123, 123, 123, 124,
124, 124, 125, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 125, 125, 125, 125, 124,
124, 124, 123, 123, 123, 122, 122, 121, 121, 121, 120, 120, 119, 119, 118, 117,
117, 116, 116, 115, 114, 114, 113, 112, 112, 111, 110, 109, 108, 108, 107, 106,
105, 104, 103, 102, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 91, 90,
89, 88, 87, 86, 85, 84, 82, 81, 80, 79, 78, 76, 75, 74, 73, 71,
70, 69, 67, 66, 65, 63, 62, 61, 59, 58, 57, 55, 54, 52, 51, 50,
48, 47, 45, 44, 42, 41, 39, 38, 36, 35, 33, 32, 30, 29, 27, 26,
24, 23, 21, 20, 18, 17, 15, 13, 12, 10, 9, 7, 6, 4, 3, 1,
0, -1, -3, -4, -6, -7, -9, -10, -12, -13, -15, -17, -18, -20, -21, -23,
-24, -26, -27, -29, -30, -32, -33, -35, -36, -38, -39, -41, -42, -44, -45, -47,
-48, -50, -51, -52, -54, -55, -57, -58, -59, -61, -62, -63, -65, -66, -67, -69,
-70, -71, -73, -74, -75, -76, -78, -79, -80, -81, -82, -84, -85, -86, -87, -88,
-89, -90, -91, -93, -94, -95, -96, -97, -98, -99, -100, -101, -102, -102, -103, -104,
-105, -106, -107, -108, -108, -109, -110, -111, -112, -112, -113, -114, -114, -115, -116, -116,
-117, -117, -118, -119, -119, -120, -120, -121, -121, -121, -122, -122, -123, -123, -123, -124,
-124, -124, -125, -125, -125, -125, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
-126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -125, -125, -125, -125, -124,
-124, -124, -123, -123, -123, -122, -122, -121, -121, -121, -120, -120, -119, -119, -118, -117,
-117, -116, -116, -115, -114, -114, -113, -112, -112, -111, -110, -109, -108, -108, -107, -106,
-105, -104, -103, -102, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -91, -90,
-89, -88, -87, -86, -85, -84, -82, -81, -80, -79, -78, -76, -75, -74, -73, -71,
-70, -69, -67, -66, -65, -63, -62, -61, -59, -58, -57, -55, -54, -52, -51, -50,
-48, -47, -45, -44, -42, -41, -39, -38, -36, -35, -33, -32, -30, -29, -27, -26,
-24, -23, -21, -20, -18, -17, -15, -13, -12, -10, -9, -7, -6, -4, -3, -1
};
void __attribute__ ((signal, used, externally_visible)) TIMER1_CAPT_vect(void)
{
static uint16_t n;
OCR1A = 300 + st[n & 0x01FF]; // 50 Hz Sine
OCR1B = 300 + st[n & 0x00FF]; // 100 Hz Rectified sine
++n;
}
int main(void)
{
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x02;
DDRB = 0xFF;
DDRC = 0xFF;
DDRD = 0xFE;
TCCR1A = 0xA2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 625 - 1; // 16M / 512 / 50
OCR1A = OCR1B = 180;
TIFR1 = ~0;
TIMSK1 = 0x20;
__asm__ __volatile__ ("sei" ::: "memory");
for(;;);
return 0;
}