cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with ADC: channel affected by another and trouble with type conversion

jean_prieur
Associate III
Posted on June 24, 2012 at 14:58

Hello,

I'm using IAR embedded Workbench for ARM 6.30 kickstart to program a STM32F4 DISCOVERY microcontroler.

I have two problem with ADCs:

- I use two ADC channels (12 & 14) based on the same ADC (ADC2) to 8-bits digitizing two potentiometers output voltages. The trouble is, when I change the first potentiometer value, it's affects the second potentiometer digital value.

- The strangest problem: sometimes when I run my project on the STM32 with the ''Make and Restart Debugger'' button, with NO CHANGES in my code, the ADC behavior can change: instead of being digitized on 8-bit (0 to 255), potentiometers values will be digitized on 6-bits (0 to 63) or on 16-bits (0 to 65535), I can see it on the watch !! What is the problem with IAR ?

Thanks for your help ! I work on this problem for 2 weeks...

Jean

 

// ADC ADRESS

#define ADC_CCR_ADDRESS ((uint32_t)0x40012308)

// Table to store digitized ADC values

extern

__IO uint16_t TabADC[2];

////////////////////////////////////////////////////////////////////

//////// ADC configuration ///////////

////////////////////////////////////////////////////////////////////

void

ADC_Config(

void

)

{

// ADC initialisation

ADC_CommonInitTypeDef ADC_CommonInitStructure;

// CLOCK set for DMA2 + GPIOC2 + ADC1 + ADC2

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);

// DMA2 config (direct access memory) Stream0 channel0

DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_Channel = DMA_Channel_0;

// USE CHANNEL 0

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&TabADC;

// Store in my table the digitized values

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStructure.DMA_BufferSize = 2;

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_Enable;

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);

// DMA2_Stream0 enable

// ADCs configuration: ADC Channel 12 & 14

// POT2: ADC Channel 12 -> PIN PC2

// POT3: ADC Channel 14 -> PIN PC4

GPIO_InitTypeDef GPIO_InitStructure;

// GPIOC

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

// 'ADC ''Common''

ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;

ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;

ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonInitStructure);

// Initialisation ADC ''2'' channels 12 & 14

ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;

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_NbrOfConversion = 2;

ADC_Init(ADC2, &ADC_InitStructure);

// ADC2 regular channels 12, 14

ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 2, ADC_SampleTime_3Cycles);

// Enable DMA request after last transfer (Multi-ADC mode)

ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

// Start ADC2

ADC_Cmd(ADC1, ENABLE);

ADC_Cmd(ADC2, ENABLE);

// Start ADC1 Software Conversion

ADC_SoftwareStartConv(ADC1);

}

#adc

8 REPLIES 8
raptorhal2
Lead
Posted on June 24, 2012 at 16:00

It's not an IAR problem. The ST ADC library examples for the F4 are missing a structure init that causes your bit resolution problems and possibly the signal leakage problem. Add the following after line 64:

ADC_InitStructure.ADC_ExternalTrigConv =  0;

ST has promised to fix the library in the next release, whenever that is.

After you fix this, you may find the results somewhat inaccurate if your potentiometer is connected directly to the ADC pin. The ADC has an input impedance and capacitance. For best results. use an operational amplifier between the potentiometer and ADC pin.

And, check the input signal to make sure something in your circuit isn't causing one potentiometer to affect the output of the other.

Cheers, Hal

jean_prieur
Associate III
Posted on June 24, 2012 at 17:36

Thanks a lot Hal! This solve the problem with the type conversion!

Unfortunaltely, I still have a problem with ADC channels which influence each others. For example:

PC2 =

115

and PC4 =

115

if I change the value of PC4 to

250

, the value of PC2 is affected and change to the value

121

.

if I change the value of PC4 to

0

, the value of PC2 is affected and change to the value

108

.

(I change the value of value of PC2 with a potentiometer, PC4 is also linked to a potentiometer.)

Do you have any idea? I monitored the voltage on the pin PC2 but there is no voltage change, while the digitized value change! 

Thanks a lot!

(note: I change the code 

ADC_Prescaler = ADC_Prescaler_Div2

to 

ADC_Prescaler = ADC_Prescaler_Div8 

and this improved the influence but it is still bad)

raptorhal2
Lead
Posted on June 24, 2012 at 18:24

Change Line 50 to:

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

Cheers, Hal
jean_prieur
Associate III
Posted on June 24, 2012 at 18:38

Thanks !

I just try it but infortunately this change nothing...

raptorhal2
Lead
Posted on June 24, 2012 at 19:56

This may take a day or two, but I will hook up my Discovery board and try and duplicate the problem.

Cheers, Hal

jean_prieur
Associate III
Posted on June 24, 2012 at 20:39

Thanks a lot Hal for your support !!

frankmeyer9
Associate II
Posted on June 25, 2012 at 12:09

I would try to set a longer sampling time.

 ... ADC_SampleTime_3Cycles

);

This is not much. If the channels are adjacent, the cap of the S&H stage might not have enough time to charge/discharge to the value of the consecutive channel, (depends also on impedances).

As the value from a potentiometer is not time critical, I suggest a substantial larger value.

jean_prieur
Associate III
Posted on June 25, 2012 at 15:54

Thanks you fm it's working perfectly with a largest sampletime ! Now I understand.