cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407: Problem With triggering ADC2

phill4563
Associate II
Posted on December 08, 2014 at 09:14

Hi,

I have a problem with my stm32f4 discovery board when i try to use a second ADC (ADC2) in DMA mode. For my project i need 2 ADC'S coupled with DMA. The first ADC (ADC1) is triggert by timer2 update flg. This part is working fine. The second ADC (ADC2) is also triggert by the timer2 update flg, but my oscilloscope shows me, that the trigger doesnt work for ADC2. The converted values of ADC2 have the right values, even the sampling freq is incorrect. Do I maybe have to use the ADC Dual Mode?, or is there any possibility to avoid this Mode? The Code below shows my implementation. Thanks ahead greetz phil

/* Main function calls */
SystemInit();
Init_IOS();
Init_ADC_TIMER();
Init_DMA1();
Init_ADC1();
Init_DMA2();
Init_ADC2();
/* TIM2 (ADC_TIMER) init */
void Init_ADC_TIMER(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 1000; 
TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
TIM_Cmd(TIM2, ENABLE);
}
/* ADC1_init*/
void Init_ADC1(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_DeInit(); 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//ADC_StructInit(&ADC_InitStructure);
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC Common configuration *************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; 
ADC_CommonInit(&ADC_CommonInitStructure); 
/* ADC1 Configuration */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_3Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE); 
ADC_SoftwareStartConv(ADC1); 
}
/* DMA2_stream0 channel0 init*/
void Init_DMA1(void)
{
/* Initialisierungsstruct für DMA2 **************************************/
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//Takt an DMA2 zuweissen *************************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* DMA2 Stream0 channel0 configuration ************************************/
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&ADC1->DR; //(uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_Values;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ADC1_BUFFERSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
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);
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
/**************** DMA Interrupt Init**************************************/
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//
//
//
// This is the part which doesnt work
//
//
//
/* ADC2 init*/
void Init_ADC2(void)
{
ADC_InitTypeDef ADC_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T2_TRGO;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2,ADC_Channel_8,1,ADC_SampleTime_3Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);
ADC_DMACmd(ADC2, ENABLE); 
ADC_Cmd(ADC2, ENABLE); 
ADC_SoftwareStartConv(ADC2);
}
*/ DMA2_stream2 channel1 init*/
void Init_DMA2(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 
DMA_DeInit(DMA2_Stream2);
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&ADC2->DR; //(uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_airmassvalues;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ADC2_BUFFERSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
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_Stream2, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream2, ENABLE);
DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);
/**************** DMA Interrupt Init**************************************/
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
*/ the interrupt routins */
extern void DMA2_Stream0_IRQHandler()
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
GPIO_ToggleBits(GPIOD,GPIO_Pin_12) /* working fine; has the right sample freq*/
}
extern void DMA2_Stream2_IRQHandler()
{ 
DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF0);
GPIO_ToggleBits(GPIOD,GPIO_Pin_13); /* doesnt work; sampling freq is at the limit*/
}

2 REPLIES 2
Posted on December 08, 2014 at 14:02

DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF0);

// ?? should be TCIF2
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
phill4563
Associate II
Posted on December 08, 2014 at 14:25

Hi,

big thanks to you clive, works perfect with your tip

greetz phil