AnsweredAssumed Answered

ADC Multi-Channel has a problem.

Question asked by K. Suppakit on Jan 27, 2014
Latest reply on Jan 27, 2014 by baird.hal.001
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.

Outcomes