Change 'Use Timer 2 Only' from compile option to software option

This commit is contained in:
nick6x 2017-07-28 10:52:11 -07:00
parent 2e3955fa80
commit 6f4d8a93c5
3 changed files with 47 additions and 32 deletions

View File

@ -16,6 +16,7 @@ void setup() {
digitalWrite(PWM_PIN, LOW); digitalWrite(PWM_PIN, LOW);
dds.start(); dds.start();
dds.startPhaseAccumulator(false);
dds.playWait(600, 3000); dds.playWait(600, 3000);
dds.on(); dds.on();
//dds.setAmplitude(31); //dds.setAmplitude(31);

View File

@ -13,6 +13,7 @@ void DDS::start() {
#ifdef DDS_PWM_PIN_3 #ifdef DDS_PWM_PIN_3
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0)) | TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0)) |
_BV(WGM21) | _BV(WGM20); _BV(WGM21) | _BV(WGM20);
//TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20) | _BV(WGM22);
TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20) | _BV(WGM22); TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20) | _BV(WGM22);
#else #else
// Alternatively, use pin 11 // Alternatively, use pin 11
@ -33,25 +34,40 @@ void DDS::start() {
OCR2A = 0; OCR2A = 0;
#endif #endif
#ifdef DDS_USE_ONLY_TIMER2
}
void DDS::stop() {
// TODO: Stop the timers.
if(!timer2only){
TCCR1B = 0;
}
TCCR2B = 0;
}
void DDS::startPhaseAccumulator(bool use_only_timer_2 = false){
timer2only = use_only_timer_2;
if(timer2only){
TIMSK2 |= _BV(TOIE2); TIMSK2 |= _BV(TOIE2);
#endif }
// Second, setup Timer1 to trigger the ADC interrupt // Second, setup Timer1 to trigger the ADC interrupt
// This lets us use decoding functions that run at the same reference // This lets us use decoding functions that run at the same reference
// clock as the DDS. // clock as the DDS.
// We use ICR1 as TOP and prescale by 8 // We use ICR1 as TOP and prescale by 8
/* TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12); if(!timer2only){
TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
TCCR1A = 0; TCCR1A = 0;
ICR1 = ((F_CPU / 1) / refclk) - 1; ICR1 = ((F_CPU / 1) / refclk) - 1;
#ifdef DDS_DEBUG_SERIAL #ifdef DDS_DEBUG_SERIAL
Serial.print(F("DDS SysClk: ")); Serial.print(F("DDS SysClk: "));
Serial.println(F_CPU/8); Serial.println(F_CPU/8);
Serial.print(F("DDS RefClk: ")); Serial.print(F("DDS RefClk: "));
Serial.println(refclk, DEC); Serial.println(refclk, DEC);
Serial.print(F("DDS ICR1: ")); Serial.print(F("DDS ICR1: "));
Serial.println(ICR1, DEC); Serial.println(ICR1, DEC);
#endif #endif
// Configure the ADC here to automatically run and be triggered off Timer1 // 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) ADMUX = _BV(REFS0) | _BV(ADLAR) | 0; // Channel 0, shift result left (ADCH used)
@ -60,15 +76,7 @@ void DDS::start() {
DIDR0 |= _BV(0); DIDR0 |= _BV(0);
ADCSRB = _BV(ADTS2) | _BV(ADTS1) | _BV(ADTS0); ADCSRB = _BV(ADTS2) | _BV(ADTS1) | _BV(ADTS0);
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2); // | _BV(ADPS0); ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2); // | _BV(ADPS0);
*/ }
}
void DDS::stop() {
// TODO: Stop the timers.
#ifndef DDS_USE_ONLY_TIMER2
TCCR1B = 0;
#endif
TCCR2B = 0;
} }
// Set our current sine wave frequency in Hz // Set our current sine wave frequency in Hz
@ -88,6 +96,8 @@ ddsAccumulator_t DDS::calcFrequency(unsigned short freq) {
newStep = (1500.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS); newStep = (1500.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS);
} else if (freq == 600) { } else if (freq == 600) {
newStep = (600.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS); newStep = (600.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS);
} else {
newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset);
} }
} else { } else {
newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset); newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset);

View File

@ -10,7 +10,7 @@
// Normally, we turn on timer2 and timer1, and have ADC sampling as our clock // Normally, we turn on timer2 and timer1, and have ADC sampling as our clock
// Define this to only use Timer2, and not start the ADC clock // Define this to only use Timer2, and not start the ADC clock
// #define DDS_USE_ONLY_TIMER2 //#define DDS_USE_ONLY_TIMER2
// Use a short (16 bit) accumulator. Phase accuracy is reduced, but speed // Use a short (16 bit) accumulator. Phase accuracy is reduced, but speed
// is increased, along with a reduction in memory use. // is increased, along with a reduction in memory use.
@ -133,7 +133,7 @@ class DDS {
public: public:
DDS(): refclk(DDS_REFCLK_DEFAULT), refclkOffset(DDS_REFCLK_OFFSET), DDS(): refclk(DDS_REFCLK_DEFAULT), refclkOffset(DDS_REFCLK_OFFSET),
accumulator(0), running(false), accumulator(0), running(false),
timeLimited(false), tickDuration(0), amplitude(255) timeLimited(false), tickDuration(0), amplitude(255), timer2only(false)
{}; {};
// Start all of the timers needed // Start all of the timers needed
@ -142,6 +142,9 @@ public:
const bool isRunning() { return running; }; const bool isRunning() { return running; };
// Stop the DDS timers // Stop the DDS timers
void stop(); void stop();
// Start the phase accumulator
void startPhaseAccumulator(bool use_only_timer_2 = false);
bool isTimer2Only() { return timer2only; };
// Start and stop the PWM output // Start and stop the PWM output
void on() { void on() {
@ -214,6 +217,7 @@ public:
void clockTick(); void clockTick();
private: private:
volatile bool timer2only;
volatile bool running; volatile bool running;
volatile unsigned long tickDuration; volatile unsigned long tickDuration;
volatile bool timeLimited; volatile bool timeLimited;