2024-09-29 10:13 PM
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
TIM3:
ADC:
Using 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:
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
Solved! Go to Solution.
2024-09-30 11:49 AM
> But how come 14400-1 is giving 200us period?
Oh, now that I understand the issue you're describing, the answer is easy:
The timer clock is 72 MHz, not 36 MHz.
14400 / 72 MHz = 200 us.
This all checks out, yes?
2024-09-30 05:24 AM
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.
2024-09-30 09:29 AM - edited 2024-09-30 09:57 AM
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
2024-09-30 09:55 AM - edited 2024-09-30 10:15 AM
These are just 100 bytes plotted of ADC samples with the same settings [Counter Period = 7200-1].
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?
2024-09-30 10:19 AM
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.
2024-09-30 10:50 AM
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
2024-09-30 11:45 AM - edited 2024-09-30 11:50 AM
> 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.
2024-09-30 11:49 AM
> But how come 14400-1 is giving 200us period?
Oh, now that I understand the issue you're describing, the answer is easy:
The timer clock is 72 MHz, not 36 MHz.
14400 / 72 MHz = 200 us.
This all checks out, yes?
2024-09-30 07:45 PM
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
2024-09-30 07:56 PM
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.