cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 ADC+DMA PROBLEMS

Tapankaew.Sarod
Associate II
Posted on November 26, 2013 at 16:31

I try to use adc_triplemode_regsimult to convert two phase ac voltage 50 Hz and current with

adc_DMAaccessmode_1 but DMA keep sending me wrong alignment in ADCConvertedValue[3].I noticed that DMA star to mess up when DMA_S0NDTR change from 3 to 2 or 1.Plese someone help me.Every answer would be appreciated.

Here is my code.

6 REPLIES 6
Posted on November 26, 2013 at 16:45

Not seeing any code, but is [3] valid? Wouldn't you get values in [0],[1],[2]?

Some of these multiple modes are hard to set up and get your head around. Especially with 16-bit, 32-bit values, and arrays. Your buffer may need to accommodate multiple samples.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Tapankaew.Sarod
Associate II
Posted on November 26, 2013 at 16:49

#include ''stm32f4_discovery.h''

#include ''rcc.h''

#include ''ADC.h''

#include ''DMA.h''

int main(void)

{  

    //RCC Configuration

    RCC_Config();

    //GPIO Configuration

    GPIO_Config();

    //DMA Configuration

    DMA_Config();    

    //ADC Configuration

    ADC_Config();

    while (1)

    { }

 }

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

 void RCC_Config(void)

 {

 /* TIM3 clock enable */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  /* GPIOA GPIOB GPIOC GPIOD and GPIOE clock enable */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB |    RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE , ENABLE);

 

 /* Enable ADC1 clocks ****************************************/

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);

    /* Enable ADC2 clocks ****************************************/

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2 , ENABLE);    

    /* Enable ADC3 clocks ****************************************/

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3 , ENABLE);    

  /* Enable DMA2 clocks ****************************************/

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,  ENABLE);

}

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

 void GPIO_Config(void)

  {

    GPIO_InitTypeDef GPIO_InitStructure;

 

  /* Configure ADC1 Channel0 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

    

   /* Configure ADC2 Channel15 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

    

  /* Configure ADC3 Channel10 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

}    

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

#define CDR_ADDRESS ((uint32_t)0x40012308)

__IO uint16_t  ADCConvertedValue[3];

void DMA_Config(void)

{

    DMA_InitTypeDef       DMA_InitStructure;

    

    DMA_InitStructure.DMA_Channel = DMA_Channel_0;

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)CDR_ADDRESS;

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) & ADCConvertedValue;

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

    DMA_InitStructure.DMA_BufferSize = 3;

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

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_Init(DMA2_Stream0, &DMA_InitStructure);

    

    DMA_Cmd(DMA2_Stream0,ENABLE);

}

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

void ADC_Config(void)

{

  ADC_InitTypeDef       ADC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

    

     /* ADC Common Init **********************************************************/

    ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;

    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1 ;  

    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

    ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init ****************************************************************/

    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_ExternalTrigConv = 0;

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_NbrOfConversion = 1;

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Init(ADC2, &ADC_InitStructure);

    ADC_Init(ADC3, &ADC_InitStructure);

    

    /* ADC1 regular channel0 configuration *************************************/

  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);

    

    /* ADC2 regular channel15 configuration *************************************/

  ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_SampleTime_3Cycles);

    

    /* ADC3 regular channel10 configuration *************************************/

  ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

    

    ADC_Cmd(ADC1,ENABLE);

   

ADC_Cmd(ADC2,ENABLE);

   

ADC_Cmd(ADC3,ENABLE);

    ADC_ContinuousModeCmd(ADC1,ENABLE);

    ADC_DMACmd(ADC1,ENABLE);

    ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

    ADC_SoftwareStartConv(ADC1);

}

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

Posted on November 26, 2013 at 17:07

__IO uint16_t ADCConvertedValue[3];

So ZERO based array elements in ADCConvertedValue[0] ADCConvertedValue[1] ADCConvertedValue[2] Quoted

#include ''stm32f4_discovery.h''
#include ''rcc.h''
#include ''ADC.h''
#include ''DMA.h''
int main(void)
{ 
//RCC Configuration
RCC_Config();
//GPIO Configuration
GPIO_Config();
//DMA Configuration
DMA_Config(); 
//ADC Configuration
ADC_Config();
while (1)
{ }
}
/****************************************************/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure ADC1 Channel0 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure ADC2 Channel15 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure ADC3 Channel10 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
} 
/****************************************************/
#define CDR_ADDRESS ((uint32_t)0x40012308)
__IO uint16_t ADCConvertedValue[3];
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)CDR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) & ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 3;
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_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0,ENABLE);
}
/****************************************************/
void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1 ; 
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init ****************************************************************/
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_ExternalTrigConv = 0;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Init(ADC2, &ADC_InitStructure);
ADC_Init(ADC3, &ADC_InitStructure);
/* ADC1 regular channel0 configuration *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);
/* ADC2 regular channel15 configuration *************************************/
ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_SampleTime_3Cycles);
/* ADC3 regular channel10 configuration *************************************/
ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_Cmd(ADC1,ENABLE);
ADC_Cmd(ADC2,ENABLE);
ADC_Cmd(ADC3,ENABLE);
ADC_ContinuousModeCmd(ADC1,ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
ADC_SoftwareStartConv(ADC1);
}
/****************************************************/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 26, 2013 at 17:27

PC0 Channel 10 is a poor choice on the STM32F4-Discovery, PC1 Channel 11 (ADC123_11) might be a better one. Refer to board documentation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Tapankaew.Sarod
Associate II
Posted on November 26, 2013 at 17:42

I have changed to PC1 (ADC_chanal 11) but still doesn't work.The convert value alignment correct at frist time but it mess up on second request.Thank you for your answer 0690X0000060MnuQAE.gif.ToT

Posted on November 26, 2013 at 18:25

''Doesn't Work'' is hard for me to quantify, what does this mean in actual measurements vs physical state of the pins.

A 3 cycle sample time is very short, you are in continuous/circular mode, measurements are going to be flooding in. You're going to have to use some more care in handling the results to insure the values you are using are in fact contemporaneous with each other. This will require a larger buffer, and HT/TC interrupt handling to handle values before new ones arrive.

In terms of validating the three ADC results, and that they are in the buffer correctly one could tie each to a unique fix source. Subsequent testing could look at specific phase relationships between them.

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