This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Constructing an arbitrary-frequency NCO/DDS waveform generator with CMSIS-DSP

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.