Multi Channel ADC + DMA on STM32F723. Conversion of one channel affects other channels
Hello ST Community,
as part of a project I want to perform an AD conversion (ADC1 + DMA) of 4 channels at a sampling frequency of 5.5kHz. For this I have configured a timer which determines the sampling frequency and the data is stored on a MicroSD card.
The MCU is the STM32F723IC. I generate a PWM signal on one channel between 0-3.3V at 1 Hz and 50% duty cycle on the ADC CH1 and notice that the other three channels show a "weakened" pattern.
While cross-talk like behavior is displayed, the fact that when splitting the channels on two ADCs (ADC1 CH1 + CH2 and ADC2 CH3 + CH4) this pattern is only present on CH2 which leads me to suspect that the SAR ADC's capacitor is not discharging quickly. How can I prevent the pattern from appearing on the other pins when using a single ADC with 4 channels and the described sampling frequency? The pins are directly routed out from the processor. Floating state, no filtering is used.
Attached is a code snippet of the relevant parts:
...
htim5.Instance = TIM5;
htim5.Init.Prescaler = 0;
htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
htim5.Init.Period = 19593;
htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_RegisterCallback(&htim5, HAL_TIM_BASE_MSPINIT_CB_ID, Microphones_TIM_Base_MspInit);
HAL_TIM_RegisterCallback(&htim5, HAL_TIM_BASE_MSPDEINIT_CB_ID, Microphones_TIM_Base_MspDeInit);
if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
{
Error_Handling();;
return status;
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
{
Error_Handling();
return status;
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
{
Error_Handling();
return status;
}
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T5_TRGO;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = NBR_MICROPHONES_CHANNELS;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
HAL_ADC_RegisterCallback(&hadc1, HAL_ADC_MSPINIT_CB_ID, Microphones_ADC_MspInit);
HAL_ADC_RegisterCallback(&hadc1, HAL_ADC_MSPDEINIT_CB_ID, Microphones_ADC_MspDeInit);
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handling();
return status;
}
HAL_ADC_RegisterCallback(&hadc1, HAL_ADC_CONVERSION_COMPLETE_CB_ID, Microphones_ADC_ConvCpltCallback);
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_15;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handling();
return status;
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handling();
return status;
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_8;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handling();
return status;
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_12;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handling();
return status;
}
HAL_StatusTypeDef halStatus = HAL_OK;
halStatus = HAL_TIM_Base_Start_IT(&htim5);
if(halStatus != HAL_OK)
{
Error_Handling();
return status;
}
halStatus = HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&tempBuffer[0], NBR_MICROPHONES_CHANNELS);
if(halStatus != HAL_OK)
{
Error_Handling();
return status;
}If some parts of the source code are missing, I can provide them.
