/* Mehrfachpulsgenerator mittels DDS Ausgabe von vier Digitalsignalen mit variabler Frequenz und Phase Auflösung der Variablen R(frequenz) : F_TIMER / 2^16 = 6552Hz / 65536 = 0,1 Hz R(phase) : 360° / 256 = 1,4° = 0,025 rad */ #include #define F_TIMER 6552L // Hz #define PRESCALER 1 #define TIMER_RELOAD ((F_CPU / ( PRESCALER * F_TIMER) -1)) // Fast PWM // Variablen volatile uint16_t accu[4], frequenz[4]; volatile uint8_t phase[4]; // freq100mHz in 0,1 Hz, 0-(F_TIMER*10)/2 uint16_t setFrequency(uint16_t freq100mHz) { return ((uint32_t)freq100mHz<<16)/(F_TIMER*10); } // phaseDeg in Grad, 0-360 uint8_t setPhase(uint16_t phaseDeg) { return (phaseDeg * 256L) / 360; } // Reset des DDS Akkus muss atomar sein, damit die Phasenlage garantiert ist // Außerdem sind die Akkus 16 Bit und damit nicht atomar auf einem kleinen 8 Bit AVR // Erst Frequenz und Phase definieren, danach resetDDS() aufrufen void resetDDS(void) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { accu[0] = phase[0] << 8; accu[1] = phase[1] << 8; accu[2] = phase[2] << 8; accu[3] = phase[3] << 8; } } void setup(){ // zusammenliegende IOs in einem PORT wählen // muss manuell an Bits in ISR angepaßt werden // direkter IO Zugriff über Register ist deutlich schneller als digitalWrite() und digitalRead() pinMode(2, OUTPUT); // PD2 pinMode(3, OUTPUT); // PD3 pinMode(4, OUTPUT); // PD4 pinMode(5, OUTPUT); // PD5 // Timer1 initialisieren // Mode 14, Fast PWM (ICR1), nichtinvertierte PWM, Prescaler 1 TCCR1A = (1<