cancel
Showing results for 
Search instead for 
Did you mean: 

multichannel adc stm32f4

joneyvindur
Associate II
Posted on August 24, 2012 at 00:41

stm32f4-discovery

I am impressed with the built-in 12bit adc. 

I want eventually to read 12 voltages at 10Hz or greater. 

I am going to simplify the problem to 2 channel add and expand to 12 once that is working. 

I read with great interest:

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00258017.pdf

In particular article 1.2  

Multichannel (scan), single conversion mode    

but unfortunately it says:

this application note is not delivered with a firmware example of this mode.    

So I tried to merge projects across the web but it doesn't quite work yet (it just converts one analog input, the other one is 0 all the time). 

Can anyone provide a sample code or scrutinize my approach:

__IO uint32_t ADC3ConvertedVoltage[2] = {0,0};

void ADC3_DMA_Config(void)

{

  ADC_InitTypeDef       ADC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  DMA_InitTypeDef       DMA_InitStructure;

  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC3, DMA2 and GPIO clocks ****************************************/

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  /* DMA2 Stream0 channel0 configuration **************************************/

  DMA_InitStructure.DMA_Channel = DMA_Channel_2;

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC3ConvertedValue;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = 2;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // u32

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

  DMA_Cmd(DMA2_Stream0, ENABLE);

 /* Configure ADC3 Channel12 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);

  /* ADC3 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_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = 2;

  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel12 configuration *************************************/

  ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles);

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

  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

  /* Enable ADC3 DMA */

  ADC_DMACmd(ADC3, ENABLE);

  /* Enable ADC3 */

  ADC_Cmd(ADC3, ENABLE);

}

Debugger:

Breakpoint 1, main () at main.c:27

27   }

4: /x ADC3ConvertedValue = {0x550, 0x0}

3: /x ADC3ConvertedValue = {0x540, 0x0}

2: /x ADC3ConvertedValue = {0x550, 0x0}

1: ADC3ConvertedValue = {1408, 0}

(gdb) 

#multichannel-adc-stm32f4 #read-function
7 REPLIES 7
Posted on August 24, 2012 at 04:29

A half word is 16-bits.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
raptorhal2
Lead
Posted on August 24, 2012 at 15:23

While the F4 version on the Discovery board has 16 ADC channels, only 9 are free due to pin assignments to other board functions. See the Discovery manual for pin assignments. You should still be able to learn with what you have before making your own board.

You need to initialize PC1 and PC2, not PC2 and PC3. Channel 13 (PC3) is not a free channel

And, you need to add the following statement to prevent strange behavior:

ADC_InitStructure.ADC_ExternalTrigConv = 0;

Cheers, Hal

joneyvindur
Associate II
Posted on August 24, 2012 at 20:31

I switched to PC1 and PC2 and it behaved the same way. 

After a little messing around, I found another post and changed to this:

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

And it is working now. 

Thanks for the help.

pccmd
Associate II
Posted on June 09, 2013 at 08:26

Jon,

Could you post your main.c implementation...that is, how you are reading the data?

I successfully ran single ADC input project with output to serialmonitor, but your code(with corrections posted) shows only 0 in serial monitor.

I can confirm voltages correct by multitester and debugger shows appropriate responses(changing data) in the ADC3->DR.

So I guess it's my implentation of 'get data' function.

pccmd
Associate II
Posted on June 09, 2013 at 08:33

(sorry...tried posting from tablet...go figure...)

Posted on June 09, 2013 at 13:47

Please just top post responses, it is not necessary to quote the original message.

The Microsoft forum software does not permit posting from most mobile devices
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 09, 2013 at 18:40

Yeah, I supposed the embedded Word(tm) Editor thing might work on a Surface, who has one of those, but it doesn't work on a Nexus 7?

At a glance the code needs a couple of tweaks, most notably a ''volatile uint16_t'' for the receiving data structure, peripheral inc disabled and a correct pin/channel association
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..