summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Geldenhuis <andre@team9.99.org.nz>2012-04-04 20:36:01 +1200
committerAndre Geldenhuis <andre@team9.99.org.nz>2012-04-04 20:36:01 +1200
commitbcfb325adf5264a04fd726d2591304c417c70618 (patch)
tree5bde15792d31df2c2bf43e3732d628c15ec4c2eb
parentdb17870dc10cd3e5fe011d0344ced36e8ac62b6f (diff)
downloadDDS-bcfb325adf5264a04fd726d2591304c417c70618.tar.gz
DDS-bcfb325adf5264a04fd726d2591304c417c70618.tar.bz2
DDS-bcfb325adf5264a04fd726d2591304c417c70618.zip
create genwave to create arbitrary wavetables of arbirary length. It auto write the wave table header file and neccessary variables
-rw-r--r--DDS.cpp39
-rw-r--r--DDS.h4
-rw-r--r--genwave.py69
3 files changed, 100 insertions, 12 deletions
diff --git a/DDS.cpp b/DDS.cpp
index 09a2e0d..7fbd1c3 100644
--- a/DDS.cpp
+++ b/DDS.cpp
@@ -26,35 +26,37 @@
// Kunsthochschule fuer Medien Koeln
// Academy of Media Arts Cologne
+//Note to improve performance make sure to picka frequency which is not a multiple of the clock frequency.
+
#include "WProgram.h"
#include "DDS.h"
+#include "wavetable.h"
-// table of 256 sine values / one sine period / stored in flash memory
-PROGMEM prog_uchar sine256[] = {
- 127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
- 242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
- 221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
- 76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
- 33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
-
-};
//start and stop timers for DDS alorithm
#define disableT(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define enableT(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+
+
//double dfreq;
// const double refclk=31372.549; // =16MHz / 510
//scope measurement 31.39717425
const double refclk=31397.2; // measured
// variables used inside interrupt service declared as volatile
-volatile byte icnt; // var inside interrupt
+volatile int icnt; // var inside interrupt
volatile byte icnt1; // var inside interrupt
extern volatile unsigned long c4ms=0; // counter incremented all 4ms
volatile unsigned long phaccu; // phase accumulator
volatile unsigned long tword_m; // dds tuning word m
+
+unsigned int ddsrand;
+volatile unsigned char randloc;
+
+volatile char ditherbit;
+
DDS::DDS()
{
@@ -67,6 +69,8 @@ DDS::DDS()
//activate outputs on D11
pinMode(11, OUTPUT);
pinMode(7,OUTPUT);
+ ddsrand=random(MAXRANDOM);
+ randloc=0;
}
@@ -76,6 +80,11 @@ void DDS::SetFreq(double inputfreq)
}
+void DDS::ReRand(){
+ ddsrand=random(MAXRANDOM);
+
+}
+
void DDS::initTimers(){
// Timer2 Clock Prescaler to : 1
enableT (TCCR2B, CS20);
@@ -115,9 +124,15 @@ ISR(TIMER2_OVF_vect) {
enableT(PORTD,7); // Test / set PORTD,7 high to observe timing with a oscope
phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits
- icnt=phaccu >> 24; // use upper 8 bits for phase accu as frequency information
+ icnt=phaccu >> truncval; // use upper 8 bits for phase accu as frequency information
// read value fron ROM sine table and send to PWM DAC
- OCR2A=pgm_read_byte_near(sine256 + icnt);
+
+ ditherbit=bitRead(ddsrand,randloc++);
+ if(randloc>15){
+ randloc=0;
+ }
+ //OCR2A=(pgm_read_byte_near(sine256 + icnt))^ditherbit;
+ OCR2A=(pgm_read_byte_near(sine256 + icnt));
//icnt1=icnt1+1;
diff --git a/DDS.h b/DDS.h
index a0f4d20..0dcaf38 100644
--- a/DDS.h
+++ b/DDS.h
@@ -32,6 +32,8 @@
#include "WProgram.h"
#include <avr/pgmspace.h>
+#define MAXRANDOM 65536
+
class DDS
{
public:
@@ -39,8 +41,10 @@ class DDS
void initTimers();
void SetDDSTimers(byte enableCom);
void SetFreq(double inputfreq);
+ void ReRand(void);
//volatile unsigned long c4ms;
volatile byte icnt1;
volatile byte test;
+
};
#endif
diff --git a/genwave.py b/genwave.py
new file mode 100644
index 0000000..77e53bc
--- /dev/null
+++ b/genwave.py
@@ -0,0 +1,69 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+freespace=24000*10 #the amount of flash sapce available for the lookuptable
+elementsize=8 #size of each element in the wave table in bits, probabably 8, 16 or 32 bits
+phaccu_len=32
+
+fileout="wavetable.h"
+fileoutwidth=70 #how far to write the output table before line breaks
+for i in range(8,32):
+ requiredspace=(2**i)*elementsize
+ if (requiredspace>freespace):
+ tablelength=i-1
+ requiredspace=(2**tablelength)*elementsize
+ break
+truncval=phaccu_len-tablelength
+print "wave table length is {} bits. Phase Accumulator will be truncated by {}\nIt will consume {} bytes".format(tablelength,truncval,requiredspace)
+#calculate array size based on available space. do this in a cheap and cheerful way
+
+
+arrayS=2**tablelength
+AoutRes=255 #pwm output res
+halfAout=int(AoutRes/2.)
+x=np.linspace(-np.pi,np.pi,arrayS)
+sinwave=127*(np.cos(x+np.pi/2.))
+sinwave=sinwave+127
+sinwaveint=[]
+for i in range(0,len(sinwave)):
+ sinwaveint.append(int(sinwave[i]))
+
+
+plt.plot(sinwaveint)
+plt.show()
+
+
+
+testwave=[
+ 127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
+ 242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
+ 221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
+ 76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
+ 33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
+]
+
+#~
+#~ stringwave=str(sinwaveint)
+#~ stringwave=stringwave.replace(" ","")
+
+f=open(fileout,'w')
+f.write("#ifndef wavetable_h\n#define wavetable_h\n")
+f.write("// table of {} sine values of {} bit resolution\n\n".format(tablelength,elementsize))
+f.write("const char truncval = {};\n".format(truncval))
+f.write("PROGMEM prog_uchar sine256[] = {\n")
+
+
+widthcounter=0
+for i in range(0,len(sinwaveint)-1): #every element but the last
+ thisstr=str(sinwaveint[i]) + ","
+
+ widthcounter=widthcounter+len(thisstr)
+ if(widthcounter>fileoutwidth):
+ f.write("\n")
+ widthcounter=0
+ f.write(thisstr)
+f.write(str(sinwaveint[-1])) #write the last element, no comma
+f.write("};\n\n")
+f.write("#endif")
+f.close()
+