cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 ADC multiple channel

pano
Associate II
Posted on October 21, 2014 at 16:40

Hi,

I was looking for an example about ADC with 2 input pin and I have found this code, from another old thread in this forum:

#include <
stdio.h
>
#include <
stdlib.h
>
#include <
string.h
>
#include ''stm32f4xx.h''
//******************************************************************************
volatile uint16_t ADCConvertedValues[2];
//******************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Configure ADC1 Channel3 & 5 pins as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//******************************************************************************
void ADC1_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Enable peripheral clocks *************************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* DMA2_Stream0 channel0 configuration **************************************/
DMA_DeInit(DMA2_Stream0);
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 = 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_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);
/* 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 Init ****************************************************************/
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_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel configuration ******************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_480Cycles); // PA3
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_480Cycles); // PA5
/* 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);
}
//******************************************************************************
int main(void)
{
GPIO_Configuration();
ADC1_Configuration();
puts(''ADC Testing'');
while(1)
{
if (ADCConvertedValues[1] != 0xFFFF)
{
printf(''%03X %03X\n'', ADCConvertedValues[0], ADCConvertedValues[1]);
ADCConvertedValues[1] = 0xFFFF;
}
}
while(1); /* Infinite loop */
}

I have main.c and ADC.c like different files; how to fix the previous code to read the two converted values in the main.c file? thanks
6 REPLIES 6
Posted on October 21, 2014 at 18:11

I was looking for an example about ADC with 2 input pin and I have found this code, from another old thread in this forum:

 

...

 

I have main.c and ADC.c like different files; how to fix the previous code to read the two converted values in the main.c file?

 

Ok, code looks very familiar, pity you don't cite the thread you lifted it from, what's the question here? How do you create a project with multiple files? How do you copy/merge functions between files?

The example uses DMA to read two samples continuously into memory, in the background.

You'd need to think about your toolchain/IDE. You'd need to think about how you need the data, whether you want it paced, or if you want an interrupt when the samples are ready, or if you want to accumulate a larger number of samples.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pano
Associate II
Posted on October 22, 2014 at 12:19

Ok, then:

now, I'm using this code for an ADC

#include ''stm32f4xx_adc.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_rcc.h''
#include ''ADC.h''
void adc_configure(void){
ADC_InitTypeDef ADC_init_structure; //Structure for adc confguration
GPIO_InitTypeDef GPIO_initStructre; //Structure for analog input pin
//Clock configuration
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//The ADC1 is connected the APB2 peripheral bus thus we will use its clock source
RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);//Clock for the ADC port!! Do not forget about this one ;)
//Analog pin configuration
GPIO_initStructre.GPIO_Pin = GPIO_Pin_0;//The channel 10 is connected to PC0
GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //The PC0 pin is configured in analog mode
GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //We don't need any pull up or pull down
GPIO_Init(GPIOC,&GPIO_initStructre);//Affecting the port with the initialization structure configuration
//Analog pin configuration
GPIO_initStructre.GPIO_Pin = GPIO_Pin_1;//The channel 11 is connected to PC1
GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //The PC1 pin is configured in analog mode
GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //We don't need any pull up or pull down
GPIO_Init(GPIOC,&GPIO_initStructre);//Affecting the port with the initialization structure configuration
//ADC structure configuration
ADC_DeInit();
ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
ADC_init_structure.ADC_ContinuousConvMode = ENABLE; //the conversion is continuous, the input data is converted more than once
ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;// conversion is synchronous with TIM1 and CC1 (actually I'm not sure about this one :/)
ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//no trigger for conversion
ADC_init_structure.ADC_NbrOfConversion = 1;//I think this one is clear :p
ADC_init_structure.ADC_ScanConvMode = DISABLE;//The scan is configured in one channel
ADC_Init(ADC1,&ADC_init_structure);//Initialize ADC with the previous configuration
//Enable ADC conversion
ADC_Cmd(ADC1,ENABLE);
//Select the channel to be read from
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_144Cycles);
}
int adc_convert(void){
ADC_SoftwareStartConv(ADC1);//Start the conversion
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion
return ADC_GetConversionValue(ADC1); //Return the converted data
}

and in the main file

ConvertedValue = adc_convert();

Now, I need another analog input (for a force sensor); I have no idea how to do this, so, looking in this forum I have founded [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/Multi%20Channel%20ADC%20reading&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=3075]this 3d with your code. The previous code has the function

int adc_convert(void)

that I can use to have the converted value in the main fuction. If I copy the code of the mutiple channel ADC and then copy the code about main fuction

GPIO_Configuration();
ADC1_Configuration();
puts(''ADC Testing'');
while(1)
{
if (ADCConvertedValues[1] != 0xFFFF)
{
printf(''%03X %03
X'', ADCConvertedValues[0], ADCConvertedValues[1]);
ADCConvertedValues[1] = 0xFFFF;
}
}
while(1); /* Infinite loop */
}

it doesn't works because main function doesn't know what

ADCConvertedValues

is.
frankmeyer9
Associate II
Posted on October 22, 2014 at 12:48

..it doesn't works because main function doesn't know what

ADCConvertedValues

is That's probably because your mastering of the C language seems not quite sufficient. Have you heard of the

extern

keyword ?
Posted on October 22, 2014 at 15:38

Define it in one file, and then use the external reference in the other(s)

extern volatile uint16_t ADCConvertedValues[2];

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pano
Associate II
Posted on October 24, 2014 at 12:56

ok thanks;

to resolve this errors?

.\output\controllo_mot.axf: Error: L6218E: Undefined symbol DMA_Cmd (referred from adc.o).

.\output\controllo_mot.axf: Error: L6218E: Undefined symbol DMA_DeInit (referred from adc.o).

.\output\controllo_mot.axf: Error: L6218E: Undefined symbol DMA_Init (referred from adc.o).
Posted on October 24, 2014 at 14:17

Add stm32f4xx_dma.c to your project, review project templates.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..