cancel
Showing results for 
Search instead for 
Did you mean: 

Not able to get required samples from ADC DMA triggered using timer [STM32F103C8]

x4ce
Associate III

Hello,

I am acquiring samples from 50Hz Sine Wave through a CT and want to get 100 samples of this signal (T=20ms). For this, I need each sample at 200us apart so I get an array of 100 bytes. I have following clock setup:

APB1 = 36Mhz; ADC = 12Mhz

TIM3 Event: 36,000,000/ 7,200 = 5,000Hz = 200us

ADC Sample Time: Sampling Time + 12.5 cycles = 239.5 + 12.5 = 252 cycles => 1/12Mhz X 252 = 21us

Screenshot_44.png

 

TIM3:

Screenshot_45.png

ADC:

Screenshot_46.pngUsing above settings & calculations, SOC is supposed to complete said ADC in 21us and sample time is 200us which is fine. Here is the code:

/* USER CODE BEGIN PV */
uint16_t adc_value[500] = {0};
/* USER CODE END PV */

  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim3);
  HAL_ADCEx_Calibration_Start(&hadc1);
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_value, sizeof(adc_value));
  /* USER CODE END 2 */

/* ADC Config */
hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;

sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
/* ADC Config */

/* TIM3 Config */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 7200;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
/* TIM3 Config */

 

I am getting samples in the 400 byte array but I am supposed to get a complete sine wave cycle in first 100 byte but the cycle is completed in 200 bytes. Even I tried to increased sampling time (Counter Period: 14,400) it shows same the result. Here is the samples vs. data result:

Screenshot_47.png

 

Please guide, what I may be missing in the code or in calculations to get a complete 50Hz Sine Wave cycle in ADC of 100 samples.

 

Regards

Shahid

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> But how come 14400-1 is giving 200us period?

Oh, now that I understand the issue you're describing, the answer is easy:

TDK_0-1727722046543.png

 

The timer clock is 72 MHz, not 36 MHz.

14400 / 72 MHz = 200 us.

This all checks out, yes?

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

View solution in original post

9 REPLIES 9
TDK
Guru

It looks like you have 2 complete sine waves in 200 samples, which is 1 per 100 samples, yes?

Counter period is off by one. It should be 7199.

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

More on this, I have to subtract the offset i.e. 2036 (approx.) then should I get the voltage in float or continue squaring value in integers? What would be the best less computing method you recommend?

Thanks

x4ce
Associate III

These are just 100 bytes plotted of ADC samples with the same settings [Counter Period = 7200-1].

Screenshot_48.png

 

This is for [Counter Period = 14400 - 1] and I suppose initial graph is taken at the same setting. So, I am getting samples at every 200us but with Counter Period = 14400-1. How does that work?

Screenshot_49.png

 

 

 

I don't understand why the x axis in your plots are not the same.

Changing TIM3 period will change the capture rate if it's tied to ADC trigger, which it looks like it is.

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

But how come 14400-1 is giving 200us period? ADC tied Timer gives event at each rising/ falling edge?

At Counter Period = 7200-1, period is 200us but is it like a PWM signal so ADC is triggered 2 times?

Also, in 100 byte sample, the sine wave is more than half covered.

 

Thanks

TDK
Guru

> But how come 14400-1 is giving 200us period? ADC tied Timer gives event at each rising/ falling edge?

> At Counter Period = 7200-1, period is 200us but is it like a PWM signal so ADC is triggered 2 times?

 

It doesn't make logical sense that these two would have the same period. Perhaps you are not updating the code before running, or not running the code you think you are. Consider toggling a pin in a relevant callback to verify clock settings. Make the pin a PWM output and verify it gets updated at the expected rate.

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

> But how come 14400-1 is giving 200us period?

Oh, now that I understand the issue you're describing, the answer is easy:

TDK_0-1727722046543.png

 

The timer clock is 72 MHz, not 36 MHz.

14400 / 72 MHz = 200 us.

This all checks out, yes?

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

Yes, I have missed that and mistakenly considering 36MHz as Timer 3 clock as well. Thanks for pointing out.

More on this, I have to subtract the offset i.e. 2036 (approx.) then should I get the voltage in float or continue squaring value in integers? What would be the best less computing method you recommend?

Thanks

I'd prefer squaring the integers and summing them if you're trying to get RMS or something similar. The STM32F1 doesn't have a math coprocessor so it needs to emulate the float operation in software, which is very slow.

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