/* Sinussignalerzeugung mittels DDS Ausgabe von zwei Sinussignalen mit vaiabler Frequenz, Amplitude und Phase mittels PWM Auflösung der Variablen R(frequenz) : F_PWM / 2^16 = 62,5kHz / 65536 = 0,95367Hz R(phase) : 360° / 256 = 1,4° = 0,025 rad R(amplitude): 1 / 256 = 0,39% */ #include #define F_PWM 62500L // Hz #define PRESCALER 1 #define TIMER_RELOAD ((F_CPU / ( PRESCALER * F_PWM) -1)) // Fast PWM #define DELAY 20 // ms, Pause für Zwischenschritte im Demo #define LOOPS 1 // Anzahl Schleifen pro Modulationsdemo // Variablen volatile uint16_t frequenz; volatile uint8_t amplitude, phase; const int8_t sinus[256] PROGMEM = { 0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116, 117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 125, 125, 124, 123, 122, 122, 121, 120, 118, 117, 116, 115, 113, 112, 111, 109, 107, 106, 104, 102, 100, 98, 96, 94, 92, 90, 88, 85, 83, 81, 78, 76, 73, 71, 68, 65, 63, 60, 57, 54, 51, 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 12, 9, 6, 3, 0, -3, -6, -9, -12, -16, -19, -22, -25, -28, -31, -34, -37, -40, -43, -46, -49, -51, -54, -57, -60, -63, -65, -68, -71, -73, -76, -78, -81, -83, -85, -88, -90, -92, -94, -96, -98, -100, -102, -104, -106, -107, -109, -111, -112, -113, -115, -116, -117, -118, -120, -121, -122, -122, -123, -124, -125, -125, -126, -126, -126, -127, -127, -127, -127, -127, -127, -127, -126, -126, -126, -125, -125, -124, -123, -122, -122, -121, -120, -118, -117, -116, -115, -113, -112, -111, -109, -107, -106, -104, -102, -100, -98, -96, -94, -92, -90, -88, -85, -83, -81, -78, -76, -73, -71, -68, -65, -63, -60, -57, -54, -51, -49, -46, -43, -40, -37, -34, -31, -28, -25, -22, -19, -16, -12, -9, -6, -3, }; void setup(){ pinMode(A0,INPUT); pinMode(11,OUTPUT); // OCR1A pinMode(12,OUTPUT); // OCR1B // Timer1 initialisieren // Mode 14, Fast PWM (ICR1), nichtinvertierte PWM, Prescaler 1 // OCR1A, OCR1B aktiv TCCR1A = (1<0; j--) { amplitude = j; delay(DELAY); } } amplitude = 255; // Frequenzmodulation for (i=0; i0; j--) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { frequenz = 256+2*j; } delay(DELAY); } } ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { frequenz = 256; } // Phasenmodulation von OCR1B for (i=0; i0; j--) { phase = j; delay(DELAY); } } phase = 0; } // Interrupt für Timer 1, Frequenz F_PWM // Nachladen der PWM ISR(TIMER1_CAPT_vect) { // Index für Sinustabelle, Festkommazahl, 8 Bit Vorkomma, 8 Bit Nachkomma static uint16_t i; i += frequenz; OCR1A = 128+(((int8_t)pgm_read_byte(&sinus[i>>8])*(int16_t)amplitude)>>8); OCR1B = 128+(((int8_t)pgm_read_byte(&sinus[((i>>8)+phase) & 0xFF])*(int16_t)amplitude)>>8); }