cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Multi-Channel has a problem.

suppakit
Associate II
Posted on January 27, 2014 at 06:13

Hello,

I have many questions about ADC Multi-Channel to ask and thank you for your helping. I used STM32F417ZGT6.

1. I used ADC to read voltage in 2 channel with below setting.

01./* Enable ADCx, DMA and GPIO clocks ****************************************/

02.    RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_DMA2, ENABLE );

03.    RCC_AHB1PeriphClockCmd ( SS_AI_RJA7_GPIO_CLK | SS_AI_RJB7_GPIO_CLK, ENABLE );

04.    RCC_APB2PeriphClockCmd ( SS_AI_ADC_CLK, ENABLE );

05. 

06.    /* Configure ADC3 Channel7 pin as analog input ******************************/

07.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

08.    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

09. 

10.    GPIO_InitStructure.GPIO_Pin = SS_AI_RJA7_PIN;

11.    GPIO_Init ( SS_AI_RJA7_GPIO_PORT, &GPIO_InitStructure );

12. 

13.    GPIO_InitStructure.GPIO_Pin = SS_AI_RJB7_PIN;

14.    GPIO_Init ( SS_AI_RJB7_GPIO_PORT, &GPIO_InitStructure );

15. 

16.    DMA_DeInit (DMA2_Stream0);

17. 

18.    /* DMA2 Stream0 channel2 configuration **************************************/

19.    DMA_InitStructure.DMA_Channel               = DMA_Channel_2;

20.    DMA_InitStructure.DMA_PeripheralBaseAddr    = (uint32_t) &ADC3->DR;

21.    DMA_InitStructure.DMA_Memory0BaseAddr       = (uint32_t) &ADCValue[0];

22.    DMA_InitStructure.DMA_DIR                   = DMA_DIR_PeripheralToMemory;

23.    DMA_InitStructure.DMA_BufferSize            = 2;

24.    DMA_InitStructure.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;

25.    DMA_InitStructure.DMA_MemoryInc             = DMA_MemoryInc_Enable;

26.    DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_HalfWord;

27.    DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_HalfWord;

28.    DMA_InitStructure.DMA_Mode                  = DMA_Mode_Circular;

29.    DMA_InitStructure.DMA_Priority              = DMA_Priority_High;

30.    DMA_InitStructure.DMA_FIFOMode              = DMA_FIFOMode_Disable;

31.    DMA_InitStructure.DMA_FIFOThreshold         = DMA_FIFOThreshold_HalfFull;

32.    DMA_InitStructure.DMA_MemoryBurst           = DMA_MemoryBurst_Single;

33.    DMA_InitStructure.DMA_PeripheralBurst       = DMA_PeripheralBurst_Single;

34. 

35.    DMA_Init ( DMA2_Stream0, &DMA_InitStructure );

36.    DMA_Cmd ( DMA2_Stream0, ENABLE );

37. 

38.    /* ADC Common Init **********************************************************/

39.    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

40.    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

41.    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

42.    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

43.    ADC_CommonInit ( &ADC_CommonInitStructure );

44. 

45.    /* ADC3 Init ****************************************************************/

46.    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

47.    ADC_InitStructure.ADC_ScanConvMode = ENABLE;

48.    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

49.    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

50.    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

51.    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

52.    ADC_InitStructure.ADC_NbrOfConversion = 2;

53.    ADC_Init ( SS_AI_ADC, &ADC_InitStructure );

54. 

55.    /* ADC3 regular channel7 configuration **************************************/

56.    ADC_RegularChannelConfig ( SS_AI_ADC, SS_AI_RJA7_ADC_CH, 1, ADC_SampleTime_15Cycles );

57.    ADC_RegularChannelConfig ( SS_AI_ADC, SS_AI_RJB7_ADC_CH, 2, ADC_SampleTime_15Cycles );

58. 

59.    /* Enable DMA request after last transfer (Single-ADC mode) */

60.    ADC_DMARequestAfterLastTransferCmd ( SS_AI_ADC, ENABLE );

61.    /* Enable ADC3 DMA */

62.    ADC_DMACmd ( SS_AI_ADC, ENABLE );

63.    /* Enable ADC3 */

64.    ADC_Cmd ( SS_AI_ADC, ENABLE );

65. 

66.    ADC_SoftwareStartConv(SS_AI_ADC);

But I have a problem when I put voltage to adc with this

1. I measure voltage before I plug it to MCU, about 1.185V 

2. Plug it and measure again, about 1.181V 

3. When I plug another input on another channel with 2.501V. The old one will be 1.200V. 

This value is used multimeter for measurement. And I try to read adc value, 

they have same value about 2.501V and 1.200V But it is not stable, it is about 2.492-2.508 when I put 2.501V. 

However, The actual value is about 1.185V and 2.501 V. 

Then I changed sampling rate from ADC_SampleTime_15Cycles to ADC_SampleTime_480Cycles. The voltage don't changed when I plug it.

But the value is not stable. When I used only one channel, I used ADC_SampleTime_15Cycles

and the value is enough accurate. I put 2.501 and can read 2.498-2.502 that's ok. 

2. Can I turn off ADC and come back to read normal GPIO? And Can they come back again to read an ADC? How can I do it? And it is very important to not loss an accuracy on ADC.

Thank you very much to helping.

#stm32f4 #adc_multi-channel
1 REPLY 1
raptorhal2
Lead
Posted on January 27, 2014 at 16:10

The conversion results appear to be the result of source signal noise and impedance. Are you using an amplifier as a signal source? And does the board design follow ST's guidance for reference supply capacitors, grounding, short traces, etc.

It may be difficult to get lower noise results. Can the conversion results be averaged over a number of samples to filter the noise ?

Yes, you can switch between AN and GPIO mode on a pin, but ADC converting the pin in GPIO mode or GPIO reading the pin in AN mode is meaningless.

Cheers, Hal