Skip to main content
alexander239955_stm1_stmicro_c
Associate
October 4, 2015
Question

STM32f3 ADC & DMA Problem

  • October 4, 2015
  • 3 replies
  • 1051 views
Posted on October 04, 2015 at 15:30

Hey,

i am trying hard to get the DMA & ADC controller to work on my discovery board. I want to sample PA1&2, which are connected to current shunts.

the following code is not working, and i am not sure why. the DMA_IT_TC is called once. 

i start the conversion in the TIM1_CC4 with

DMA_SetCurrDataCounter(DMA1_Channel1, 2);

DMA_Cmd(DMA1_Channel1, ENABLE);

ADC_StartConversion(ADC1);

this is my init_code:

uint16_t ADCBuffer[] = {1,1};

void ADC_DMA_Config(void){

 RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

 ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;

 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

 ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;

 ADC_CommonInitStructure.ADC_TwoSamplingDelay = 10;

 ADC_CommonInit(ADC1, &ADC_CommonInitStructure);

 ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;

 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

 ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;

 ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

 ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;

 ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;

 ADC_InitStructure.ADC_NbrOfRegChannel = 2;

 ADC_Init(ADC1, &ADC_InitStructure);

 /* ADC1 regular channel7 configuration */

 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_7Cycles5);

 ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_7Cycles5);

 DMA_StructInit(&DMA_InitStructure);

 DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)&(ADC1->DR);

 DMA_InitStructure.DMA_MemoryBaseAddr  = (uint32_t)&ADCBuffer;

 DMA_InitStructure.DMA_DIR  = DMA_DIR_PeripheralSRC;

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

 DMA_InitStructure.DMA_Priority  = DMA_Priority_Medium;

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 DMA_ClearITPendingBit(DMA1_IT_TC1);

 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 NVIC_Init(&NVIC_InitStructure);

 /* Enable ADC1 */

 ADC_DMAConfig( ADC1, ADC_DMAMode_OneShot);

 ADC_DMACmd(ADC1, ENABLE);

 ADC_Cmd(ADC1, ENABLE);

}

    This topic has been closed for replies.

    3 replies

    Tesla DeLorean
    Guru
    October 4, 2015
    Posted on October 04, 2015 at 15:35

    the DMA_IT_TC is called once

    That would suggest you'd need to reset the DMA controller more effectively, or use it in Circular mode so it reconfigures itself each time around.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    alexander239955_stm1_stmicro_c
    Associate
    October 4, 2015
    Posted on October 04, 2015 at 16:38

    Hey Clive,

    thank you for your input. i changed to code. the DMA interrupt is called every time, but the values of the ADCBuffer are wrong or not changed.

    uint16_t ADCBuffer[] = {1,1};

    void ADC_DMA_Config(void){

     RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div8);

     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

     GPIO_Init(GPIOA, &GPIO_InitStructure);

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

     GPIO_Init(GPIOA, &GPIO_InitStructure);

     ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

     ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;

     ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

     ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;

     ADC_CommonInitStructure.ADC_TwoSamplingDelay = 16;

     ADC_CommonInit(ADC1, &ADC_CommonInitStructure);

     ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;

     ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

     ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;

     ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;

     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

     ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;

     ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;

     ADC_InitStructure.ADC_NbrOfRegChannel = 2;

     ADC_Init(ADC1, &ADC_InitStructure);

     /* ADC1 regular channel7 configuration */

     ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_7Cycles5);

     ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_7Cycles5);

     DMA_StructInit(&DMA_InitStructure);

     DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)&(ADC1->DR);

     DMA_InitStructure.DMA_MemoryBaseAddr  = (uint32_t)&ADCBuffer;

     DMA_InitStructure.DMA_DIR  = DMA_DIR_PeripheralSRC;

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

     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

     DMA_Init(DMA1_Channel1, &DMA_InitStructure);

     DMA_ClearITPendingBit(DMA1_IT_TC1);

     DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

     NVIC_Init(&NVIC_InitStructure);

     ADC_DMAConfig( ADC1, ADC_DMAMode_Circular);

     ADC_DMACmd(ADC1, ENABLE);

     ADC_Cmd(ADC1, ENABLE);

    }

    G S
    Associate II
    November 17, 2017
    Posted on November 17, 2017 at 19:47

    I have the same exact issue, was this ever resolved?