Change 'Use Timer 2 Only' from compile option to software option
This commit is contained in:
parent
2e3955fa80
commit
6f4d8a93c5
|
@ -16,6 +16,7 @@ void setup() {
|
|||
digitalWrite(PWM_PIN, LOW);
|
||||
|
||||
dds.start();
|
||||
dds.startPhaseAccumulator(false);
|
||||
dds.playWait(600, 3000);
|
||||
dds.on();
|
||||
//dds.setAmplitude(31);
|
||||
|
@ -38,4 +39,4 @@ ISR(ADC_vect) {
|
|||
}
|
||||
dds.clockTick();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
68
src/DDS.cpp
68
src/DDS.cpp
|
@ -13,6 +13,7 @@ void DDS::start() {
|
|||
#ifdef DDS_PWM_PIN_3
|
||||
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0)) |
|
||||
_BV(WGM21) | _BV(WGM20);
|
||||
//TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20) | _BV(WGM22);
|
||||
TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20) | _BV(WGM22);
|
||||
#else
|
||||
// Alternatively, use pin 11
|
||||
|
@ -33,42 +34,49 @@ void DDS::start() {
|
|||
OCR2A = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DDS_USE_ONLY_TIMER2
|
||||
TIMSK2 |= _BV(TOIE2);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Second, setup Timer1 to trigger the ADC interrupt
|
||||
// This lets us use decoding functions that run at the same reference
|
||||
// clock as the DDS.
|
||||
// We use ICR1 as TOP and prescale by 8
|
||||
/* TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
|
||||
TCCR1A = 0;
|
||||
ICR1 = ((F_CPU / 1) / refclk) - 1;
|
||||
#ifdef DDS_DEBUG_SERIAL
|
||||
Serial.print(F("DDS SysClk: "));
|
||||
Serial.println(F_CPU/8);
|
||||
Serial.print(F("DDS RefClk: "));
|
||||
Serial.println(refclk, DEC);
|
||||
Serial.print(F("DDS ICR1: "));
|
||||
Serial.println(ICR1, DEC);
|
||||
#endif
|
||||
if(!timer2only){
|
||||
TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
|
||||
TCCR1A = 0;
|
||||
ICR1 = ((F_CPU / 1) / refclk) - 1;
|
||||
#ifdef DDS_DEBUG_SERIAL
|
||||
Serial.print(F("DDS SysClk: "));
|
||||
Serial.println(F_CPU/8);
|
||||
Serial.print(F("DDS RefClk: "));
|
||||
Serial.println(refclk, DEC);
|
||||
Serial.print(F("DDS ICR1: "));
|
||||
Serial.println(ICR1, DEC);
|
||||
#endif
|
||||
|
||||
// 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)
|
||||
DDRC &= ~_BV(0);
|
||||
PORTC &= ~_BV(0);
|
||||
DIDR0 |= _BV(0);
|
||||
ADCSRB = _BV(ADTS2) | _BV(ADTS1) | _BV(ADTS0);
|
||||
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;
|
||||
ADMUX = _BV(REFS0) | _BV(ADLAR) | 0; // Channel 0, shift result left (ADCH used)
|
||||
DDRC &= ~_BV(0);
|
||||
PORTC &= ~_BV(0);
|
||||
DIDR0 |= _BV(0);
|
||||
ADCSRB = _BV(ADTS2) | _BV(ADTS1) | _BV(ADTS0);
|
||||
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2); // | _BV(ADPS0);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
} else if (freq == 600) {
|
||||
newStep = (600.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS);
|
||||
} else {
|
||||
newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset);
|
||||
}
|
||||
} else {
|
||||
newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// 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 DDS_USE_ONLY_TIMER2
|
||||
//#define DDS_USE_ONLY_TIMER2
|
||||
|
||||
// Use a short (16 bit) accumulator. Phase accuracy is reduced, but speed
|
||||
// is increased, along with a reduction in memory use.
|
||||
|
@ -133,7 +133,7 @@ class DDS {
|
|||
public:
|
||||
DDS(): refclk(DDS_REFCLK_DEFAULT), refclkOffset(DDS_REFCLK_OFFSET),
|
||||
accumulator(0), running(false),
|
||||
timeLimited(false), tickDuration(0), amplitude(255)
|
||||
timeLimited(false), tickDuration(0), amplitude(255), timer2only(false)
|
||||
{};
|
||||
|
||||
// Start all of the timers needed
|
||||
|
@ -142,6 +142,9 @@ public:
|
|||
const bool isRunning() { return running; };
|
||||
// Stop the DDS timers
|
||||
void stop();
|
||||
// Start the phase accumulator
|
||||
void startPhaseAccumulator(bool use_only_timer_2 = false);
|
||||
bool isTimer2Only() { return timer2only; };
|
||||
|
||||
// Start and stop the PWM output
|
||||
void on() {
|
||||
|
@ -214,6 +217,7 @@ public:
|
|||
void clockTick();
|
||||
|
||||
private:
|
||||
volatile bool timer2only;
|
||||
volatile bool running;
|
||||
volatile unsigned long tickDuration;
|
||||
volatile bool timeLimited;
|
||||
|
|
Loading…
Reference in New Issue