Confusion about ADC sampling speed and sampled value
Hello.
I am very new in using STM32. I am using STM32H747I-DISCO board. For my project, I only need one ADC in differential mode. Previously, I tried to use DMA with ADC but it never worked, even the "ADC dual mode interleaved" example provided by st didn't work. So, I started to fiddle with "PollForConversion" and interrupt methods. Now, from CubeIDE, i have the following clock setup,
CPU1 - 480 MHz, CPU2 - 240 MHz, APB1 and APB2 timer clocks - 240 MHz, ADC - 21 MHz
Only have channel 1 set to differential mode for ADC1 and Timer 2 in free running (1 MHz) to measure timings.
Here's the timer initialize,
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 240;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 4294967295;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}Here's the ADC initialize,
static void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
I tried both poll and interrupt method and checked the time it takes for reading one sample. From the ADC configuration, it should have 1 Msps sampling rate, that is 1us for each sample. But when checking in action, poll method seems to take about 1 second to read 1 sample (two calls, "PollForConversion" and "GetValue"). Interrupt method seems to take about 400ms. Besides, without any input to ADC pins (0V), the values I get is still very big, roughly 32000 in 16 bit mode and 2000 in 12 bit mode.
For my project, I need very fast sampling rate, at least 0.1 Msps, preferably 1 Msps. The processor doesn't have to do anything during sampling. Even the sampled value conversion can be done later. This should be feasible in STM32 microprocessors but I had been unable to do so.
Any help or guidance on what I could be doing wrong or what I can improve would be very appreciated. Thank you.
