cancel
Showing results for 
Search instead for 
Did you mean: 

Multi ADC conversion

bmwael1
Associate II
Posted on January 21, 2013 at 14:53

Hi

friends

I use this program to Read ADC1 Value connected to PC2 port

of my

''stm32f4discovery'' card

.

/****************************************************************************************/

void

ADC_setup(

void

)

{

/* Enable ADC clock (This seems to be a duplicate statement) */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

/*********************************************************/

/* Configure ADC Channel 12 pin as analog input */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

/*** ADC1 regular channel 12 configuration ***/

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStructure.ADC_ScanConvMode = DISABLE;

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfConversion = 1;

ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

}

/*Read potentiometer (voltage) value*/

int

POTGetValue(

void

)

{

ADC_SoftwareStartConv(ADC1);

while

(ADC_GetSoftwareStartConvStatus(ADC1));

return

ADC_GetConversionValue(ADC1);

}

/****************************************************************************************/

int

main(

void

)

{

ADC_setup();

int

val1 = POTGetValue();

puts(val1);

}

It works

, Now i want to display many ADC

conversion for example i want to connect

4 signal to 4 port PC0

, P

C

1,

PC2

A

ND PC3.

what are the

modifications to do please ?

I fo

und in d

atasheet t

hat PC2 represent

ADC_Channel_12

th

at's why i use it

And i use in ligne 19 one

numbe

r

of

conversion

Thank you

#stm32f4discovery #adc

10 REPLIES 10
raptorhal2
Lead
Posted on January 21, 2013 at 15:14

The F4 Standard Peripheral Library example ADC3_DMA provides an example for ADC1 Channel 12. Change the DMA buffer size and number of ADC channels to 4. Change ADCConvertedValue to a 4 word buffer. Configure 3 more GPIOs as analog input. Add 3 more ADC channel configuration statements.

Unless I have overlooked something, that should do it.

Cheers, Hal

bmwael1
Associate II
Posted on January 21, 2013 at 15:25

Thank you for your replay

I change the program and add PC0,1,2,3 But i don't know how to read conversion value from Channel 1 or 2... Because i don't see a specific command that read actualy from channel 1 this is my program

/****************************************************************************************/
void
ADC_setup(
void
)
{
/* Enable ADC clock (This seems to be a duplicate statement) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/*********************************************************/
/* Configure ADC Channel 12 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| 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(GPIOC, &GPIO_InitStructure);
/*** ADC1 regular channel 12 configuration ***/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_3Cycles);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
/*Read potentiometer (voltage) value*/
int
POTGetValue(
void
)
{
ADC_SoftwareStartConv(ADC1);
while
(ADC_GetSoftwareStartConvStatus(ADC1));
return
ADC_GetConversionValue(ADC1);
} 
/****************************************************************************************/
int
main(
void
)
{
ADC_setup();
int
val1 = POTGetValue();
puts(val1);
}

I mean that this function

int
POTGetValue(
void
)
{
ADC_SoftwareStartConv(ADC1);
while
(ADC_GetSoftwareStartConvStatus(ADC1));
return
ADC_GetConversionValue(ADC1);
} 

Read automatically from channel 1 how to change it to read the others channels please ?

raptorhal2
Lead
Posted on January 21, 2013 at 15:44

The modification I listed are to be made to the ADC1 part of the Library example, which includes initializing DMA. The ADC3 code in the Library Example can be tossed out.

The results are stored in ADCConvertedValue[] in the regular channel configuration sequence. A GetConvertedValue statement is then not needed.

I did overlook one thing. Not all ADC channels are freely available on the Discovery Kit. Select from 1,2,3,8,9,11,12,14,15.

Cheers, Hal

bmwael1
Associate II
Posted on January 22, 2013 at 10:45

Hello

I tried to change the program with the example used in documentation but it gives always ADC value = 0 :(

/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC1ConvertedValue = 0;
void
ADC_setup(
void
)
{
/* Enable ADC clock (This seems to be a duplicate statement) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_2; 
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
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_Disable;
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);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
/*********************************************************/
/* Configure ADC Channel 12 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/*** ADC1 regular channel 12 configuration ***/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
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(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 2, ADC_SampleTime_3Cycles);
/* 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);
}
/******************************************************************/
int
main(
void
)
{
ADC_setup();
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
Puts (ADC1ConvertedValue);
}

Posted on January 22, 2013 at 13:20

You must not leave main()

The array you write the values too can't be too short for the DMA.

You must wait for the values to get loaded/converted.

You can't puts() binary values.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
bmwael1
Associate II
Posted on January 22, 2013 at 13:59

Yes friend i use while(0) of course ,

And the puts i have program it to be able to read value

Are there other problem in DMA or ADC code ?

frankmeyer9
Associate II
Posted on January 22, 2013 at 14:26

And the puts i have program it to be able to read value

 

puts() is no function to ''read values''. It does not accept binary values as parameter.

 

 

 

Are there other problem in DMA or ADC code ?

 

Yes.

Once you fired up the ADC and DMA, it runs in parallel to the code execution in main.

What do you think will finish first ?

raptorhal2
Lead
Posted on January 22, 2013 at 15:47

Are there other problem in DMA or ADC code ?

Yes. In DMA initialization, MemoryInc needs to be enabled in order to store the second conversion in the second location of the converted values array.

Also, to avoid problems you haven't encountered yet, add the following to ADC1 initialization:

ADC_InitStructure.ADC_ExternalTrigConv = 0;

Cheers, Hal

bmwael1
Associate II
Posted on January 22, 2013 at 16:37

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6cG&d=%2Fa%2F0X0000000brr%2FWR2kofMhvse_A5O_3Hu9oSVVxwmcBTLp.q05HzZcotE&asPdf=false