Hi all,
I've been looking into this challenge for a couple of days, I figured now would be a good time for me to ask some questions on a forum like this. I have done some C++ programming in the past; I'm slowly getting back into the mindset and vernacular but am not a seasoned programmer. Basically what I'd like to do is employ a low-cost MCU with DAC to act as a sine wave frequency generator in the range of about 100 kHz to 1 MHz, with a frequency resolution ideally of about 5 Hz. I am looking at the STM32F072 and STM32L151; currently I am prototyping on a STM32F4 Discovery Board that has an STM32F407, connected to a suitable opamp circuit as described in this ST Application Note.
Sofar, I've managed to make a simple phase accumulator (rising sawtooth) at a frequency of 100 kHz and a samplerate of 2 MHz; when I use the arm_math.h function arm_sin_f32 to convert this into a sine wave, I unfortunately get regular discontinuities, which after some investigation I presume are due to some type of processor overload. Therefore I'd like to investigate using arm_sin_q15; the reduced resolution is not a problem for my application.
I have been learning about the Q15 data type and understand that it is essentially a signed 16-bit integer that goes from -1 to 0 to 0.9999ish - the latter being 32767/32768 = 0.9999695. This discussion was enlightening in this. Also, the CMSIS DSP documentation mentions that the q15_t input for the sine function accepts an input ranging from 0 to 0.9999, which is internally mapped to the range of 0 to 2pi.
My question is: how do I (elegantly) construct a phase accumulator with Q15 as a data type, if the data type itself can't handle values more than (the equivalent of) 1? With floats or ints, what I did was: if phase >= 2pi (phase -= 2pi); - this requires though that the phase parameter can overshoot the 2pi value...
Perhaps there is a way to do this with modulo? Or is there another approach in general that is recommended in terms of simplicity, elegance & efficiency? I am considering also to build a complex oscillator as mentioned in this article.
Perhaps I should just normalize first to a lower integer value to represent the 2pi wrapping point? That seems like an expensive extra computational step...
Thanks in advance for any help.
Ah... I can just simply use an unsigned 16-bits integer for the phase parameter of course. Duh...