Compare commits

...

12 Commits

Author SHA1 Message Date
Morgan Redfield ec1fccf424
Merge pull request #6 from per1234/keywords-separator
Use correct field separator in keywords.txt
2018-08-04 18:13:20 -07:00
Morgan Redfield c2feff6816 update library keywords and properties 2018-08-04 18:12:16 -07:00
Morgan Redfield 95c808bb7f update keywords tabs 2018-08-04 13:39:06 -07:00
per1234 b66c2088b9
Use correct field separator in keywords.txt
The Arduino IDE requires the use of a single true tab separator between the keyword name and identifier. When spaces are used rather than a true tab the keyword is not highlighted.

Reference:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords
2018-07-15 22:26:20 -07:00
Morgan Redfield bcd6d7e6b3
Merge pull request #5 from per1234/remove-redundant-default-argument
Remove default argument from function definition
2018-03-07 21:41:25 -08:00
Nigel VH 0e8d42699a
Merge pull request #4 from per1234/arduino_h
#include Arduino.h dependency
2018-03-07 21:34:12 -08:00
per1234 3d476bf1c2
Remove default argument from function definition
Default arguments should only be specified in function prototypes, not in the function definition. This caused compilation of the library to fail for Arduino AVR Boards 1.6.11 or earlier. It does not cause compilation to fail for Arduino AVR Boards 1.6.12 and newer only because the -fpermissive compiler flag was added, which downgrades this to an error. It has been stated that flag may be removed in the future:
06868f4cd3
So this change is necessary for both backwards and forwards compatibility. Even with current versions it fixes a warning, which is always wise to do.
2018-03-07 21:32:24 -08:00
per1234 f9322214a9
#include Arduino.h dependency
Previously the library relied on the Arduino IDE doing the automatic insertion of #include <Arduino.h> in the sketch before #include <DDS.h>. In some IDE versions that does not happen and there is no guarantee of that behavior in future IDE versions thus for backwards and forwards compatibility it's best to simply add an #include directive to DDS.h.
2018-03-07 21:27:02 -08:00
nick6x 6726836631 Fix example 2017-07-30 12:07:00 -07:00
nick6x 7ebe201f96 Determine ISR on #define 2017-07-30 11:53:55 -07:00
nick6x c4daa7941b Fix examples isr 2017-07-28 16:16:10 -07:00
nick6x 6f4d8a93c5 Change 'Use Timer 2 Only' from compile option to software option 2017-07-28 10:52:11 -07:00
5 changed files with 86 additions and 50 deletions

View File

@ -9,6 +9,9 @@
#define PWM_PIN 3
#define DDS_USE_ONLY_TIMER2 true
#define TIMER2_PHASE_ADVANCE 24
DDS dds;
void setup() {
@ -16,6 +19,7 @@ void setup() {
digitalWrite(PWM_PIN, LOW);
dds.start();
dds.startPhaseAccumulator(DDS_USE_ONLY_TIMER2);
dds.playWait(600, 3000);
dds.on();
//dds.setAmplitude(31);
@ -25,9 +29,14 @@ void loop() {
dds.setFrequency(2200);
}
#ifdef DDS_USE_ONLY_TIMER2
#if DDS_USE_ONLY_TIMER2
ISR(TIMER2_OVF_vect) {
static unsigned char tcnt = 0;
if(++tcnt == TIMER2_PHASE_ADVANCE) {
tcnt = 0;
dds.clockTick();
}
}
#else // Use the ADC timer instead
ISR(ADC_vect) {

View File

@ -11,19 +11,31 @@ DDS KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
#begin KEYWORD2
#exists KEYWORD2
#mkdir KEYWORD2
#remove KEYWORD2
#rmdir KEYWORD2
#open KEYWORD2
#close KEYWORD2
#seek KEYWORD2
#position KEYWORD2
#size KEYWORD2
start KEYWORD2
isRunning KEYWORD2
stop KEYWORD2
startPhaseAccumulator KEYWORD2
isTimer2Only KEYWORD2
on KEYWORD2
off KEYWORD2
play KEYWORD2
playWait KEYWORD2
calcFrequency KEYWORD2
getPhaseAdvance KEYWORD2
setFrequency KEYWORD2
setPrecalcFrequency KEYWORD2
setPhaseDeg KEYWORD2
setAmplitude KEYWORD2
changePhaseDeg KEYWORD2
setReferenceClock KEYWORD2
getReferenceClock KEYWORD2
setReferenceOffset KEYWORD2
getReferenceOffset KEYWORD2
getDutyCycle KEYWORD2
clockTick KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
#FILE_READ LITERAL1
#FILE_WRITE LITERAL1

View File

@ -1,10 +1,10 @@
name=DDS
version=1.0.2
version=1.0.3
author=Morgan Redfield <morgan@enhancedradio.com>, Casey Halverson <casey@enhancedradio.com>
maintainer=Morgan Redfield <morgan@enhancedradio.com>
sentence=A library for use with HamShield by Enhanced Radio Devices.
sentence=Generate sinusoids on AVR-based Arduinos at varying frequencies. Requires an analog low-pass filter.
paragraph=
category=Device Control
category=Signal Input/Output
url=http://www.hamshield.com
architectures=*
architectures=avr
includes=DDS.h

View File

@ -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,25 +34,40 @@ void DDS::start() {
OCR2A = 0;
#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){
timer2only = use_only_timer_2;
if(timer2only){
TIMSK2 |= _BV(TOIE2);
#endif
}
// 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);
if(!timer2only){
TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
TCCR1A = 0;
ICR1 = ((F_CPU / 1) / refclk) - 1;
#ifdef DDS_DEBUG_SERIAL
#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
#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)
@ -60,15 +76,7 @@ void DDS::start() {
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;
}
}
// 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);

View File

@ -1,6 +1,7 @@
#ifndef _DDS_H_
#define _DDS_H_
#include <Arduino.h>
#include <avr/pgmspace.h>
// Use pin 3 for PWM? If not defined, use pin 11
@ -10,7 +11,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 +134,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 +143,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 +218,7 @@ public:
void clockTick();
private:
volatile bool timer2only;
volatile bool running;
volatile unsigned long tickDuration;
volatile bool timeLimited;