2017-02-17 08:56 AM
Hi.
I've been using 4 channel ADC DMA convertion and recently noticed that one of the inputs affects the read values of another. The troubleshouting showed that the voltage on Channel 15(PC5) somehow gets to the other ADC pins.
Interestingly, I see the read values be affected only on one channel (2,PA2). However, I see the voltage change on all other ADC channels when I change voltage on PC5. With 0.3-3V input swing on PC5, I have almost the same swing on the other ADC pins, if they're not connected to anything, and 8mV swing if the pins connected through opamp buffer and 100ohm.
Did anyone faced a similar problem? This is a second prototype board out of two which exhibits this behaiviour.
void ADC_Config()
{ ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; /* Enable peripheral clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 32; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_Cmd(DMA2_Stream0, ENABLE); //DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); /* Configure ADC pins as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* ADC Common configuration *************************************************/ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled ; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 regular channel 1 configuration ************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // Not used but needed for valid init ADC_InitStructure.ADC_NbrOfConversion = 4; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_28Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_28Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_28Cycles); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 **************************************************************/ ADC_Cmd(ADC1, ENABLE); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1);}#adc #analog-inputSolved! Go to Solution.
2017-02-17 09:04 AM
One ADC with multiplexed channels, and an improper setup. All channels share the same S&H capacitor, explaining this effect.
Either buffer your inputs (opamp) to get a lower impedance, or increase the sample time.
2017-02-17 09:04 AM
One ADC with multiplexed channels, and an improper setup. All channels share the same S&H capacitor, explaining this effect.
Either buffer your inputs (opamp) to get a lower impedance, or increase the sample time.
2017-02-17 10:15 AM
The inputs are opamp buffered trough 100ohm ressistors
2017-02-18 08:23 AM
Play with the adc sample and hold time. Make the integration as small as possible while keeping the output within acceptable noise range. I have seen other solved similar crosstalk like topics in december...
2017-02-18 09:01 AM
The reason is not really crosstalk, but the remaining charge on the S&H capacitor.
Either one configures enough time for charge/discharge (sampling times), or takes care for a faster charge/discharge (input impedance).
An understanding of the working principle of SAR-ADCs is advantageous.
2017-02-19 10:46 AM
I changed the resistors after the buffer to 22ohm and it minimized the effect to a negligible state. Didn't see any improvements when set the sampling time to maximum.
2017-02-19 11:32 AM
With buffer, I mean a buffer amplifier, usually an opamp.
Each of your ADC input channels must be able to fully charge (or discharge) the S&H capacitor in your configured sampling time over the sum impedance (which is the output impedance of your buffer amplifier plus the input impedance of the ADC, as specified in the datasheet). Basically a first order RC element.