cancel
Showing results for 
Search instead for 
Did you mean: 

Multi Channel ADC + DMA on STM32F723. Conversion of one channel affects other channels

Rookie38
Associate III

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.

0693W00000Lz48yQAB.png 

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.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> during floating state of the pins Ch2-4 my expectation would have been a DC voltage and no signal of the first pin.

The sampling capacitor is not discharged to 0 between each conversion. Rather, it keeps its value from the previous conversion (to a large degree) and will be charged/discharged through R_ADC when the next sampling happens. Increasing sampling time will help improve accuracy for high impedance sources, but for infinite impedance, it won't do a whole lot.

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

View solution in original post

4 REPLIES 4
TDK
Guru

> 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.

 

> The pins are directly routed out from the processor. Floating state, no filtering is used.

What exactly is the setup? One pin (CH1?) is connected to a PWM input and the other pins are left floating?

Measuring an infinite impedance source is unlikely to produce a useful result.

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

> What exactly is the setup? One pin (CH1?) is connected to a PWM input and the other pins are left floating?

I generate the PWM signal using a logic analyzer. Not via STM32. Simple setup like this:0693W00000Lz4cPQAR.pngI just want to prove the correct functionality of the AD conversion with the described sampling rates.

> Measuring an infinite impedance source is unlikely to produce a useful result.

I currently use AN2834 "How to get the best ADC accuracy in STM32 microcontrollers" document for learning about ADCs. Maybe I lack the electrotechnical background, but during floating state of the pins Ch2-4 my expectation would have been a DC voltage and no signal of the first pin.

TDK
Guru

> during floating state of the pins Ch2-4 my expectation would have been a DC voltage and no signal of the first pin.

The sampling capacitor is not discharged to 0 between each conversion. Rather, it keeps its value from the previous conversion (to a large degree) and will be charged/discharged through R_ADC when the next sampling happens. Increasing sampling time will help improve accuracy for high impedance sources, but for infinite impedance, it won't do a whole lot.

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

I notice that my expectation regarding the floating pin states and their effect was not justified. As soon as different signals are generated on all channels by my test equipment (and not in floating state anymore), there is no interference and all signals correspond to the expected value. Thanks for correction.