Showing results for 
Search instead for 
Did you mean: 

STM32F303K8 - Sampling a 40KHz sine-wave

Associate III

The problem

I am to compare the phase shift between two sinewaves from an external source (I used a function generator in this case). I am running the STM32F303K8 at 64MHz, and this clock goes directly to the ADC and Timers 1 and 2 as well with a prescalar of 1.

Now according to Nyquist theorem, i have to sample at atleast x2 the frequency that is available, of interest. I start off with both my sinewaves having exactly 40KHz.

_legacyfs_online_stmicro_images_0693W00000bku8LQAQ.pngsnapshot of my function generator

I am using timer triggerd ADCs 1 and 2 with DMA + continous mode, each taking in a sinewave because i need them to be sampled simultaneously with very minimal distortion.

According to the datasheet on P.323, the Tconv = (Sampling time + 12.5 (12bit)) / 4095. I went for 601.5 cycles which puts me at Tconv to be 9.9us approx 100KHz, puting me well beyong the Nyquist frequency to sample the 40KHz waves.

I also configured separate timers for each ADC, 1 and 2 to be triggered by TIM 1 and 2 update event respectively.

When i convert the DMA'd values back to voltages, i can't recreate the sinewaves again, with the STM Studio.

_legacyfs_online_stmicro_images_0693W00000bku8kQAA.pngsnapshot from STM Studio.

I use the formula to convert my adc values back to voltages.

uint32_t adc1 = 0, adc2 = 0;
float voltage0 = 0.0, voltage1 = 0.0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *adc) {
	if (adc->Instance == ADC1)
		voltage0 = (adc1 * 3.3) / 4095;
	if (adc->Instance == ADC2)
		voltage1 = (adc2 * 3.3) / 4095;

In order not to overwhelm the question, i have attached my main.c file on this topic.

I think based on the sampling frequency, i can digitalize my sinewaves effortlessly, but still i don't know what is missing. I cant seem realize the theory.


>to compare the phase shift between two sinewaves from an external source

first you should look, how this is done by others. 🙂 (obviously you have not much experience with signal processing )

standard /easy way : signals -> comparators -> (timer) measure delay between zero crossings = precision phase angle measurement


on "your way" , analog -> ADC sampling and ..then?

  1. complex FFT -> searching maximum amplitude + take phase angle here
  2. reconstruct (!) wave and find zero crossings and then the delay

here a lot of complex mathematics needed and so lot of possible ways to calculate totally wrong or need pre-calculate, what resolution and errors will come out in best/bad case of SFDR/noise/rounding errors etc.


 Nyquist theorem, is just theoretical ...and you should read exactly, what it is saying: is possible, to reconstruct a wave up to this limit.

NOT that you get what you are dreaming of : perfect wave always there, without complex reconstruction....

If you feel a post has answered your question, please click "Accept as Solution".
Associate III

Well, i didn't want to concentrate on the signal processing aspect. I simply wanted to get the signal representation in the digital form, then i can apply whatever methods available. FFT, or even apply FIR filters. But first, i want to get the signal in the digital domain. Thats the gist of the matter. Forget the signal processing aspect of it for a moment.

Uwe Bonnes
Principal II

Try first with a much slower sinus wave so that reconstruction is straight forward. Reconstruction at the Nyquist edge is tricky.