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