diff --git a/DDS.cpp b/DDS.cpp index 8d0c02b..b4cf79e 100644 --- a/DDS.cpp +++ b/DDS.cpp @@ -42,8 +42,8 @@ void DDS::start() { // clock as the DDS. TCCR1B = _BV(CS11) | _BV(WGM13) | _BV(WGM12); TCCR1A = 0; - //ICR1 = ((F_CPU / 8) / refclk) - 1; - ICR1 = ((F_CPU / 8) / 9600) - 1; + ICR1 = ((F_CPU / 8) / refclk) - 1; + //ICR1 = ((F_CPU / 8) / 9600) - 1; // Configure the ADC here to automatically run and be triggered off Timer1 ADMUX = _BV(REFS0) | _BV(ADLAR) | 0; // Channel 0, shift result left (ADCH used) @@ -77,8 +77,21 @@ void DDS::setFrequency(unsigned short freq) { } } +// Degrees should be between -360 and +360 (others don't make much sense) +void DDS::setPhaseDeg(int16_t degrees) { + accumulator = degrees * (pow(2,ACCUMULATOR_BITS)/360.0); +} +void DDS::changePhaseDeg(int16_t degrees) { + accumulator += degrees * (pow(2,ACCUMULATOR_BITS)/360.0); +} + // TODO: Clean this up a bit.. void DDS::clockTick() { +/* if(running) { + accumulator += stepRate; + OCR2A = getDutyCycle(); + } + return;*/ if(running) { accumulator += stepRate; if(timeLimited && tickDuration == 0) { @@ -129,5 +142,7 @@ uint8_t DDS::getDutyCycle() { phAng = (accumulator >> ACCUMULATOR_BIT_SHIFT); uint8_t position = pgm_read_byte_near(ddsSineTable + phAng)>>(8-COMPARATOR_BITS); // Apply scaling and return - return position >> amplitude; + uint16_t scaled = position; + scaled *= amplitude; + return scaled>>8; } diff --git a/DDS.h b/DDS.h index 54199a4..e18f1e9 100644 --- a/DDS.h +++ b/DDS.h @@ -42,7 +42,7 @@ // This is how often we'll perform a phase advance, as well as ADC sampling // rate. The higher this value, the smoother the output wave will be, at the // expense of CPU time. It maxes out around 62000 (TBD) -#define DDS_REFCLK_DEFAULT 9600 +#define DDS_REFCLK_DEFAULT 38400 // As each Arduino crystal is a little different, this can be fine tuned to // provide more accurate frequencies. Adjustments in the range of hundreds // is a good start. @@ -193,10 +193,16 @@ public: // frequency supported will fit in a short. void setFrequency(unsigned short freq); + // Handle phase shifts + void setPhaseDeg(int16_t degrees); + void changePhaseDeg(int16_t degrees); + // Adjustable reference clock. This shoud be done before the timers are // started, or they will need to be restarted. Frequencies will need to // be set again to use the new clock. - void setReferenceClock(unsigned long ref); + void setReferenceClock(unsigned long ref) { + refclk = ref; + } unsigned long getReferenceClock() { return refclk; } @@ -206,7 +212,7 @@ public: // Set a scaling factor. To keep things quick, this is a power of 2 value. // Set it with 0 for lowest (which will be off), 8 is highest. void setAmplitude(unsigned char amp) { - amplitude = 8 - amp; + amplitude = amp; } // This is the function called by the ADC_vect ISR to produce the tones