Allow for high idle duty cycle when output is 'off', amplitude adjustments.

This commit is contained in:
Stephen Olesen 2015-07-01 14:27:10 -06:00
parent 1117542411
commit 31eb465ebf
2 changed files with 31 additions and 13 deletions

14
DDS.cpp
View File

@ -61,22 +61,30 @@ void DDS::clockTick() {
accumulator += stepRate; accumulator += stepRate;
if(running) { if(running) {
if(tickDuration == 0) { if(tickDuration == 0) {
#ifdef DDS_IDLE_HIGH
// Set the duty cycle to 50%
OCR2B = pow(2,COMPARATOR_BITS)/2;
#else
// Set duty cycle to 0, effectively off
OCR2B = 0; OCR2B = 0;
#endif
running = false; running = false;
} else { } else {
OCR2B = getPhaseAngle(); OCR2B = getDutyCycle();
} }
// Reduce our playback duration by one tick // Reduce our playback duration by one tick
tickDuration--; tickDuration--;
} }
} }
uint8_t DDS::getPhaseAngle() { uint8_t DDS::getDutyCycle() {
#if ACCUMULATOR_BIT_SHIFT >= 24 #if ACCUMULATOR_BIT_SHIFT >= 24
uint16_t phAng; uint16_t phAng;
#else #else
uint8_t phAng; uint8_t phAng;
#endif #endif
phAng = (accumulator >> ACCUMULATOR_BIT_SHIFT); phAng = (accumulator >> ACCUMULATOR_BIT_SHIFT);
return pgm_read_byte_near(ddsSineTable + phAng)>>(8-COMPARATOR_BITS); uint8_t position = pgm_read_byte_near(ddsSineTable + phAng)>>(8-COMPARATOR_BITS);
// Apply scaling and return
return position >> amplitude;
} }

30
DDS.h
View File

@ -11,6 +11,10 @@
#define ACCUMULATOR_BITS 32 #define ACCUMULATOR_BITS 32
#endif #endif
// If defined, the timer will idle at 50% duty cycle
// This leaves it floating in the centre of the PWM/DAC voltage range
#define DDS_IDLE_HIGH
#define COMPARATOR_BITS 6 #define COMPARATOR_BITS 6
#define DDS_REFCLK_DEAULT 38400 #define DDS_REFCLK_DEAULT 38400
@ -123,7 +127,7 @@ public:
void on(unsigned short duration) { void on(unsigned short duration) {
// Duration in ticks from milliseconds is: // Duration in ticks from milliseconds is:
// t = (1/refclk) // t = (1/refclk)
tickDuration = duration / (1000.0/refclk); tickDuration = (duration * refclk) / 1000;
running = true; running = true;
} }
void off() { void off() {
@ -137,8 +141,7 @@ public:
} }
// Blocking version // Blocking version
void playWait(unsigned short freq, unsigned short duration) { void playWait(unsigned short freq, unsigned short duration) {
setFrequency(freq); play(freq, duration);
on(duration);
delay(duration * 1000); delay(duration * 1000);
} }
@ -149,20 +152,27 @@ public:
// Adjustable reference clock // Adjustable reference clock
void setReferenceClock(unsigned long ref); void setReferenceClock(unsigned long ref);
uint8_t getPhaseAngle(); uint8_t getDutyCycle();
// 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;
}
void clockTick(); void clockTick();
private: private:
bool running; volatile bool running;
unsigned long tickDuration; volatile unsigned long tickDuration;
volatile unsigned char amplitude;
#ifdef SHORT_ACCUMULATOR #ifdef SHORT_ACCUMULATOR
unsigned short accumulator; volatile unsigned short accumulator;
unsigned short stepRate; volatile unsigned short stepRate;
unsigned short refclk; unsigned short refclk;
#else #else
unsigned long accumulator; volatile unsigned long accumulator;
unsigned long stepRate; volatile unsigned long stepRate;
unsigned long refclk; unsigned long refclk;
#endif #endif
static DDS *sDDS; static DDS *sDDS;