chipKIT® Development Platform

Inspired by Arduino™

Sinusoidal generator

Created Sun, 04 Sep 2011 16:33:26 +0000 by paoletto


paoletto

Sun, 04 Sep 2011 16:33:26 +0000

Hi all. My name is Paolo, from Naples. Sorry for my english level, it's very low! :oops: , and also I hope it is the right section for this topic

Recently I discovered the worl of PIC and i know a little of this topic. I whis create a sinusoidal generator whit Max32 and a DAC (16 bits). The idea is to generate the samples of sine function and pass it in out on digital pin whit appropriate time sampling (according to nyquist frequency).

The problem is to generate a precise time sampling, in fact the delay function (delay() and delayMicroseconds()) accept only integer number of milli or micro seconds, but the time sampling could not be integer! How can we solve the the problem?

Thanks for the valuable aid.

Hello, by Paolo.


serveurperso

Tue, 13 Sep 2011 05:23:48 +0000

Hi Paolo,

My English is worse than yours. A quick and dirty method : you can use a loop instead of delay. Measure the execution time for one minute and then made ​​a rule of three / next, tune your sine wave with a 440Hz tuning fork or frequency meter to trim the loop value! The good way is with a Timer interrupt

setup : (use Timer2, Timer1 is used by Tone() or other?)

ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_7); OpenTimer2(T2_ON | T2_PS_1_256, F_CPU / 256 / RATE);

Adjust the (256) ratio and your RATE : F_CPU / 256 / RATE must be < 16 bits

extern "C" { void __ISR(_TIMER_2_VECTOR, ipl7) T2InterruptHandler() { mT2ClearIntFlag();

//your code

} }

Pascal


serveurperso

Sun, 06 Nov 2011 10:40:02 +0000

#define PWMPIN 10

#define SAMPLERATE 20000 // 20KHz
#define LOOKUPSIZE 2000  // 10Hz

int8_t lookup[LOOKUPSIZE];

// volatile is not needed if you don't read vars inside loop() { ...  }
volatile uint32_t sample = 0;
volatile uint8_t increment = 0;

void setup() {
 pinMode(PWMPIN, OUTPUT);

 for(uint16_t i = 0; i &lt; LOOKUPSIZE; i++)
  lookup[i] = round(sin(i * 2 * PI / LOOKUPSIZE) * 127);

 OpenTimer2(T2_ON | T2_PS_1_1, 256);
 OpenOC5(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);

 ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_3);
 OpenTimer1(T1_ON | T1_PS_1_1, F_CPU / SAMPLERATE);
}

void loop() {
 // if(increment++ &gt; 100) increment = 1; // 10Hz to 1KHz sweep
 increment = random(100) + 1; // 10Hz to 1KHz random
 delay(100);
}

extern "C" {
 void __ISR(_TIMER_1_VECTOR, ipl3) T1InterruptHandler() {
  mT1ClearIntFlag();

  SetDCOC5PWM(lookup[sample % LOOKUPSIZE] + 128);
  sample += increment;
 }
}