2014-03-17 07:01 AM
Hi, since some days I'm trying to create a code to operate the ADC with DMA for STM32F4 card, the problem is that my code does not work if I want to add a second chanel because it always displays the same values for both pins.
Please who can help me solve my problem Here is my code:#include ''stm32f4_discovery.h''#include <stdio.h>#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)/* You can monitor the converted value by adding the variable ''ADC3ConvertedValue'' to the debugger watch window */__IO uint16_t ADC3ConvertedValue = 0;__IO uint32_t ADC3ConvertedVoltage = 0;__IO uint32_t val[2]={0,0};/**********************************/ ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;void ADC3_CH12_DMA_Config(void);int main(void){ /* ADC3 configuration *******************************************************/ /* - Enable peripheral clocks */ /* - DMA2_Stream0 channel2 configuration */ /* - Configure ADC Channel12 pin as analog input */ /* - Configure ADC3 Channel12 */ ADC3_CH12_DMA_Config(); /* Start ADC3 Software Conversion */ ADC_SoftwareStartConv(ADC3);; while (1) { /* convert the ADC value (from 0 to 0xFFF) to a voltage value (from 0V to 3.3V)*/val[0]=ADC3ConvertedValue *5000/0xFFF;val[1]=ADC3ConvertedValue*5000/0xFFF; }}void ADC3_CH12_DMA_Config(void){ /* 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_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); 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_12, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 2, ADC_SampleTime_3Cycles); /* 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);}2014-03-17 07:18 AM
__IO uint16_t ADC3ConvertedValue = [0,0];
You also need to configure the second channel pin to analog. Then access each array element for the two values instead of the ADC value register. The channel 13 pin is also used by another peripheral on the F4 Discovery board. There is a table in the F4 Discovery User manual which defines which pins are freely available for your use. Cheers, Hal2014-03-17 07:39 AM
2014-03-17 09:51 AM
Sorry, I gave you the wrong advice and bad coding. Point the DMA memory to:
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&val; Then pick up the converted values there. Cheers, Hal2014-03-17 11:33 AM
2014-03-17 12:38 PM
Show the new code.
Cheers, Hal2014-03-18 06:07 AM
Claude,
DMA are very susceptible devices, the most probable cause for your problem is that DMA2_Stream0 is wrong state. Try this before DMA_Init():DMA_DeInit(DMA2_Stream0);
Let ADC be handled the same way:
ADC_DeInit();
It's a bit strong where simply clearing ADC3->SR should suffice, but that way you are safer.
By the way, when using the ST library you must take care either to initialize whole init structure or simply use the proper 'init' function:
DMA_StructInit(&DMA_InitStructure);
GPIO_StructInit(&GPIO_InitStructure);
ADC_StructInit(&ADC_InitStructure);
Remember that when an overflow occurs, the whole DMA+ADC must be reconfigured (according what says the RM).
Et voilà !