I use the code
// RCArduino DDS Sinewave for Arduino Due
// RCArduino DDS Sinewave by RCArduino is licensed under a Creative Commons Attribution 3.0 Unported License.
// Based on a work at rcarduino.blogspot.com.
// For helpful background information on Arduino Due Timer Configuration, refer to the following link
// thanks to Sebastian Vik
// http://arduino.cc/forum/index.php?action=post;topic=130423.15;num_replies=20
// For background information on the DDS Technique see
// http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/
// For audio sketches making extensive use of DDS Techniques, search the RCArduino Blog
// for the tags Audio or synth
// These are the clock frequencies available to the timers /2,/8,/32,/128
// 84Mhz/2 = 42.000 MHz
// 84Mhz/8 = 10.500 MHz
// 84Mhz/32 = 2.625 MHz
// 84Mhz/128 = 656.250 KHz
//
// 44.1Khz = CD Sample Rate
// Lets aim for as close to the CD Sample Rate as we can get -
//
// 42Mhz/44.1Khz = 952.38
// 10.5Mhz/44.1Khz = 238.09 // best fit divide by 8 = TIMER_CLOCK2 and 238 ticks per sample
// 2.625Hmz/44.1Khz = 59.5
// 656Khz/44.1Khz = 14.88
// 84Mhz/44.1Khz = 1904 instructions per tick
// the phase accumulator points to the current sample in our wavetable
uint32_t ulPhaseAccumulator = 0;
// the phase increment controls the rate at which we move through the wave table
// higher values = higher frequencies
volatile uint32_t ulPhaseIncrement = 0; // 32 bit phase increment, see below
// full waveform = 0 to SAMPLES_PER_CYCLE
// Phase Increment for 1 Hz =(SAMPLES_PER_CYCLE_FIXEDPOINT/SAMPLE_RATE) = 1Hz
// Phase Increment for frequency F = (SAMPLES_PER_CYCLE/SAMPLE_RATE)*F
#define SAMPLE_RATE 5000.0
#define SAMPLES_PER_CYCLE 2000
#define SAMPLES_PER_CYCLE_FIXEDPOINT (SAMPLES_PER_CYCLE<<20)
#define TICKS_PER_CYCLE (float)((float)SAMPLES_PER_CYCLE_FIXEDPOINT/(float)SAMPLE_RATE)
// to represent 600 we need 10 bits
// Our fixed point format will be 10P22 = 32 bits
// We have 521K flash and 96K ram to play with
// Create a table to hold the phase increments we need to generate midi note frequencies at our 44.1Khz sample rate
#define MIDI_NOTES 1000
uint32_t nMidiPhaseIncrement[MIDI_NOTES];
// fill the note table with the phase increment values we require to generate the note
void createNoteTable(float fSampleRate)
{
for(uint32_t unMidiNote = 0;unMidiNote < MIDI_NOTES;unMidiNote++)
{
// Correct calculation for frequency
Serial.print(unMidiNote);
Serial.print(" ");
float fFrequency = ((pow(2.0,(unMidiNote)/12)) * 2.0);
Serial.print(fFrequency);
Serial.print(" ");
nMidiPhaseIncrement[unMidiNote] = fFrequency*TICKS_PER_CYCLE*10;
Serial.println(nMidiPhaseIncrement[unMidiNote]);
}
}
// Create a table to hold pre computed sinewave, the table has a resolution of 600 samples
#define WAVE_SAMPLES 2000
// default int is 32 bit, in most cases its best to use uint32_t but for large arrays its better to use smaller
// data types if possible, here we are storing 12 bit samples in 16 bit ints
uint16_t nSineTable[WAVE_SAMPLES];
// create the individual samples for our sinewave table
void createSineTable()
{
for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++)
{
// normalised to 12 bit range 0-4095
nSineTable[nIndex] = (uint16_t) (((1+sin(((2.0*PI)/WAVE_SAMPLES)*nIndex))*4095.0)/2);
Serial.println(nSineTable[nIndex]);
}
}
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2);
uint32_t rc = VARIANT_MCK/8/frequency; //128 because we selected TIMER_CLOCK4 above
TC_SetRA(tc, channel, 32/2); //50% high, 50% low
TC_SetRC(tc, channel, 16);
TC_Start(tc, channel);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_EnableIRQ(irq);
analogWrite(DAC0,0);
}
void setup()
{
Serial.begin(9600);
createNoteTable(SAMPLE_RATE);
createSineTable();
startTimer(TC1, 1, TC4_IRQn, 1);
// this is a cheat - enable the DAC
}
void loop()
{
// read analog input 0 drop the range from 0-1024 to 0-127 with a right shift 3 places,
// then look up the phaseIncrement required to generate the note in our nMidiPhaseIncrement table
uint32_t ulInput = analogRead(0);
ulPhaseIncrement = nMidiPhaseIncrement[ulInput>>3];
}
void TC4_Handler()
{
// We need to get the status to clear it and allow the interrupt to fire again
TC_GetStatus(TC1, 1);
ulPhaseAccumulator += ulPhaseIncrement; // 32 bit phase increment, see below
// if the phase accumulator over flows - we have been through one cycle at the current pitch,
// now we need to reset the grains ready for our next cycle
if(ulPhaseAccumulator > SAMPLES_PER_CYCLE_FIXEDPOINT)
{
// DB 02/Jan/2012 - carry the remainder of the phase accumulator
ulPhaseAccumulator -= SAMPLEAS_PER_CYCLE_FIXEDPOINT;
}
// get the current sample
uint32_t ulOutput = nSineTable[ulPhaseAccumulator>>20];
// we cheated and user analogWrite to enable the dac, but here we want to be fast so
// write directly
dacc_write_conversion_data(DACC_INTERFACE, ulOutput);
}
I didn`t know how to set Frequency?
PS.Frequency rate: 20khz~200khz