Created Sun, 04 Sep 2011 16:33:26 +0000 by 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.
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
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 < 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++ > 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;
}
}